Merge from OSM SO master
[osm/SO.git] / rwlaunchpad / plugins / rwresmgr / rift / tasklets / rwresmgrtasklet / rwresmgrtasklet.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 import logging
20 import sys
21
22 import gi
23 gi.require_version('RwDts', '1.0')
24 gi.require_version('RwYang', '1.0')
25 gi.require_version('RwResourceMgrYang', '1.0')
26 gi.require_version('RwLaunchpadYang', '1.0')
27 gi.require_version('RwcalYang', '1.0')
28 from gi.repository import (
29 RwDts as rwdts,
30 RwYang,
31 RwResourceMgrYang,
32 RwLaunchpadYang,
33 RwcalYang,
34 )
35
36 import rift.tasklets
37 from rift.mano.utils.project import (
38 ManoProject,
39 ProjectHandler,
40 )
41
42 from . import rwresmgr_core as Core
43 from . import rwresmgr_config as Config
44 from . import rwresmgr_events as Event
45
46
47 class ResourceManager(object):
48 def __init__(self, log, log_hdl, loop, dts, project):
49 self._log = log
50 self._log_hdl = log_hdl
51 self._loop = loop
52 self._dts = dts
53 self._project = project
54
55 self.config_handler = Config.ResourceMgrConfig(self._dts, self._log, self._log_hdl, self._loop, self)
56 self.event_handler = Event.ResourceMgrEvent(self._dts, self._log, self._loop, self)
57 self.core = Core.ResourceMgrCore(self._dts, self._log, self._log_hdl, self._loop, self)
58
59 @asyncio.coroutine
60 def register(self):
61 yield from self.config_handler.register()
62 yield from self.event_handler.register()
63
64 def deregister(self):
65 self.event_handler.deregister()
66 self.config_handler.deregister()
67
68 def add_cloud_account_config(self, account):
69 self._log.debug("Received Cloud-Account add config event for account: %s", account.name)
70 self.core.add_cloud_account(account)
71
72 def update_cloud_account_config(self, account):
73 self._log.debug("Received Cloud-Account update config event for account: %s", account.name)
74 self.core.update_cloud_account(account)
75
76 def delete_cloud_account_config(self, account_name, dry_run=False):
77 self._log.debug("Received Cloud-Account delete event for account (dry_run: %s): %s",
78 dry_run, account_name)
79 self.core.delete_cloud_account(account_name, dry_run)
80
81 def get_cloud_account_names(self):
82 cloud_account_names = self.core.get_cloud_account_names()
83 return cloud_account_names
84
85 def pool_add(self, cloud_account_name, pool):
86 self._log.debug("Received Pool add event for cloud account %s pool: %s",
87 cloud_account_name, pool.name)
88 self.core.add_resource_pool(cloud_account_name, pool)
89
90 def pool_modify(self, cloud_account_name, pool):
91 self._log.debug("Received Pool modify event for cloud account %s pool: %s",
92 cloud_account_name, pool.name)
93 self.core.modify_resource_pool(cloud_account_name, pool)
94
95 def pool_delete(self, cloud_account_name, pool_name):
96 self._log.debug("Received Pool delete event for cloud account %s pool: %s",
97 cloud_account_name, pool_name)
98 self.core.delete_resource_pool(cloud_account_name, pool_name)
99
100 def get_pool_list(self, cloud_account_name):
101 return self.core.get_resource_pool_list(cloud_account_name)
102
103 def get_pool_info(self, cloud_account_name, pool_name):
104 self._log.debug("Received get-pool-info event for cloud account %s pool: %s",
105 cloud_account_name, pool_name)
106 return self.core.get_resource_pool_info(cloud_account_name, pool_name)
107
108 def lock_pool(self, cloud_account_name, pool_name):
109 self._log.debug("Received pool unlock event for pool: %s",
110 cloud_account_name, pool_name)
111 self.core.lock_resource_pool(cloud_account_name, pool_name)
112
113 def unlock_pool(self, cloud_account_name, pool_name):
114 self._log.debug("Received pool unlock event for pool: %s",
115 cloud_account_name, pool_name)
116 self.core.unlock_resource_pool(cloud_account_name, pool_name)
117
118 @asyncio.coroutine
119 def allocate_virtual_network(self, event_id, cloud_account_name, request):
120 self._log.info("Received network resource allocation request with event-id: %s", event_id)
121 resource = yield from self.core.allocate_virtual_resource(event_id, cloud_account_name, request, 'network')
122 return resource
123
124 @asyncio.coroutine
125 def reallocate_virtual_network(self, event_id, cloud_account_name, request, resource):
126 self._log.info("Received network resource reallocation request with event-id: %s", event_id)
127 resource = yield from self.core.reallocate_virtual_resource(event_id, cloud_account_name, request, 'network', resource)
128 return resource
129
130 @asyncio.coroutine
131 def release_virtual_network(self, event_id):
132 self._log.info("Received network resource release request with event-id: %s", event_id)
133 yield from self.core.release_virtual_resource(event_id, 'network')
134
135 @asyncio.coroutine
136 def read_virtual_network_info(self, event_id):
137 self._log.info("Received network resource read request with event-id: %s", event_id)
138 info = yield from self.core.read_virtual_resource(event_id, 'network')
139 return info
140
141 @asyncio.coroutine
142 def allocate_virtual_compute(self, event_id, cloud_account_name, request):
143 self._log.info("Received compute resource allocation request "
144 "(cloud account: %s) with event-id: %s",
145 cloud_account_name, event_id)
146 resource = yield from self.core.allocate_virtual_resource(
147 event_id, cloud_account_name, request, 'compute',
148 )
149 return resource
150
151 @asyncio.coroutine
152 def reallocate_virtual_compute(self, event_id, cloud_account_name, request, resource):
153 self._log.info("Received compute resource reallocation request "
154 "(cloud account: %s) with event-id: %s",
155 cloud_account_name, event_id)
156 resource = yield from self.core.reallocate_virtual_resource(
157 event_id, cloud_account_name, request, 'compute', resource,
158 )
159 return resource
160
161 @asyncio.coroutine
162 def release_virtual_compute(self, event_id):
163 self._log.info("Received compute resource release request with event-id: %s", event_id)
164 yield from self.core.release_virtual_resource(event_id, 'compute')
165
166 @asyncio.coroutine
167 def read_virtual_compute_info(self, event_id):
168 self._log.info("Received compute resource read request with event-id: %s", event_id)
169 info = yield from self.core.read_virtual_resource(event_id, 'compute')
170 return info
171
172
173 class ResMgrProject(ManoProject):
174
175 def __init__(self, name, tasklet, **kw):
176 super(ResMgrProject, self).__init__(tasklet.log, name)
177 self.update(tasklet)
178
179 self._resource_manager = None
180
181 @asyncio.coroutine
182 def register (self):
183 self._log.debug("Initializing the Resource Manager tasklet for project {}".
184 format(self.name))
185 self._resource_manager = ResourceManager(self._log,
186 self._log_hdl,
187 self._loop,
188 self._dts,
189 self,)
190 yield from self._resource_manager.register()
191
192 def deregister(self):
193 self._log.debug("De-registering project {}".format(self.name))
194 self._resource_manager.deregister()
195
196
197 class ResMgrTasklet(rift.tasklets.Tasklet):
198 def __init__(self, *args, **kwargs):
199 super(ResMgrTasklet, self).__init__(*args, **kwargs)
200 self.rwlog.set_category("rw-resource-mgr-log")
201 self._dts = None
202 self._project_handler = None
203 self.projects = {}
204
205 @property
206 def dts(self):
207 return self._dts
208
209 def start(self):
210 super(ResMgrTasklet, self).start()
211 self.log.debug("Starting ResMgrTasklet")
212
213 self.log.debug("Registering with dts")
214
215 self._dts = rift.tasklets.DTS(self.tasklet_info,
216 RwResourceMgrYang.get_schema(),
217 self.loop,
218 self.on_dts_state_change)
219
220 self.log.debug("Created DTS Api GI Object: %s", self._dts)
221
222 def stop(self):
223 try:
224 self._dts.deinit()
225 except Exception:
226 print("Caught Exception in RESMGR stop:", sys.exc_info()[0])
227 raise
228
229 def on_instance_started(self):
230 self.log.debug("Got instance started callback")
231
232 @asyncio.coroutine
233 def init(self):
234 self.log.debug("creating project handler")
235 self.project_handler = ProjectHandler(self, ResMgrProject)
236 self.project_handler.register()
237
238 @asyncio.coroutine
239 def run(self):
240 pass
241
242 @asyncio.coroutine
243 def on_dts_state_change(self, state):
244 """Take action according to current dts state to transition
245 application into the corresponding application state
246
247 Arguments
248 state - current dts state
249 """
250 switch = {
251 rwdts.State.INIT: rwdts.State.REGN_COMPLETE,
252 rwdts.State.CONFIG: rwdts.State.RUN,
253 }
254
255 handlers = {
256 rwdts.State.INIT: self.init,
257 rwdts.State.RUN: self.run,
258 }
259
260 # Transition application to next state
261 handler = handlers.get(state, None)
262 if handler is not None:
263 yield from handler()
264
265 # Transition dts to next state
266 next_state = switch.get(state, None)
267 if next_state is not None:
268 self._dts.handle.set_state(next_state)