Merge from OSM SO master
[osm/SO.git] / rwlaunchpad / plugins / rwnsm / rift / tasklets / rwnsmtasklet / cloud.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 from gi.repository import (
20 RwDts as rwdts,
21 RwcalYang as rwcal,
22 RwTypes,
23 ProtobufC,
24 )
25
26 import rift.mano.cloud
27 import rift.mano.dts as mano_dts
28 import rift.tasklets
29
30 from . import openmano_nsm
31 from . import rwnsmplugin
32
33
34 class RwNsPlugin(rwnsmplugin.NsmPluginBase):
35 """
36 RW Implentation of the NsmPluginBase
37 """
38 def __init__(self, dts, log, loop, publisher, ro_account):
39 self._dts = dts
40 self._log = log
41 self._loop = loop
42
43 def set_state(self, nsr_id, state):
44 pass
45
46 def create_nsr(self, nsr_msg, nsd,key_pairs=None):
47 """
48 Create Network service record
49 """
50 pass
51
52 @asyncio.coroutine
53 def deploy(self, nsr):
54 pass
55
56 @asyncio.coroutine
57 def instantiate_ns(self, nsr, config_xact):
58 """
59 Instantiate NSR with the passed nsr id
60 """
61 yield from nsr.instantiate(config_xact)
62
63 @asyncio.coroutine
64 def instantiate_vnf(self, nsr, vnfr):
65 """
66 Instantiate NSR with the passed nsr id
67 """
68 yield from vnfr.instantiate(nsr)
69
70 @asyncio.coroutine
71 def instantiate_vl(self, nsr, vlr):
72 """
73 Instantiate NSR with the passed nsr id
74 """
75 yield from vlr.instantiate()
76
77 @asyncio.coroutine
78 def terminate_ns(self, nsr):
79 """
80 Terminate the network service
81 """
82 pass
83
84 @asyncio.coroutine
85 def terminate_vnf(self, vnfr):
86 """
87 Terminate the network service
88 """
89 yield from vnfr.terminate()
90
91 @asyncio.coroutine
92 def terminate_vl(self, vlr):
93 """
94 Terminate the virtual link
95 """
96 yield from vlr.terminate()
97
98
99 class NsmPlugins(object):
100 """ NSM Plugins """
101 def __init__(self):
102 self._plugin_classes = {
103 "openmano": openmano_nsm.OpenmanoNsPlugin,
104 }
105
106 @property
107 def plugins(self):
108 """ Plugin info """
109 return self._plugin_classes
110
111 def __getitem__(self, name):
112 """ Get item """
113 print("%s", self._plugin_classes)
114 return self._plugin_classes[name]
115
116 def register(self, plugin_name, plugin_class, *args):
117 """ Register a plugin to this Nsm"""
118 self._plugin_classes[plugin_name] = plugin_class
119
120 def deregister(self, plugin_name, plugin_class, *args):
121 """ Deregister a plugin to this Nsm"""
122 if plugin_name in self._plugin_classes:
123 del self._plugin_classes[plugin_name]
124
125 def class_by_plugin_name(self, name):
126 """ Get class by plugin name """
127 return self._plugin_classes[name]
128
129
130 class CloudAccountConfigSubscriber:
131 def __init__(self, log, dts, log_hdl, project):
132 self._dts = dts
133 self._log = log
134 self._log_hdl = log_hdl
135 self._project = project
136
137 self._cloud_sub = rift.mano.cloud.CloudAccountConfigSubscriber(
138 self._dts,
139 self._log,
140 self._log_hdl,
141 self._project,
142 rift.mano.cloud.CloudAccountConfigCallbacks())
143
144 def get_cloud_account_sdn_name(self, account_name):
145 if account_name in self._cloud_sub.accounts:
146 self._log.debug("Cloud accnt msg is %s",self._cloud_sub.accounts[account_name].account_msg)
147 if self._cloud_sub.accounts[account_name].account_msg.has_field("sdn_account"):
148 sdn_account = self._cloud_sub.accounts[account_name].account_msg.sdn_account
149 self._log.info("SDN associated with Cloud name %s is %s", account_name, sdn_account)
150 return sdn_account
151 else:
152 self._log.debug("No SDN Account associated with Cloud name %s", account_name)
153 return None
154
155 @asyncio.coroutine
156 def register(self):
157 self._cloud_sub.register()
158
159 def deregister(self):
160 self._cloud_sub.deregister()
161
162
163 class ROAccountPluginSelector(object):
164 """
165 Select the RO based on the config.
166
167 If no RO account is specified, then default to rift-ro.
168
169 Note:
170 Currently only one RO can be used (one-time global config.)
171 """
172 DEFAULT_PLUGIN = RwNsPlugin
173
174 def __init__(self, dts, log, loop, project, records_publisher):
175 self._dts = dts
176 self._log = log
177 self._loop = loop
178 self._project = project
179 self._records_publisher = records_publisher
180
181 self._nsm_plugins = NsmPlugins()
182
183 self._ro_sub = mano_dts.ROAccountConfigSubscriber(
184 self._log,
185 self._dts,
186 self._loop,
187 self._project,
188 callback=self.on_ro_account_change
189 )
190 self._nsr_sub = mano_dts.NsrCatalogSubscriber(
191 self._log,
192 self._dts,
193 self._loop,
194 self._project,
195 self.handle_nsr)
196
197 # The default plugin will be RwNsPlugin
198 self._ro_plugin = self._create_plugin(self.DEFAULT_PLUGIN, None)
199 self.live_instances = 0
200
201 @property
202 def ro_plugin(self):
203 return self._ro_plugin
204
205 def handle_nsr(self, nsr, action):
206 if action == rwdts.QueryAction.CREATE:
207 self.live_instances += 1
208 elif action == rwdts.QueryAction.DELETE:
209 self.live_instances -= 1
210
211 def on_ro_account_change(self, ro_account, action):
212 if action in [rwdts.QueryAction.CREATE, rwdts.QueryAction.UPDATE]:
213 self._on_ro_account_change(ro_account)
214 elif action == rwdts.QueryAction.DELETE:
215 self._on_ro_account_deleted(ro_account)
216
217 def _on_ro_account_change(self, ro_account):
218 self._log.debug("Got nsm plugin RO account: %s", ro_account)
219 try:
220 nsm_cls = self._nsm_plugins.class_by_plugin_name(
221 ro_account.account_type
222 )
223 except KeyError as e:
224 self._log.debug(
225 "RO account nsm plugin not found: %s. Using standard rift nsm.",
226 ro_account.name
227 )
228 nsm_cls = self.DEFAULT_PLUGIN
229
230 ro_plugin = self._create_plugin(nsm_cls, ro_account)
231 if self.live_instances == 0:
232 self._ro_plugin = ro_plugin
233 else:
234 raise ValueError("Unable to change the plugin when live NS instances exists!")
235
236 def _on_ro_account_deleted(self, ro_account):
237 self._ro_plugin = None
238
239 def _create_plugin(self, nsm_cls, ro_account):
240
241 self._log.debug("Instantiating new RO account using class: %s", nsm_cls)
242 nsm_instance = nsm_cls(self._dts, self._log, self._loop,
243 self._records_publisher, ro_account)
244
245 return nsm_instance
246
247 @asyncio.coroutine
248 def register(self):
249 yield from self._ro_sub.register()
250 yield from self._nsr_sub.register()
251
252 def deregister(self):
253 self._log.debug("Project {} de-register".format(self._project.name))
254 self._ro_sub.deregister()
255 self._nsr_sub.deregister()