X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=common%2Fpython%2Frift%2Fmano%2Fsdn%2Faccounts.py;fp=common%2Fpython%2Frift%2Fmano%2Fsdn%2Faccounts.py;h=d539ead5ef9fe12aec0fe09a73c312fc79909f36;hb=7b75903dd891795d4426612fd4de76c0f51cf17e;hp=0000000000000000000000000000000000000000;hpb=3fdf6a93baec6d042f79a44973a3d21ddf37bafc;p=osm%2FSO.git diff --git a/common/python/rift/mano/sdn/accounts.py b/common/python/rift/mano/sdn/accounts.py new file mode 100644 index 00000000..d539ead5 --- /dev/null +++ b/common/python/rift/mano/sdn/accounts.py @@ -0,0 +1,157 @@ + +# +# Copyright 2017 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 sys +import asyncio +from gi import require_version +require_version('RwTypes', '1.0') +require_version('RwsdnalYang', '1.0') +require_version('RwSdnYang', '1.0') + +from gi.repository import ( + RwTypes, + RwsdnalYang, + RwSdnYang, + ) +import rw_peas + +if sys.version_info < (3, 4, 4): + asyncio.ensure_future = asyncio.async + + +class PluginLoadingError(Exception): + pass + + +class SDNAccountCalError(Exception): + pass + + +class SDNAccount(object): + def __init__(self, log, rwlog_hdl, account_msg): + self._log = log + self._account_msg = account_msg.deep_copy() + + self._sdn_plugin = None + self._engine = None + + self._sdn = self.plugin.get_interface("Topology") + self._sdn.init(rwlog_hdl) + + self._status = RwsdnalYang.SDNAccount_ConnectionStatus( + status="unknown", + details="Connection status lookup not started" + ) + + self._validate_task = None + + @property + def plugin(self): + if self._sdn_plugin is None: + try: + self._sdn_plugin = rw_peas.PeasPlugin( + getattr(self._account_msg, self.account_type).plugin_name, + 'RwSdn-1.0', + ) + + except AttributeError as e: + raise PluginLoadingError(str(e)) + + self._engine, _, _ = self._sdn_plugin() + + return self._sdn_plugin + + def _wrap_status_fn(self, fn, *args, **kwargs): + ret = fn(*args, **kwargs) + rw_status = ret[0] + if rw_status != RwTypes.RwStatus.SUCCESS: + msg = "%s returned %s" % (fn.__name__, str(rw_status)) + self._log.error(msg) + raise SDNAccountCalError(msg) + + # If there was only one other return value besides rw_status, then just + # return that element. Otherwise return the rest of the return values + # as a list. + return ret[1] if len(ret) == 2 else ret[1:] + + @property + def sdn(self): + return self._sdn + + @property + def name(self): + return self._account_msg.name + + @property + def account_msg(self): + return self._account_msg + + @property + def sdnal_account_msg(self): + return RwsdnalYang.SDNAccount.from_dict( + self.account_msg.as_dict(), + ignore_missing_keys=True, + ) + + def sdn_account_msg(self, account_dict): + self._account_msg = RwSdnYang.SDNAccount.from_dict(account_dict) + + @property + def account_type(self): + return self._account_msg.account_type + + @property + def connection_status(self): + return self._status + + def update_from_cfg(self, cfg): + self._log.debug("Updating parent SDN Account to %s", cfg) + + raise NotImplementedError("Update SDN account not yet supported") + + + @asyncio.coroutine + def validate_sdn_account_credentials(self, loop): + self._log.debug("Validating SDN Account credentials %s", self._account_msg) + self._status = RwSdnYang.SDNAccount_ConnectionStatus( + status="validating", + details="SDN account connection validation in progress" + ) + rwstatus, status = yield from loop.run_in_executor( + None, + self._sdn.validate_sdn_creds, + self.sdnal_account_msg, + ) + if rwstatus == RwTypes.RwStatus.SUCCESS: + self._status = RwSdnYang.SDNAccount_ConnectionStatus.from_dict(status.as_dict()) + else: + self._status = RwSdnYang.SDNAccount_ConnectionStatus( + status="failure", + details="Error when calling SDNAL validate SDN creds" + ) + + self._log.info("Got SDN account validation response: %s", self._status) + + def start_validate_credentials(self, loop): + if self._validate_task is not None: + self._validate_task.cancel() + self._validate_task = None + + self._validate_task = asyncio.ensure_future( + self.validate_sdn_account_credentials(loop), + loop=loop + )