Merge from OSM SO master
[osm/SO.git] / rwlaunchpad / plugins / rwlaunchpadtasklet / rift / tasklets / rwlaunchpad / datacenters.py
1
2 #
3 # Copyright 2016 RIFT.IO Inc
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17
18 import asyncio
19
20 from gi.repository import (
21 RwDts,
22 RwLaunchpadYang,
23 )
24
25 import rift.mano.dts as mano_dts
26 import rift.openmano.openmano_client as openmano_client
27 import rift.tasklets
28
29
30 class DataCenterPublisher(mano_dts.DtsHandler):
31 """
32 This class is reponsible for exposing the data centers associated with an
33 openmano cloud account.
34 """
35
36 XPATH = "D,/rw-launchpad:datacenters"
37
38 def __init__(self, log, dts, loop, project):
39 """Creates an instance of a DataCenterPublisher
40
41 Arguments:
42 tasklet - the tasklet that this publisher is registered for
43
44 """
45 super().__init__(log, dts, loop, project)
46
47 self._ro_sub = mano_dts.ROAccountConfigSubscriber(
48 self.log,
49 self.dts,
50 self.loop,
51 self.project,
52 callback=self.on_ro_account_change
53 )
54 self.ro_accounts = {}
55
56 def on_ro_account_change(self, ro_account, action):
57 if action in [ RwDts.QueryAction.CREATE, RwDts.QueryAction.UPDATE ]:
58 self.ro_accounts[ro_account.name] = ro_account
59 elif action == RwDts.QueryAction.DELETE and ro_account.name in self.ro_accounts:
60 del self.ro_accounts[ro_account.name]
61
62 def deregister(self):
63 self._log.debug("De-register datacenter handler for project {}".
64 format(self.project.name))
65 if self.reg:
66 self.reg.deregister()
67 self.reg = None
68
69 self._ro_sub.deregister()
70
71 @asyncio.coroutine
72 def register(self):
73 """Registers the publisher with DTS"""
74 yield from self._ro_sub.register()
75
76 @asyncio.coroutine
77 def on_prepare(xact_info, action, ks_path, msg):
78 try:
79 # Create a datacenters instance to hold all of the cloud
80 # account data.
81 datacenters = RwLaunchpadYang.DataCenters()
82
83 # Iterate over the known openmano accounts and populate cloud
84 # account instances with the corresponding data center info
85 for _, account in self.ro_accounts.items():
86 if account.account_type != "openmano":
87 continue
88
89 try:
90 ro_account = RwLaunchpadYang.ROAccount()
91 ro_account.name = account.name
92
93 # Create a client for this cloud account to query for
94 # the associated data centers
95 client = openmano_client.OpenmanoCliAPI(
96 self.log,
97 account.openmano.host,
98 account.openmano.port,
99 account.openmano.tenant_id,
100 )
101
102 # Populate the cloud account with the data center info
103 for uuid, name in client.datacenter_list():
104 ro_account.datacenters.append(
105 RwLaunchpadYang.DataCenter(
106 uuid=uuid,
107 name=name,
108 )
109 )
110
111 datacenters.ro_accounts.append(ro_account)
112
113 except Exception as e:
114 self.log.exception(e)
115
116 xact_info.respond_xpath(
117 RwDts.XactRspCode.MORE,
118 self.project.add_project(DataCenterPublisher.XPATH),
119 datacenters,
120 )
121
122 xact_info.respond_xpath(RwDts.XactRspCode.ACK)
123
124 except Exception as e:
125 self.log.exception(e)
126 raise
127
128 handler = rift.tasklets.DTS.RegistrationHandler(on_prepare=on_prepare)
129
130 with self.dts.group_create() as group:
131 self.reg = group.register(
132 xpath=self.project.add_project(DataCenterPublisher.XPATH),
133 handler=handler,
134 flags=RwDts.Flag.PUBLISHER,
135 )