RIFT OSM R1 Initial Submission
[osm/SO.git] / rwlaunchpad / plugins / rwnsm / rift / tasklets / rwnsmtasklet / cloud.py
diff --git a/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/cloud.py b/rwlaunchpad/plugins/rwnsm/rift/tasklets/rwnsmtasklet/cloud.py
new file mode 100644 (file)
index 0000000..5326ca1
--- /dev/null
@@ -0,0 +1,238 @@
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+import asyncio
+from gi.repository import (
+    RwDts as rwdts,
+    RwcalYang as rwcal,
+    RwTypes,
+    ProtobufC,
+    )
+
+import rift.mano.cloud
+import rift.mano.dts as mano_dts
+import rift.tasklets
+
+from . import openmano_nsm
+from . import rwnsmplugin
+
+
+class RwNsPlugin(rwnsmplugin.NsmPluginBase):
+    """
+        RW Implentation of the NsmPluginBase
+    """
+    def __init__(self, dts, log, loop, publisher, ro_account):
+        self._dts = dts
+        self._log = log
+        self._loop = loop
+
+    def create_nsr(self, nsr_msg, nsd):
+        """
+        Create Network service record
+        """
+        pass
+
+    @asyncio.coroutine
+    def deploy(self, nsr):
+        pass
+
+    @asyncio.coroutine
+    def instantiate_ns(self, nsr, config_xact):
+        """
+        Instantiate NSR with the passed nsr id
+        """
+        yield from nsr.instantiate(config_xact)
+
+    @asyncio.coroutine
+    def instantiate_vnf(self, nsr, vnfr):
+        """
+        Instantiate NSR with the passed nsr id
+        """
+        yield from vnfr.instantiate(nsr)
+
+    @asyncio.coroutine
+    def instantiate_vl(self, nsr, vlr):
+        """
+        Instantiate NSR with the passed nsr id
+        """
+        yield from vlr.instantiate()
+
+    @asyncio.coroutine
+    def terminate_ns(self, nsr):
+        """
+        Terminate the network service
+        """
+        pass
+
+    @asyncio.coroutine
+    def terminate_vnf(self, vnfr):
+        """
+        Terminate the network service
+        """
+        yield from vnfr.terminate()
+
+    @asyncio.coroutine
+    def terminate_vl(self, vlr):
+        """
+        Terminate the virtual link
+        """
+        yield from vlr.terminate()
+
+
+class NsmPlugins(object):
+    """ NSM Plugins """
+    def __init__(self):
+        self._plugin_classes = {
+                "openmano": openmano_nsm.OpenmanoNsPlugin,
+                }
+
+    @property
+    def plugins(self):
+        """ Plugin info """
+        return self._plugin_classes
+
+    def __getitem__(self, name):
+        """ Get item """
+        print("%s", self._plugin_classes)
+        return self._plugin_classes[name]
+
+    def register(self, plugin_name, plugin_class, *args):
+        """ Register a plugin to this Nsm"""
+        self._plugin_classes[plugin_name] = plugin_class
+
+    def deregister(self, plugin_name, plugin_class, *args):
+        """ Deregister a plugin to this Nsm"""
+        if plugin_name in self._plugin_classes:
+            del self._plugin_classes[plugin_name]
+
+    def class_by_plugin_name(self, name):
+        """ Get class by plugin name """
+        return self._plugin_classes[name]
+
+
+class ROAccountConfigSubscriber(mano_dts.AbstractConfigSubscriber):
+
+    def key_name(self):
+        return "name"
+
+    def get_xpath(self):
+        return("C,/rw-launchpad:resource-orchestrator")
+
+
+class CloudAccountConfigSubscriber:
+    def __init__(self, log, dts, log_hdl):
+        self._dts = dts
+        self._log = log
+        self._log_hdl = log_hdl
+
+        self._cloud_sub = rift.mano.cloud.CloudAccountConfigSubscriber(
+                self._dts,
+                self._log,
+                self._log_hdl,
+                rift.mano.cloud.CloudAccountConfigCallbacks())
+
+    def get_cloud_account_sdn_name(self, account_name):
+        if account_name in self._cloud_sub.accounts:
+            self._log.debug("Cloud accnt msg is %s",self._cloud_sub.accounts[account_name].account_msg)
+            if self._cloud_sub.accounts[account_name].account_msg.has_field("sdn_account"):
+                sdn_account = self._cloud_sub.accounts[account_name].account_msg.sdn_account 
+                self._log.info("SDN associated with Cloud name %s is %s", account_name, sdn_account)
+                return sdn_account
+            else:
+                self._log.debug("No SDN Account associated with Cloud name %s", account_name)
+                return None
+
+    @asyncio.coroutine
+    def register(self):
+       self._cloud_sub.register()
+
+
+class ROAccountPluginSelector(object):
+    """
+    Select the RO based on the config.
+
+    If no RO account is specified, then default to rift-ro.
+
+    Note:
+    Currently only one RO can be used (one-time global config.)
+    """
+    DEFAULT_PLUGIN = RwNsPlugin
+
+    def __init__(self, dts, log, loop, records_publisher):
+        self._dts = dts
+        self._log = log
+        self._loop = loop
+        self._records_publisher = records_publisher
+
+        self._nsm_plugins = NsmPlugins()
+
+        self._ro_sub = ROAccountConfigSubscriber(
+                self._log,
+                self._dts,
+                self._loop,
+                callback=self.on_ro_account_change
+                )
+
+        # The default plugin will be RwNsPlugin
+        self._plugin_instances = {}
+        self._ro_plugin = self._create_plugin(self.DEFAULT_PLUGIN, None)
+
+    @property
+    def ro_plugin(self):
+        return self._ro_plugin
+
+    def on_ro_account_change(self, ro_account, action):
+        if action == rwdts.QueryAction.CREATE:
+            self._on_ro_account_added(ro_account)
+        elif action == rwdts.QueryAction.DELETE:
+            self._on_ro_account_deleted(ro_account)
+
+    def _on_ro_account_added(self, ro_account):
+        self._log.debug("Got nsm plugin RO account: %s", ro_account)
+        try:
+            nsm_cls = self._nsm_plugins.class_by_plugin_name(
+                    ro_account.account_type
+                    )
+        except KeyError as e:
+            self._log.debug(
+                "RO account nsm plugin not found: %s.  Using standard rift nsm.",
+                ro_account.name
+                )
+            nsm_cls = self.DEFAULT_PLUGIN
+
+        self._ro_plugin = self._create_plugin(nsm_cls, ro_account)
+
+    def _on_ro_account_deleted(self, ro_account):
+        self._ro_plugin = None
+
+    def _create_plugin(self, nsm_cls, ro_account):
+        # Check to see if the plugin was already instantiated
+        if nsm_cls in self._plugin_instances:
+            self._log.debug("RO account nsm plugin already instantiated.  Using existing.")
+            return self._plugin_instances[nsm_cls]
+
+        # Otherwise, instantiate a new plugin using the cloud account
+        self._log.debug("Instantiating new RO account using class: %s", nsm_cls)
+        nsm_instance = nsm_cls(self._dts, self._log, self._loop,
+                               self._records_publisher, ro_account)
+
+        self._plugin_instances[nsm_cls] = nsm_instance
+        return nsm_instance
+
+    @asyncio.coroutine
+    def register(self):
+        yield from self._ro_sub.register()