SDN Accounts refactoring
[osm/SO.git] / rwlaunchpad / plugins / rwvns / rift / tasklets / rwvnstasklet / rwvnstasklet.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 sys
20
21 import gi
22 gi.require_version('RwVnsYang', '1.0')
23 gi.require_version('RwDts', '1.0')
24 from gi.repository import (
25 RwVnsYang,
26 RwDts as rwdts,
27 RwTypes,
28 )
29
30 import rift.tasklets
31 import rift.mano.sdn
32
33 from rift.vlmgr import (
34 VlrDtsHandler,
35 VldDtsHandler,
36 VirtualLinkRecord,
37 )
38
39 from rift.topmgr import (
40 NwtopStaticDtsHandler,
41 NwtopDiscoveryDtsHandler,
42 NwtopDataStore,
43 )
44
45
46 class VlRecordError(Exception):
47 """ Vlr Record creation Error """
48 pass
49
50
51 class VlRecordNotFound(Exception):
52 """ Vlr Record not found"""
53 pass
54
55
56 class SDNAccountHandlers(object):
57 def __init__(self, dts, log, log_hdl, acctstore, loop):
58 self._log = log
59 self._log_hdl = log_hdl
60 self._dts = dts
61 self._loop = loop
62 self._acctstore = acctstore
63
64 self._log.debug("Creating SDN account config handler")
65 self.sdn_cfg_handler = rift.mano.sdn.SDNAccountConfigSubscriber(
66 self._dts, self._log, self._log_hdl,
67 rift.mano.sdn.SDNAccountConfigCallbacks(
68 on_add_apply=self.on_sdn_account_added,
69 on_delete_apply=self.on_sdn_account_deleted,
70 ),
71 self._acctstore
72
73 )
74
75 self._log.debug("Creating SDN account opdata handler")
76 self.sdn_operdata_handler = rift.mano.sdn.SDNAccountDtsOperdataHandler(
77 self._dts, self._log, self._loop,
78 )
79
80 def on_sdn_account_deleted(self, account_name):
81 self._log.debug("SDN account deleted")
82 self.sdn_operdata_handler.delete_sdn_account(account_name)
83
84 def on_sdn_account_added(self, account):
85 self._log.debug("SDN account added")
86 self.sdn_operdata_handler.add_sdn_account(account)
87
88 @asyncio.coroutine
89 def register(self):
90 self.sdn_cfg_handler.register()
91 yield from self.sdn_operdata_handler.register()
92
93
94 class VnsManager(object):
95 """ The Virtual Network Service Manager """
96 def __init__(self, dts, log, log_hdl, loop):
97 self._dts = dts
98 self._log = log
99 self._log_hdl = log_hdl
100 self._loop = loop
101 self._acctstore = {}
102 self._vlr_handler = VlrDtsHandler(dts, log, loop, self)
103 self._vld_handler = VldDtsHandler(dts, log, loop, self)
104 self._sdn_handlers = SDNAccountHandlers(dts, log, log_hdl, self._acctstore, loop)
105 self._nwtopdata_store = NwtopDataStore(log)
106 self._nwtopdiscovery_handler = NwtopDiscoveryDtsHandler(dts, log, loop, self._acctstore, self._nwtopdata_store)
107 self._nwtopstatic_handler = NwtopStaticDtsHandler(dts, log, loop, self._acctstore, self._nwtopdata_store)
108 self._vlrs = {}
109
110 @asyncio.coroutine
111 def register_vlr_handler(self):
112 """ Register vlr DTS handler """
113 self._log.debug("Registering DTS VLR handler")
114 yield from self._vlr_handler.register()
115
116 @asyncio.coroutine
117 def register_vld_handler(self):
118 """ Register vlr DTS handler """
119 self._log.debug("Registering DTS VLD handler")
120 yield from self._vld_handler.register()
121
122 @asyncio.coroutine
123 def register_sdn_handlers(self):
124 """ Register SDN DTS handlers """
125 self._log.debug("Registering SDN Account handlers")
126 yield from self._sdn_handlers.register()
127
128 @asyncio.coroutine
129 def register_nwtopstatic_handler(self):
130 """ Register static NW topology DTS handler """
131 self._log.debug("Registering static DTS NW topology handler")
132 yield from self._nwtopstatic_handler.register()
133
134 @asyncio.coroutine
135 def register_nwtopdiscovery_handler(self):
136 """ Register discovery-based NW topology DTS handler """
137 self._log.debug("Registering discovery-based DTS NW topology handler")
138 yield from self._nwtopdiscovery_handler.register()
139
140 @asyncio.coroutine
141 def register(self):
142 """ Register all static DTS handlers"""
143 yield from self.register_sdn_handlers()
144 yield from self.register_vlr_handler()
145 yield from self.register_vld_handler()
146 yield from self.register_nwtopstatic_handler()
147 yield from self.register_nwtopdiscovery_handler()
148
149 def create_vlr(self, msg):
150 """ Create VLR """
151 if msg.id in self._vlrs:
152 err = "Vlr id %s already exists" % msg.id
153 self._log.error(err)
154 # raise VlRecordError(err)
155 return self._vlrs[msg.id]
156
157 self._log.info("Creating VirtualLinkRecord %s", msg.id)
158 self._vlrs[msg.id] = VirtualLinkRecord(self._dts,
159 self._log,
160 self._loop,
161 self,
162 msg,
163 msg.res_id
164 )
165 return self._vlrs[msg.id]
166
167 def get_vlr(self, vlr_id):
168 """ Get VLR by vlr id """
169 return self._vlrs[vlr_id]
170
171 @asyncio.coroutine
172 def delete_vlr(self, vlr_id, xact):
173 """ Delete VLR with the passed id"""
174 if vlr_id not in self._vlrs:
175 err = "Delete Failed - Vlr id %s not found" % vlr_id
176 self._log.error(err)
177 raise VlRecordNotFound(err)
178
179 self._log.info("Deleting virtual link id %s", vlr_id)
180 yield from self._vlrs[vlr_id].terminate(xact)
181 del self._vlrs[vlr_id]
182 self._log.info("Deleted virtual link id %s", vlr_id)
183
184 def find_vlr_by_vld_id(self, vld_id):
185 """ Find a VLR matching the VLD Id """
186 for vlr in self._vlrs.values():
187 if vlr.vld_id == vld_id:
188 return vlr
189 return None
190
191 @asyncio.coroutine
192 def run(self):
193 """ Run this VNSM instance """
194 self._log.debug("Run VNSManager - registering static DTS handlers")
195 yield from self.register()
196
197 def vld_in_use(self, vld_id):
198 """ Is this VLD in use """
199 return False
200
201 @asyncio.coroutine
202 def publish_vlr(self, xact, path, msg):
203 """ Publish a VLR """
204 self._log.debug("Publish vlr called with path %s, msg %s",
205 path, msg)
206 yield from self._vlr_handler.update(xact, path, msg)
207
208 @asyncio.coroutine
209 def unpublish_vlr(self, xact, path):
210 """ Publish a VLR """
211 self._log.debug("Unpublish vlr called with path %s", path)
212 yield from self._vlr_handler.delete(xact, path)
213
214
215 class VnsTasklet(rift.tasklets.Tasklet):
216 """ The VNS tasklet class """
217 def __init__(self, *args, **kwargs):
218 super(VnsTasklet, self).__init__(*args, **kwargs)
219 self.rwlog.set_category("rw-mano-log")
220 self.rwlog.set_subcategory("vns")
221
222 self._dts = None
223 self._vlr_handler = None
224
225 self._vnsm = None
226 # A mapping of instantiated vlr_id's to VirtualLinkRecord objects
227 self._vlrs = {}
228
229 def start(self):
230 super(VnsTasklet, self).start()
231 self.log.info("Starting VnsTasklet")
232
233 self.log.debug("Registering with dts")
234 self._dts = rift.tasklets.DTS(self.tasklet_info,
235 RwVnsYang.get_schema(),
236 self.loop,
237 self.on_dts_state_change)
238
239 self.log.debug("Created DTS Api GI Object: %s", self._dts)
240
241 def on_instance_started(self):
242 """ The task instance started callback"""
243 self.log.debug("Got instance started callback")
244
245 def stop(self):
246 try:
247 self._dts.deinit()
248 except Exception:
249 print("Caught Exception in VNS stop:", sys.exc_info()[0])
250 raise
251
252 @asyncio.coroutine
253 def init(self):
254 """ task init callback"""
255 self._vnsm = VnsManager(dts=self._dts,
256 log=self.log,
257 log_hdl=self.log_hdl,
258 loop=self.loop)
259 yield from self._vnsm.run()
260
261 # NSM needs to detect VLD deletion that has active VLR
262 # self._vld_handler = VldDescriptorConfigDtsHandler(
263 # self._dts, self.log, self.loop, self._vlrs,
264 # )
265 # yield from self._vld_handler.register()
266
267 @asyncio.coroutine
268 def run(self):
269 """ tasklet run callback """
270 pass
271
272 @asyncio.coroutine
273 def on_dts_state_change(self, state):
274 """Take action according to current dts state to transition
275 application into the corresponding application state
276
277 Arguments
278 state - current dts state
279 """
280 switch = {
281 rwdts.State.INIT: rwdts.State.REGN_COMPLETE,
282 rwdts.State.CONFIG: rwdts.State.RUN,
283 }
284
285 handlers = {
286 rwdts.State.INIT: self.init,
287 rwdts.State.RUN: self.run,
288 }
289
290 # Transition application to next state
291 handler = handlers.get(state, None)
292 if handler is not None:
293 yield from handler()
294
295 # Transition dts to next state
296 next_state = switch.get(state, None)
297 if next_state is not None:
298 self._dts.handle.set_state(next_state)