rw.core.mano-mano_yang_ylib-1.0 \
rw.core.mano-common-1.0 \
rw.core.mano-rwsdn_yang_ylib-1.0 \
+ rw.core.mano-rwsdnal_yang_ylib-1.0 \
+ rw.core.mano-rwsdn-1.0 \
rw.core.mano-mano-types_yang_ylib-1.0 \
rw.core.mano-rwcal-cloudsim-1.0 \
rw.core.mano-rwcal-1.0 \
##
# Yang targets
##
+rift_add_yang_target(
+ TARGET rwsdn_yang
+ YANG_FILES rw-sdn.yang
+ COMPONENT ${PKG_LONG_NAME}
+ LIBRARIES
+ rwsdnal_yang_gen
+ DEPENDS
+ rwsdnal_yang
+)
+
rift_add_yang_target(
TARGET rwcloud_yang
- YANG_FILES rw-cloud.yang rw-sdn.yang
+ YANG_FILES rw-cloud.yang
COMPONENT ${PKG_LONG_NAME}
LIBRARIES
rwsdn_yang_gen
rwcal_yang_gen
DEPENDS
rwcal_yang
+ rwsdnal_yang
)
rift_add_yang_target(
prefix "rwpb";
}
- import rwsdn {
- prefix "rwsdn";
+ import rwsdnal {
+ prefix "rwsdnal";
}
revision 2015-09-14 {
}
container sdn {
+ rwpb:msg-new SDNAccountConfig;
list account {
- rwpb:msg-new SDNAccountConfig;
+ rwpb:msg-new SDNAccount;
key "name";
leaf name {
type string;
}
- uses rwsdn:sdn-provider-auth;
- uses rwsdn:connection-status;
+ uses rwsdnal:sdn-provider-auth;
+ uses rwsdnal:connection-status;
}
}
PYTHON3_ONLY
)
+rift_python_install_tree(
+ FILES
+ rift/mano/sdn/__init__.py
+ rift/mano/sdn/accounts.py
+ rift/mano/sdn/config.py
+ rift/mano/sdn/operdata.py
+ COMPONENT ${PKG_LONG_NAME}
+ PYTHON3_ONLY
+ )
+
rift_python_install_tree(
FILES
rift/mano/config_agent/operdata.py
--- /dev/null
+
+#
+# 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.
+#
+
+from .accounts import (
+ SDNAccount,
+ SDNAccountCalError,
+ )
+
+from .config import (
+ SDNAccountConfigSubscriber,
+ SDNAccountConfigCallbacks
+ )
+
+from .operdata import (
+ SDNAccountDtsOperdataHandler,
+)
--- /dev/null
+
+#
+# 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
+ )
--- /dev/null
+
+#
+# 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 asyncio
+
+import gi
+gi.require_version('RwDts', '1.0')
+import rift.tasklets
+
+from gi.repository import (
+ RwDts as rwdts,
+ ProtobufC,
+ )
+
+from . import accounts
+
+
+class SDNAccountNotFound(Exception):
+ pass
+
+
+class SDNAccountError(Exception):
+ pass
+
+
+def get_add_delete_update_cfgs(dts_member_reg, xact, key_name):
+ # Unforunately, it is currently difficult to figure out what has exactly
+ # changed in this xact without Pbdelta support (RIFT-4916)
+ # As a workaround, we can fetch the pre and post xact elements and
+ # perform a comparison to figure out adds/deletes/updates
+ xact_cfgs = list(dts_member_reg.get_xact_elements(xact))
+ curr_cfgs = list(dts_member_reg.elements)
+
+ xact_key_map = {getattr(cfg, key_name): cfg for cfg in xact_cfgs}
+ curr_key_map = {getattr(cfg, key_name): cfg for cfg in curr_cfgs}
+
+ # Find Adds
+ added_keys = set(xact_key_map) - set(curr_key_map)
+ added_cfgs = [xact_key_map[key] for key in added_keys]
+
+ # Find Deletes
+ deleted_keys = set(curr_key_map) - set(xact_key_map)
+ deleted_cfgs = [curr_key_map[key] for key in deleted_keys]
+
+ # Find Updates
+ updated_keys = set(curr_key_map) & set(xact_key_map)
+ updated_cfgs = [xact_key_map[key] for key in updated_keys if xact_key_map[key] != curr_key_map[key]]
+
+ return added_cfgs, deleted_cfgs, updated_cfgs
+
+
+class SDNAccountConfigCallbacks(object):
+ def __init__(self,
+ on_add_apply=None, on_add_prepare=None,
+ on_delete_apply=None, on_delete_prepare=None):
+
+ @asyncio.coroutine
+ def prepare_noop(*args, **kwargs):
+ pass
+
+ def apply_noop(*args, **kwargs):
+ pass
+
+ self.on_add_apply = on_add_apply
+ self.on_add_prepare = on_add_prepare
+ self.on_delete_apply = on_delete_apply
+ self.on_delete_prepare = on_delete_prepare
+
+ for f in ('on_add_apply', 'on_delete_apply'):
+ ref = getattr(self, f)
+ if ref is None:
+ setattr(self, f, apply_noop)
+ continue
+
+ if asyncio.iscoroutinefunction(ref):
+ raise ValueError('%s cannot be a coroutine' % (f,))
+
+ for f in ('on_add_prepare', 'on_delete_prepare'):
+ ref = getattr(self, f)
+ if ref is None:
+ setattr(self, f, prepare_noop)
+ continue
+
+ if not asyncio.iscoroutinefunction(ref):
+ raise ValueError("%s must be a coroutine" % f)
+
+
+class SDNAccountConfigSubscriber(object):
+ XPATH = "C,/rw-sdn:sdn/rw-sdn:account"
+
+ def __init__(self, dts, log, rwlog_hdl, sdn_callbacks, acctstore):
+ self._dts = dts
+ self._log = log
+ self._rwlog_hdl = rwlog_hdl
+ self._reg = None
+
+ self.accounts = acctstore
+
+ self._sdn_callbacks = sdn_callbacks
+
+ def add_account(self, account_msg):
+ self._log.info("adding sdn account: {}".format(account_msg))
+
+ account = accounts.SDNAccount(self._log, self._rwlog_hdl, account_msg)
+ self.accounts[account.name] = account
+
+ self._sdn_callbacks.on_add_apply(account)
+
+ def delete_account(self, account_name):
+ self._log.info("deleting sdn account: {}".format(account_name))
+ del self.accounts[account_name]
+
+ self._sdn_callbacks.on_delete_apply(account_name)
+
+ def update_account(self, account_msg):
+ """ Update an existing sdn account
+
+ In order to simplify update, turn an update into a delete followed by
+ an add. The drawback to this approach is that we will not support
+ updates of an "in-use" sdn account, but this seems like a
+ reasonable trade-off.
+
+
+ Arguments:
+ account_msg - The sdn account config message
+ """
+ self._log.info("updating sdn account: {}".format(account_msg))
+
+ self.delete_account(account_msg.name)
+ self.add_account(account_msg)
+
+ def register(self):
+ @asyncio.coroutine
+ def apply_config(dts, acg, xact, action, _):
+ self._log.debug("Got sdn account apply config (xact: %s) (action: %s)", xact, action)
+
+ if xact.xact is None:
+ if action == rwdts.AppconfAction.INSTALL:
+ curr_cfg = self._reg.elements
+ for cfg in curr_cfg:
+ self._log.debug("SDN account being re-added after restart.")
+ if not cfg.has_field('account_type'):
+ raise SDNAccountError("New SDN account must contain account_type field.")
+ self.add_account(cfg)
+ else:
+ # When RIFT first comes up, an INSTALL is called with the current config
+ # Since confd doesn't actally persist data this never has any data so
+ # skip this for now.
+ self._log.debug("No xact handle. Skipping apply config")
+
+ return
+
+ add_cfgs, delete_cfgs, update_cfgs = get_add_delete_update_cfgs(
+ dts_member_reg=self._reg,
+ xact=xact,
+ key_name="name",
+ )
+
+ # Handle Deletes
+ for cfg in delete_cfgs:
+ self.delete_account(cfg.name)
+
+ # Handle Adds
+ for cfg in add_cfgs:
+ self.add_account(cfg)
+
+ # Handle Updates
+ for cfg in update_cfgs:
+ self.update_account(cfg)
+
+ @asyncio.coroutine
+ def on_prepare(dts, acg, xact, xact_info, ks_path, msg, scratch):
+ """ Prepare callback from DTS for SDN Account """
+
+ action = xact_info.query_action
+ self._log.debug("SDN account on_prepare config received (action: %s): %s",
+ xact_info.query_action, msg)
+
+ if action in [rwdts.QueryAction.CREATE, rwdts.QueryAction.UPDATE]:
+ if msg.name in self.accounts:
+ self._log.debug("SDN account already exists. Invoking update request")
+
+ # Since updates are handled by a delete followed by an add, invoke the
+ # delete prepare callbacks to give clients an opportunity to reject.
+ yield from self._sdn_callbacks.on_delete_prepare(msg.name)
+
+ else:
+ self._log.debug("SDN account does not already exist. Invoking on_prepare add request")
+ if not msg.has_field('account_type'):
+ raise SDNAccountError("New sdn account must contain account_type field.")
+
+ account = accounts.SDNAccount(self._log, self._rwlog_hdl, msg)
+ yield from self._sdn_callbacks.on_add_prepare(account)
+
+ elif action == rwdts.QueryAction.DELETE:
+ # Check if the entire SDN account got deleted
+ fref = ProtobufC.FieldReference.alloc()
+ fref.goto_whole_message(msg.to_pbcm())
+ if fref.is_field_deleted():
+ yield from self._sdn_callbacks.on_delete_prepare(msg.name)
+
+ else:
+ self._log.error("Deleting individual fields for SDN account not supported")
+ xact_info.respond_xpath(rwdts.XactRspCode.NACK)
+ return
+
+ else:
+ self._log.error("Action (%s) NOT SUPPORTED", action)
+ xact_info.respond_xpath(rwdts.XactRspCode.NACK)
+
+ xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+ self._log.debug("Registering for SDN Account config using xpath: %s",
+ SDNAccountConfigSubscriber.XPATH,
+ )
+
+ acg_handler = rift.tasklets.AppConfGroup.Handler(
+ on_apply=apply_config,
+ )
+
+ with self._dts.appconf_group_create(acg_handler) as acg:
+ self._reg = acg.register(
+ xpath=SDNAccountConfigSubscriber.XPATH,
+ flags=rwdts.Flag.SUBSCRIBER | rwdts.Flag.DELTA_READY | rwdts.Flag.CACHE,
+ on_prepare=on_prepare,
+ )
--- /dev/null
+
+#
+# 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 asyncio
+import rift.tasklets
+
+from gi.repository import(
+ RwSdnYang,
+ RwDts as rwdts,
+ )
+
+
+class SDNAccountNotFound(Exception):
+ pass
+
+
+class SDNAccountDtsOperdataHandler(object):
+ def __init__(self, dts, log, loop):
+ self._dts = dts
+ self._log = log
+ self._loop = loop
+
+ self.sdn_accounts = {}
+
+ def add_sdn_account(self, account):
+ self.sdn_accounts[account.name] = account
+ account.start_validate_credentials(self._loop)
+
+ def delete_sdn_account(self, account_name):
+ del self.sdn_accounts[account_name]
+
+ def get_saved_sdn_accounts(self, sdn_account_name):
+ ''' Get SDN Account corresponding to passed name, or all saved accounts if name is None'''
+ saved_sdn_accounts = []
+
+ if sdn_account_name is None or sdn_account_name == "":
+ sdn_accounts = list(self.sdn_accounts.values())
+ saved_sdn_accounts.extend(sdn_accounts)
+ elif sdn_account_name in self.sdn_accounts:
+ account = self.sdn_accounts[sdn_account_name]
+ saved_sdn_accounts.append(account)
+ else:
+ errstr = "SDN account {} does not exist".format(sdn_account_name)
+ raise KeyError(errstr)
+
+ return saved_sdn_accounts
+
+ def _register_show_status(self):
+ def get_xpath(sdn_name=None):
+ return "D,/rw-sdn:sdn/account{}/connection-status".format(
+ "[name='%s']" % sdn_name if sdn_name is not None else ''
+ )
+
+ @asyncio.coroutine
+ def on_prepare(xact_info, action, ks_path, msg):
+ self._log.debug("Got show SDN connection status request: %s", ks_path.create_string())
+ path_entry = RwSdnYang.SDNAccount.schema().keyspec_to_entry(ks_path)
+ sdn_account_name = path_entry.key00.name
+
+ try:
+ saved_accounts = self.get_saved_sdn_accounts(sdn_account_name)
+ for account in saved_accounts:
+ connection_status = account.connection_status
+ self._log.debug("Responding to SDN connection status request: %s", connection_status)
+ xact_info.respond_xpath(
+ rwdts.XactRspCode.MORE,
+ xpath=get_xpath(account.name),
+ msg=account.connection_status,
+ )
+ except KeyError as e:
+ self._log.warning(str(e))
+ xact_info.respond_xpath(rwdts.XactRspCode.NA)
+ return
+
+ xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+ yield from self._dts.register(
+ xpath=get_xpath(),
+ handler=rift.tasklets.DTS.RegistrationHandler(
+ on_prepare=on_prepare),
+ flags=rwdts.Flag.PUBLISHER,
+ )
+
+ def _register_validate_rpc(self):
+ def get_xpath():
+ return "/rw-sdn:update-sdn-status"
+
+ @asyncio.coroutine
+ def on_prepare(xact_info, action, ks_path, msg):
+ if not msg.has_field("sdn_account"):
+ raise SDNAccountNotFound("SDN account name not provided")
+
+ sdn_account_name = msg.sdn_account
+ try:
+ account = self.sdn_accounts[sdn_account_name]
+ except KeyError:
+ raise SDNAccountNotFound("SDN account name %s not found" % sdn_account_name)
+
+ account.start_validate_credentials(self._loop)
+
+ xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+ yield from self._dts.register(
+ xpath=get_xpath(),
+ handler=rift.tasklets.DTS.RegistrationHandler(
+ on_prepare=on_prepare
+ ),
+ flags=rwdts.Flag.PUBLISHER,
+ )
+
+ @asyncio.coroutine
+ def register(self):
+ yield from self._register_show_status()
+ yield from self._register_validate_rpc()
uses connection-status;
- typedef sdn-account-type {
- description "SDN account type";
- type enumeration {
- enum odl;
- enum mock;
- enum sdnsim;
- }
- }
-
- grouping sdn-provider-auth {
- leaf account-type {
- type sdn-account-type;
- }
-
- choice provider-specific-info {
- container odl {
- leaf username {
- type string {
- length "1..255";
- }
- }
-
- leaf password {
- type string {
- length "1..32";
- }
- }
-
- leaf url {
- type string {
- length "1..255";
- }
- }
- }
- container mock {
- leaf username {
- type string;
- }
- leaf plugin-name {
- type string;
- default "rwsdn_mock";
- }
- }
-
- container sdnsim {
- leaf username {
- type string;
- }
- leaf plugin-name {
- type string;
- default "rwsdn_sim";
- }
- }
- }
- }
-
grouping provider-auth {
leaf account-type {
type manotypes:cloud-account-type;
rw-pb-ext
rw-resource-mgr
rw-restportforward
-rwsdn
+rwsdnal
rw-sdn
rwshell-mgmt
rw-sorch
VnfrYang,
RwVnfrYang,
RwNsmYang,
- RwsdnYang,
+ RwsdnalYang,
RwDts as rwdts,
RwTypes,
ProtobufC,
vnfr = yield from self._nsr.fetch_vnfr(nsr_vnfr.xpath)
self._log.debug("Received VNFR is %s", vnfr)
- sff = RwsdnYang.VNFFGSff()
+ sff = RwsdnalYang.VNFFGSff()
sff_list[nsr_vnfr.vnfd.id] = sff
sff.name = nsr_vnfr.name
sff.function_type = nsr_vnfr.vnfd.service_function_chain
from gi.repository import (
RwDts as rwdts,
- RwsdnYang,
+ RwsdnalYang,
RwTypes,
ProtobufC,
)
if (account.name in self._account):
self._log.error("SDN Account is already set")
else:
- sdn_account = RwsdnYang.SDNAccount()
+ sdn_account = RwsdnalYang.SDNAccount()
sdn_account.from_dict(account.as_dict())
sdn_account.name = account.name
self._account[account.name] = sdn_account
def get_sdn_account(self, name):
"""
- Creates an object for class RwsdnYang.SdnAccount()
+ Creates an object for class RwsdnalYang.SdnAccount()
"""
if (name in self._account):
return self._account[name]
sdn_plugin = self.get_sdn_plugin(sdn_acct_name)
for rsp in vnffgr.rsp:
- vnffg = RwsdnYang.VNFFGChain()
+ vnffg = RwsdnalYang.VNFFGChain()
vnffg.name = rsp.name
vnffg.classifier_name = rsp.classifier_name
else:
self._log.error("No RSP wiht name %s found; Skipping classifier %s creation",classifier.rsp_id_ref,classifier.name)
continue
- vnffgcl = RwsdnYang.VNFFGClassifier()
+ vnffgcl = RwsdnalYang.VNFFGClassifier()
vnffgcl.name = classifier.name
vnffgcl.rsp_name = cl_rsp_name
vnffgcl.port_id = vnffgr_cl[0].port_id
#
import asyncio
-import logging
-import os
import sys
import gi
gi.require_version('RwDts', '1.0')
from gi.repository import (
RwVnsYang,
- RwSdnYang,
RwDts as rwdts,
RwTypes,
- ProtobufC,
)
import rift.tasklets
+import rift.mano.sdn
from rift.vlmgr import (
VlrDtsHandler,
NwtopStaticDtsHandler,
NwtopDiscoveryDtsHandler,
NwtopDataStore,
- SdnAccountMgr,
)
-class SdnInterfaceError(Exception):
- """ SDN interface creation Error """
- pass
-
-
-class SdnPluginError(Exception):
- """ SDN plugin creation Error """
- pass
-
-
class VlRecordError(Exception):
""" Vlr Record creation Error """
pass
""" Vlr Record not found"""
pass
-class SdnAccountError(Exception):
- """ Error while creating/deleting/updating SDN Account"""
- pass
-class SdnAccountNotFound(Exception):
- pass
-
-class SDNAccountDtsOperdataHandler(object):
- def __init__(self, dts, log, loop, parent):
- self._dts = dts
+class SDNAccountHandlers(object):
+ def __init__(self, dts, log, log_hdl, acctstore, loop):
self._log = log
- self._loop = loop
- self._parent = parent
-
- def _register_show_status(self):
- def get_xpath(sdn_name=None):
- return "D,/rw-sdn:sdn/rw-sdn:account{}/rw-sdn:connection-status".format(
- "[name='%s']" % sdn_name if sdn_name is not None else ''
- )
-
- @asyncio.coroutine
- def on_prepare(xact_info, action, ks_path, msg):
- path_entry = RwSdnYang.SDNAccountConfig.schema().keyspec_to_entry(ks_path)
- sdn_account_name = path_entry.key00.name
- self._log.debug("Got show sdn connection status request: %s", ks_path.create_string())
-
- try:
- saved_accounts = self._parent._acctmgr.get_saved_sdn_accounts(sdn_account_name)
- for account in saved_accounts:
- sdn_acct = RwSdnYang.SDNAccountConfig()
- sdn_acct.from_dict(account.as_dict())
-
- self._log.debug("Responding to sdn connection status request: %s", sdn_acct.connection_status)
- xact_info.respond_xpath(
- rwdts.XactRspCode.MORE,
- xpath=get_xpath(account.name),
- msg=sdn_acct.connection_status,
- )
- except KeyError as e:
- self._log.warning(str(e))
- xact_info.respond_xpath(rwdts.XactRspCode.NA)
- return
-
- xact_info.respond_xpath(rwdts.XactRspCode.ACK)
-
- yield from self._dts.register(
- xpath=get_xpath(),
- handler=rift.tasklets.DTS.RegistrationHandler(
- on_prepare=on_prepare),
- flags=rwdts.Flag.PUBLISHER,
- )
-
- def _register_validate_rpc(self):
- def get_xpath():
- return "/rw-sdn:update-sdn-status"
-
- @asyncio.coroutine
- def on_prepare(xact_info, action, ks_path, msg):
- if not msg.has_field("sdn_account"):
- raise SdnAccountNotFound("SDN account name not provided")
-
- sdn_account_name = msg.sdn_account
- account = self._parent._acctmgr.get_sdn_account(sdn_account_name)
- if account is None:
- self._log.warning("SDN account %s does not exist", sdn_account_name)
- xact_info.respond_xpath(rwdts.XactRspCode.NA)
- return
-
- self._parent._acctmgr.start_validate_credentials(self._loop, sdn_account_name)
-
- xact_info.respond_xpath(rwdts.XactRspCode.ACK)
-
- yield from self._dts.register(
- xpath=get_xpath(),
- handler=rift.tasklets.DTS.RegistrationHandler(
- on_prepare=on_prepare
- ),
- flags=rwdts.Flag.PUBLISHER,
- )
-
- @asyncio.coroutine
- def register(self):
- yield from self._register_show_status()
- yield from self._register_validate_rpc()
-
-class SDNAccountDtsHandler(object):
- XPATH = "C,/rw-sdn:sdn/rw-sdn:account"
-
- def __init__(self, dts, log, parent):
+ self._log_hdl = log_hdl
self._dts = dts
- self._log = log
- self._parent = parent
-
- self._sdn_account = {}
-
- def _set_sdn_account(self, account):
- self._log.info("Setting sdn account: {}".format(account))
- if account.name in self._sdn_account:
- self._log.error("SDN Account with name %s already exists. Ignoring config", account.name);
- self._sdn_account[account.name] = account
- self._parent._acctmgr.set_sdn_account(account)
-
- def _del_sdn_account(self, account_name):
- self._log.info("Deleting sdn account: {}".format(account_name))
- del self._sdn_account[account_name]
-
- self._parent._acctmgr.del_sdn_account(account_name)
-
- def _update_sdn_account(self, account):
- self._log.info("Updating sdn account: {}".format(account))
- # No need to update locally saved sdn_account's updated fields, as they
- # are not used anywhere. Call the parent's update callback.
- self._parent._acctmgr.update_sdn_account(account)
-
+ self._loop = loop
+ self._acctstore = acctstore
+
+ self._log.debug("Creating SDN account config handler")
+ self.sdn_cfg_handler = rift.mano.sdn.SDNAccountConfigSubscriber(
+ self._dts, self._log, self._log_hdl,
+ rift.mano.sdn.SDNAccountConfigCallbacks(
+ on_add_apply=self.on_sdn_account_added,
+ on_delete_apply=self.on_sdn_account_deleted,
+ ),
+ self._acctstore
+
+ )
+
+ self._log.debug("Creating SDN account opdata handler")
+ self.sdn_operdata_handler = rift.mano.sdn.SDNAccountDtsOperdataHandler(
+ self._dts, self._log, self._loop,
+ )
+
+ def on_sdn_account_deleted(self, account_name):
+ self._log.debug("SDN account deleted")
+ self.sdn_operdata_handler.delete_sdn_account(account_name)
+
+ def on_sdn_account_added(self, account):
+ self._log.debug("SDN account added")
+ self.sdn_operdata_handler.add_sdn_account(account)
+
@asyncio.coroutine
def register(self):
- def apply_config(dts, acg, xact, action, _):
- self._log.debug("Got sdn account apply config (xact: %s) (action: %s)", xact, action)
- if action == rwdts.AppconfAction.INSTALL and xact.id is None:
- self._log.debug("No xact handle. Skipping apply config")
- return RwTypes.RwStatus.SUCCESS
-
- return RwTypes.RwStatus.SUCCESS
-
- @asyncio.coroutine
- def on_prepare(dts, acg, xact, xact_info, ks_path, msg, scratch):
- """ Prepare callback from DTS for SDN Account config """
-
- self._log.info("SDN Cloud account config received: %s", msg)
-
- fref = ProtobufC.FieldReference.alloc()
- fref.goto_whole_message(msg.to_pbcm())
-
- if fref.is_field_deleted():
- # Delete the sdn account record
- self._del_sdn_account(msg.name)
- else:
- # If the account already exists, then this is an update.
- if msg.name in self._sdn_account:
- self._log.debug("SDN account already exists. Invoking on_prepare update request")
- if msg.has_field("account_type"):
- errmsg = "Cannot update SDN account's account-type."
- self._log.error(errmsg)
- xact_info.send_error_xpath(RwTypes.RwStatus.FAILURE,
- SDNAccountDtsHandler.XPATH,
- errmsg)
- raise SdnAccountError(errmsg)
-
- # Update the sdn account record
- self._update_sdn_account(msg)
- else:
- self._log.debug("SDN account does not already exist. Invoking on_prepare add request")
- if not msg.has_field('account_type'):
- errmsg = "New SDN account must contain account-type field."
- self._log.error(errmsg)
- xact_info.send_error_xpath(RwTypes.RwStatus.FAILURE,
- SDNAccountDtsHandler.XPATH,
- errmsg)
- raise SdnAccountError(errmsg)
-
- # Set the sdn account record
- self._set_sdn_account(msg)
-
- xact_info.respond_xpath(rwdts.XactRspCode.ACK)
-
-
- self._log.debug("Registering for Sdn Account config using xpath: %s",
- SDNAccountDtsHandler.XPATH,
- )
-
- acg_handler = rift.tasklets.AppConfGroup.Handler(
- on_apply=apply_config,
- )
-
- with self._dts.appconf_group_create(acg_handler) as acg:
- acg.register(
- xpath=SDNAccountDtsHandler.XPATH,
- flags=rwdts.Flag.SUBSCRIBER | rwdts.Flag.DELTA_READY,
- on_prepare=on_prepare
- )
+ self.sdn_cfg_handler.register()
+ yield from self.sdn_operdata_handler.register()
class VnsManager(object):
self._log = log
self._log_hdl = log_hdl
self._loop = loop
+ self._acctstore = {}
self._vlr_handler = VlrDtsHandler(dts, log, loop, self)
self._vld_handler = VldDtsHandler(dts, log, loop, self)
- self._sdn_handler = SDNAccountDtsHandler(dts,log,self)
- self._sdn_opdata_handler = SDNAccountDtsOperdataHandler(dts,log, loop, self)
- self._acctmgr = SdnAccountMgr(self._log, self._log_hdl, self._loop)
+ self._sdn_handlers = SDNAccountHandlers(dts, log, log_hdl, self._acctstore, loop)
self._nwtopdata_store = NwtopDataStore(log)
- self._nwtopdiscovery_handler = NwtopDiscoveryDtsHandler(dts, log, loop, self._acctmgr, self._nwtopdata_store)
- self._nwtopstatic_handler = NwtopStaticDtsHandler(dts, log, loop, self._acctmgr, self._nwtopdata_store)
+ self._nwtopdiscovery_handler = NwtopDiscoveryDtsHandler(dts, log, loop, self._acctstore, self._nwtopdata_store)
+ self._nwtopstatic_handler = NwtopStaticDtsHandler(dts, log, loop, self._acctstore, self._nwtopdata_store)
self._vlrs = {}
@asyncio.coroutine
yield from self._vld_handler.register()
@asyncio.coroutine
- def register_sdn_handler(self):
- """ Register vlr DTS handler """
- self._log.debug("Registering SDN Account config handler")
- yield from self._sdn_handler.register()
- yield from self._sdn_opdata_handler.register()
+ def register_sdn_handlers(self):
+ """ Register SDN DTS handlers """
+ self._log.debug("Registering SDN Account handlers")
+ yield from self._sdn_handlers.register()
@asyncio.coroutine
def register_nwtopstatic_handler(self):
@asyncio.coroutine
def register(self):
""" Register all static DTS handlers"""
- yield from self.register_sdn_handler()
+ yield from self.register_sdn_handlers()
yield from self.register_vlr_handler()
yield from self.register_vld_handler()
yield from self.register_nwtopstatic_handler()
- # Not used for now
yield from self.register_nwtopdiscovery_handler()
def create_vlr(self, msg):
from .rwtopmgr import (
NwtopDiscoveryDtsHandler,
NwtopStaticDtsHandler,
- SdnAccountMgr,
)
from .rwtopdatastore import (
IetfNetworkTopologyYang,
IetfL2TopologyYang,
RwTopologyYang,
- RwsdnYang,
+ RwsdnalYang,
RwTypes
)
from gi.repository.RwTypes import RwStatus
-import rw_peas
import rift.tasklets
-class SdnGetPluginError(Exception):
- """ Error while fetching SDN plugin """
- pass
-
-
-class SdnGetInterfaceError(Exception):
- """ Error while fetching SDN interface"""
- pass
-
-
-class SdnAccountMgr(object):
- """ Implements the interface to backend plugins to fetch topology """
- def __init__(self, log, log_hdl, loop):
- self._account = {}
- self._log = log
- self._log_hdl = log_hdl
- self._loop = loop
- self._sdn = {}
-
- self._regh = None
-
- self._status = RwsdnYang.SDNAccount_ConnectionStatus(
- status='unknown',
- details="Connection status lookup not started"
- )
-
- self._validate_task = None
-
- def set_sdn_account(self,account):
- if (account.name in self._account):
- self._log.error("SDN Account is already set")
- else:
- sdn_account = RwsdnYang.SDNAccount()
- sdn_account.from_dict(account.as_dict())
- sdn_account.name = account.name
- self._account[account.name] = sdn_account
- self._log.debug("Account set is %s , %s",type(self._account), self._account)
- self.start_validate_credentials(self._loop, account.name)
-
- def del_sdn_account(self, name):
- self._log.debug("Account deleted is %s , %s", type(self._account), name)
- del self._account[name]
-
- def update_sdn_account(self,account):
- self._log.debug("Account updated is %s , %s", type(self._account), account)
- if account.name in self._account:
- sdn_account = self._account[account.name]
-
- sdn_account.from_dict(
- account.as_dict(),
- ignore_missing_keys=True,
- )
- self._account[account.name] = sdn_account
- self.start_validate_credentials(self._loop, account.name)
-
- def get_sdn_account(self, name):
- """
- Creates an object for class RwsdnYang.SdnAccount()
- """
- if (name in self._account):
- return self._account[name]
- else:
- self._log.error("ERROR : SDN account is not configured")
-
- def get_saved_sdn_accounts(self, name):
- ''' Get SDN Account corresponding to passed name, or all saved accounts if name is None'''
- saved_sdn_accounts = []
-
- if name is None or name == "":
- sdn_accounts = list(self._account.values())
- saved_sdn_accounts.extend(sdn_accounts)
- elif name in self._account:
- account = self._account[name]
- saved_sdn_accounts.append(account)
- else:
- errstr = "SDN account {} does not exist".format(name)
- raise KeyError(errstr)
-
- return saved_sdn_accounts
-
- def get_sdn_plugin(self,name):
- """
- Loads rw.sdn plugin via libpeas
- """
- if (name in self._sdn):
- return self._sdn[name]
- account = self.get_sdn_account(name)
- plugin_name = getattr(account, account.account_type).plugin_name
- self._log.info("SDN plugin being created")
- plugin = rw_peas.PeasPlugin(plugin_name, 'RwSdn-1.0')
- engine, info, extension = plugin()
-
- self._sdn[name] = plugin.get_interface("Topology")
- try:
- rc = self._sdn[name].init(self._log_hdl)
- assert rc == RwStatus.SUCCESS
- except:
- self._log.error("ERROR:SDN plugin instantiation failed ")
- else:
- self._log.info("SDN plugin successfully instantiated")
- return self._sdn[name]
-
- @asyncio.coroutine
- def validate_sdn_account_credentials(self, loop, name):
- self._log.debug("Validating SDN Account credentials %s", name)
- self._status = RwsdnYang.SDNAccount_ConnectionStatus(
- status="validating",
- details="SDN account connection validation in progress"
- )
-
- _sdnacct = self.get_sdn_account(name)
- if (_sdnacct is None):
- raise SdnGetPluginError
- _sdnplugin = self.get_sdn_plugin(name)
- if (_sdnplugin is None):
- raise SdnGetInterfaceError
-
- rwstatus, status = yield from loop.run_in_executor(
- None,
- _sdnplugin.validate_sdn_creds,
- _sdnacct,
- )
-
- 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 CAL validate sdn creds"
- )
-
- self._log.info("Got sdn account validation response: %s", self._status)
- _sdnacct.connection_status = self._status
-
- def start_validate_credentials(self, loop, name):
- 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, name),
- loop=loop
- )
-
class NwtopDiscoveryDtsHandler(object):
""" Handles DTS interactions for the Discovered Topology registration """
DISC_XPATH = "D,/nd:network"
- def __init__(self, dts, log, loop, acctmgr, nwdatastore):
+ def __init__(self, dts, log, loop, acctstore, nwdatastore):
self._dts = dts
self._log = log
self._loop = loop
- self._acctmgr = acctmgr
+ self._acctstore = acctstore
self._nwdatastore = nwdatastore
self._regh = None
if action == rwdts.QueryAction.READ:
- for name in self._acctmgr._account:
- _sdnacct = self._acctmgr.get_sdn_account(name)
- if (_sdnacct is None):
- raise SdnGetPluginError
-
- _sdnplugin = self._acctmgr.get_sdn_plugin(name)
- if (_sdnplugin is None):
- raise SdnGetInterfaceError
+ for name, sdnacct in self._acctstore.items():
+ if sdnacct.account_type != "odl":
+ continue
+ sdnintf = sdnacct.sdn
- rc, nwtop = _sdnplugin.get_network_list(_sdnacct)
+ rc, nwtop = sdnintf.get_network_list(sdnacct.sdnal_account_msg)
#assert rc == RwStatus.SUCCESS
if rc != RwStatus.SUCCESS:
self._log.error("Fetching get network list for SDN Account %s failed", name)
""" Handles DTS interactions for the Static Topology registration """
STATIC_XPATH = "C,/nd:network"
- def __init__(self, dts, log, loop, acctmgr, nwdatastore):
+ def __init__(self, dts, log, loop, acctstore, nwdatastore):
self._dts = dts
self._log = log
self._loop = loop
- self._acctmgr = acctmgr
+ self._acctstore = acctstore
self._regh = None
self.pending = {}
import rw_peas
import rwlogger
-from gi.repository import RwsdnYang
+from gi.repository import RwsdnalYang
import gi
gi.require_version('RwTypes', '1.0')
-gi.require_version('RwSdn', '1.0')
+gi.require_version('RwSdnal', '1.0')
from gi.repository import RwcalYang
from gi.repository import IetfNetworkYang
from gi.repository.RwTypes import RwStatus
def get_sdn_account():
"""
- Creates an object for class RwsdnYang.SdnAccount()
+ Creates an object for class RwsdnalYang.SdnAccount()
"""
- account = RwsdnYang.SDNAccount()
+ account = RwsdnalYang.SDNAccount()
account.account_type = "mock"
account.mock.username = "rift"
account.mock.plugin_name = "rwsdn_mock"
--- /dev/null
+
+#
+# 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 logging
+import unittest
+
+import rw_peas
+import rwlogger
+
+import gi
+gi.require_version('RwTypes', '1.0')
+from gi.repository import RwsdnalYang
+from gi.repository.RwTypes import RwStatus
+
+
+logger = logging.getLogger('sdnodl')
+
+odl_info = {
+ 'username' : 'admin',
+ 'password' : 'admin',
+ 'url' : 'http://10.66.4.27:8181',
+}
+
+
+def get_sdn_account():
+ """
+ Creates an object for class RwsdnalYang.SdnAccount()
+ """
+ account = RwsdnalYang.SDNAccount()
+ account.name = "grunt27"
+ account.account_type = "odl"
+ account.odl.plugin_name = "rwsdn_odl"
+ account.odl.username = odl_info['username']
+ account.odl.password = odl_info['password']
+ account.odl.url = odl_info['url']
+
+ return account
+
+def get_sdn_plugin():
+ """
+ Loads rw.sdn plugin via libpeas
+ """
+ plugin = rw_peas.PeasPlugin('rwsdn_odl', 'RwSdn-1.0')
+ engine, info, extension = plugin()
+
+ # Get the RwLogger context
+ rwloggerctx = rwlogger.RwLog.Ctx.new("SDN-Log")
+
+ sdn = plugin.get_interface("Topology")
+ try:
+ rc = sdn.init(rwloggerctx)
+ assert rc == RwStatus.SUCCESS
+ except:
+ logger.error("ERROR:SDN ODL plugin instantiation failed. Aborting tests")
+ else:
+ logger.info("SDN ODL plugin successfully instantiated")
+ return sdn
+
+
+
+class SdnOdlTest(unittest.TestCase):
+ def setUp(self):
+ """
+ Initialize test plugins
+ """
+ self._acct = get_sdn_account()
+ logger.info("SDN-Odl-Test: setUp")
+ self.sdn = get_sdn_plugin()
+ logger.info("SDN-Odl-Test: setUpEND")
+
+ def tearDown(self):
+ logger.info("SDN-Odl-Test: Done with tests")
+
+ def test_validate_sdn_creds(self):
+ """
+ First test case
+ """
+ logger.debug("SDN-Odl-Test: Starting validate creds ")
+ rc, status = self.sdn.validate_sdn_creds(self._acct)
+ logger.debug("SDN-Odl-Test: SDN return code %s resp %s", rc, status)
+ self.assertEqual(rc, RwStatus.SUCCESS)
+ logger.info("SDN-Odl-Test: Passed validate creds")
+
+ def test_get_network_list(self):
+ """
+ Get-network-list test case
+ """
+ logger.debug("SDN-Odl-Test: Getting network list ")
+ rc, status = self.sdn.get_network_list(self._acct)
+ logger.debug("SDN-Odl-Test: SDN return code %s resp %s", rc, status)
+ self.assertEqual(rc, RwStatus.SUCCESS)
+ logger.info("SDN-Odl-Test: Passed get network list")
+
+
+
+if __name__ == "__main__":
+ logging.basicConfig(level=logging.DEBUG)
+ unittest.main()
+
+
+
+
--- /dev/null
+
+#
+# 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 logging
+import unittest
+
+import rw_peas
+import rwlogger
+
+import gi
+gi.require_version('RwTypes', '1.0')
+from gi.repository import RwsdnalYang
+from gi.repository.RwTypes import RwStatus
+
+
+logger = logging.getLogger('sdnopenstack')
+
+openstack_info = {
+ 'username' : 'pluto',
+ 'password' : 'mypasswd',
+ 'auth_url' : 'http://10.66.4.17:5000/v2.0/',
+ 'project_name' : 'demo',
+ 'user_domain_name' : 'default',
+ 'project_domain_name': 'default'
+}
+
+
+def get_sdn_account():
+ """
+ Creates an object for class RwsdnalYang.SdnAccount()
+ """
+ account = RwsdnalYang.SDNAccount()
+ account.name = "grunt17"
+ account.account_type = "openstack"
+ account.openstack.plugin_name = "rwsdn_openstack"
+ account.openstack.key = openstack_info['username']
+ account.openstack.secret = openstack_info['password']
+ account.openstack.auth_url = openstack_info['auth_url']
+ account.openstack.tenant = openstack_info['project_name']
+ account.openstack.user_domain = openstack_info['user_domain_name']
+ account.openstack.project_domain = openstack_info['project_domain_name']
+
+ return account
+
+def get_sdn_plugin():
+ """
+ Loads rw.sdn plugin via libpeas
+ """
+ plugin = rw_peas.PeasPlugin('rwsdn_openstack', 'RwSdn-1.0')
+ engine, info, extension = plugin()
+
+ # Get the RwLogger context
+ rwloggerctx = rwlogger.RwLog.Ctx.new("SDN-Log")
+
+ sdn = plugin.get_interface("Topology")
+ try:
+ rc = sdn.init(rwloggerctx)
+ assert rc == RwStatus.SUCCESS
+ except:
+ logger.error("ERROR:SDN openstack plugin instantiation failed. Aborting tests")
+ else:
+ logger.info("SDN openstack plugin successfully instantiated")
+ return sdn
+
+
+
+class SdnOpenstackTest(unittest.TestCase):
+ def setUp(self):
+ """
+ Initialize test plugins
+ """
+ self._acct = get_sdn_account()
+ logger.info("SDN-Openstack-Test: setUp")
+ self.sdn = get_sdn_plugin()
+ logger.info("SDN-Openstack-Test: setUpEND")
+
+ def tearDown(self):
+ logger.info("SDN-Openstack-Test: Done with tests")
+
+ def test_validate_sdn_creds(self):
+ """
+ First test case
+ """
+ logger.debug("SDN-Openstack-Test: Starting validate creds ")
+ rc, status = self.sdn.validate_sdn_creds(self._acct)
+ logger.debug("SDN-Openstack-Test: SDN return code %s resp %s", rc, status)
+ self.assertEqual(rc, RwStatus.SUCCESS)
+ logger.info("SDN-Openstack-Test: Passed validate creds")
+
+
+if __name__ == "__main__":
+ logging.basicConfig(level=logging.DEBUG)
+ unittest.main()
+
+
+
+
# limitations under the License.
#
-import datetime
import logging
import unittest
import gi
gi.require_version('RwTypes', '1.0')
-gi.require_version('RwSdn', '1.0')
-from gi.repository import RwsdnYang
-from gi.repository import IetfNetworkYang
+from gi.repository import RwsdnalYang
from gi.repository.RwTypes import RwStatus
-from gi.repository import RwSdn
logger = logging.getLogger('sdnsim')
def get_sdn_account():
"""
- Creates an object for class RwsdnYang.SdnAccount()
+ Creates an object for class RwsdnalYang.SdnAccount()
"""
- account = RwsdnYang.SDNAccount()
+ account = RwsdnalYang.SDNAccount()
account.account_type = "sdnsim"
account.sdnsim.username = "rift"
account.sdnsim.plugin_name = "rwsdn_sim"
import gi.repository.IetfL2TopologyYang as l2Tl
import gi.repository.RwTopologyYang as RwTl
import gi.repository.RwLaunchpadYang as launchpadyang
-from gi.repository import RwsdnYang
+from gi.repository import RwsdnalYang
from gi.repository.RwTypes import RwStatus
from create_stackedl2topology import MyL2Topology
VALA_FILES ${VALA_FILES}
VALA_PACKAGES
rw_types-1.0 rw_yang-1.0 rw_keyspec-1.0 rw_yang_pb-1.0 rw_schema_proto-1.0
- rw_log_yang-1.0 rw_base_yang-1.0 rwcal_yang-1.0 rwsdn_yang-1.0 rw_manifest_yang-1.0 protobuf_c-1.0 ietf_netconf_yang-1.0
+ rw_log_yang-1.0 rw_base_yang-1.0 rwcal_yang-1.0 rwsdnal_yang-1.0 rw_manifest_yang-1.0 protobuf_c-1.0 ietf_netconf_yang-1.0
ietf_network_yang-1.0 ietf_network_topology_yang-1.0
ietf_l2_topology_yang-1.0 rw_topology_yang-1.0
rw_log-1.0
GENERATE_VAPI_FILE ${VALA_LONG_NAME}.vapi
GENERATE_GIR_FILE ${VALA_TYPELIB_PREFIX}.gir
GENERATE_TYPELIB_FILE ${VALA_TYPELIB_PREFIX}.typelib
- DEPENDS rwcal_yang rwsdn_yang mano_yang rwlog_gi rwschema_yang
+ DEPENDS rwcal_yang rwsdnal_yang mano_yang rwlog_gi rwschema_yang
)
rift_install_vala_artifacts(
* Credential Validation related APIs
*/
public abstract RwTypes.RwStatus validate_sdn_creds(
- Rwsdn.SDNAccount account,
- out Rwsdn.SdnConnectionStatus status);
+ Rwsdnal.SDNAccount account,
+ out Rwsdnal.SdnConnectionStatus status);
/*
* Configuring related APIs
* Network related APIs
*/
public abstract RwTypes.RwStatus get_network_list(
- Rwsdn.SDNAccount account,
+ Rwsdnal.SDNAccount account,
out RwTopology.YangData_IetfNetwork network_topology);
/*
* VNFFG Chain related APIs
*/
public abstract RwTypes.RwStatus create_vnffg_chain(
- Rwsdn.SDNAccount account,
- Rwsdn.VNFFGChain vnffg_chain,
+ Rwsdnal.SDNAccount account,
+ Rwsdnal.VNFFGChain vnffg_chain,
out string vnffg_id);
/*
* VNFFG Chain Terminate related APIs
*/
public abstract RwTypes.RwStatus terminate_vnffg_chain(
- Rwsdn.SDNAccount account,
+ Rwsdnal.SDNAccount account,
string vnffg_id);
* Network related APIs
*/
public abstract RwTypes.RwStatus get_vnffg_rendered_paths(
- Rwsdn.SDNAccount account,
- out Rwsdn.VNFFGRenderedPaths rendered_paths);
+ Rwsdnal.SDNAccount account,
+ out Rwsdnal.VNFFGRenderedPaths rendered_paths);
/*
* Classifier related APIs
*/
public abstract RwTypes.RwStatus create_vnffg_classifier(
- Rwsdn.SDNAccount account,
- Rwsdn.VNFFGClassifier vnffg_classifier,
+ Rwsdnal.SDNAccount account,
+ Rwsdnal.VNFFGClassifier vnffg_classifier,
out string vnffg_classifier_id);
/*
* Classifier related APIs
*/
public abstract RwTypes.RwStatus terminate_vnffg_classifier(
- Rwsdn.SDNAccount account,
+ Rwsdnal.SDNAccount account,
string vnffg_classifier_id);
RwSdn, # Vala package
RwTypes,
RwTopologyYang as RwTl,
- RwsdnYang
+ RwsdnalYang
)
import rw_status
)
)
- account = RwsdnYang.SDNAccount()
+ account = RwsdnalYang.SDNAccount()
account.name = 'mock'
account.account_type = 'mock'
account.mock.username = 'rift'
import gi
gi.require_version('RwTypes', '1.0')
-gi.require_version('RwsdnYang', '1.0')
+gi.require_version('RwsdnalYang', '1.0')
gi.require_version('RwSdn', '1.0')
gi.require_version('RwTopologyYang','1.0')
GObject,
RwSdn, # Vala package
RwTypes,
- RwsdnYang,
+ RwsdnalYang,
RwTopologyYang as RwTl,
)
"""
Validate the SDN account credentials by accessing the rest API using the provided credentials
"""
- status = RwsdnYang.SdnConnectionStatus()
+ status = RwsdnalYang.SdnConnectionStatus()
url = '{}/{}'.format(account.odl.url,"restconf")
try:
r=requests.get(url,auth=(account.odl.username,account.odl.password))
status.status = "failure"
status.details = "Connection Failed (Invlaid URL): %s" % str(e)
else:
- print("SDN Successfully connected")
status.status = "success"
status.details = "Connection was successful"
self.delete_all_sf(account)
def _fill_rsp_list(self,sfc_rsp_list,sff_list):
- vnffg_rsps = RwsdnYang.VNFFGRenderedPaths()
+ vnffg_rsps = RwsdnalYang.VNFFGRenderedPaths()
for sfc_rsp in sfc_rsp_list['rendered-service-paths']['rendered-service-path']:
rsp = vnffg_rsps.vnffg_rendered_path.add()
rsp.name = sfc_rsp['name']
GObject,
RwCal,
RwSdn, # Vala package
- RwsdnYang,
+ RwsdnalYang,
RwTypes,
RwcalYang)
Returns:
Validation Code and Details String
"""
- status = RwsdnYang.SdnConnectionStatus()
+ status = RwsdnalYang.SdnConnectionStatus()
drv = self._use_driver(account)
try:
drv.validate_account_creds()
@param account - a SDN account
"""
self.log.debug('Received get VNFFG rendered path for account %s ', account)
- vnffg_rsps = RwsdnYang.VNFFGRenderedPaths()
+ vnffg_rsps = RwsdnalYang.VNFFGRenderedPaths()
drv = self._use_driver(account)
port_chain_list = drv.get_port_chain_list()
for port_chain in port_chain_list:
GObject,
RwSdn, # Vala package
RwTypes,
- RwsdnYang,
+ RwsdnalYang,
#IetfL2TopologyYang as l2Tl,
RwTopologyYang as RwTl,
)
Returns:
Validation Code and Details String
"""
- status = RwsdnYang.SdnConnectionStatus()
+ status = RwsdnalYang.SdnConnectionStatus()
print("SDN Successfully connected")
status.status = "success"
status.details = "Connection was successful"
include(rift_yang)
-set(source_yang_files rwsdn.yang)
+set(source_yang_files rwsdnal.yang)
rift_add_yang_target(
- TARGET rwsdn_yang
+ TARGET rwsdnal_yang
YANG_FILES ${source_yang_files}
COMPONENT ${PKG_LONG_NAME}
LIBRARIES
+++ /dev/null
-
-/*
- *
- * 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.
- *
- *
- */
-
-module rwsdn
-{
- namespace "http://riftio.com/ns/riftware-1.0/rwsdn";
- prefix "rwsdn";
-
- import rw-base {
- prefix rwbase;
- }
-
- import rw-pb-ext {
- prefix "rwpb";
- }
-
- import rw-yang-types {
- prefix "rwt";
- }
-
- import rw-log {
- prefix "rwlog";
- }
-
- import mano-types {
- prefix "manotypes";
- }
-
- import ietf-inet-types {
- prefix "inet";
- }
-
- import ietf-yang-types {
- prefix "yang";
- }
-
-
- revision 2014-12-30 {
- description
- "Initial revision.";
- reference
- "RIFT RWSDN cloud data";
- }
-
- typedef sdn-connection-status-enum {
- description "Connection status for the sdn account";
- type enumeration {
- enum unknown;
- enum validating;
- enum success;
- enum failure;
- }
- }
-
- grouping connection-status {
- container connection-status {
- config false;
- rwpb:msg-new SdnConnectionStatus;
- leaf status {
- type sdn-connection-status-enum;
- }
- leaf details {
- type string;
- }
- }
- }
-
- uses connection-status;
-
- typedef sdn-account-type {
- description "SDN account type";
- type enumeration {
- enum odl;
- enum mock;
- enum sdnsim;
- enum openstack;
- }
- }
-
- grouping sdn-provider-auth {
- leaf account-type {
- type sdn-account-type;
- }
-
- choice provider-specific-info {
- container odl {
- leaf username {
- type string {
- length "1..255";
- }
- }
-
- leaf password {
- type string {
- length "1..32";
- }
- }
-
- leaf url {
- type string {
- length "1..255";
- }
- }
- leaf plugin-name {
- type string;
- default "rwsdn_odl";
- }
- }
- container mock {
- leaf username {
- type string;
- }
- leaf plugin-name {
- type string;
- default "rwsdn_mock";
- }
- }
-
- container sdnsim {
- leaf username {
- type string;
- }
- leaf topology-source {
- type string;
- }
- leaf plugin-name {
- type string;
- default "rwsdn_sim";
- }
- }
-
- container openstack {
- leaf key {
- type string;
- mandatory true;
- }
-
- leaf secret {
- type string;
- mandatory true;
- }
-
- leaf auth_url {
- type string;
- mandatory true;
- }
-
- leaf tenant {
- type string;
- mandatory true;
- }
-
- leaf admin {
- type boolean;
- default false;
- }
-
- leaf user-domain {
- type string;
- default "Default";
- description "Domain of the OpenStack user";
- }
-
- leaf project-domain {
- type string;
- default "Default";
- description "Domain of the OpenStack project";
- }
-
- leaf region {
- type string;
- default "RegionOne";
- }
-
- leaf plugin-name {
- type string;
- default "rwsdn_openstack";
- }
-
- leaf cert-validate {
- type boolean;
- default false;
- description "Certificate validatation policy in case of SSL/TLS connection";
- }
- }
-
- }
- }
-
- container sdn-accounts {
- list sdn-account-list {
- rwpb:msg-new SDNAccount;
- key "name";
-
- leaf name {
- type string;
- }
-
- uses sdn-provider-auth;
- uses connection-status;
- }
- }
-
- container vnffgs {
- list vnffg-chain {
- key "name";
- rwpb:msg-new VNFFGChain;
-
- leaf name {
- type string;
- }
-
- list vnf-chain-path {
- key "order";
- leaf order {
- type uint32;
- description " Order of the VNF in VNFFG chain";
- }
- leaf service-function-type {
- type string;
- }
- leaf nsh-aware {
- type boolean;
- }
- leaf transport-type {
- type string;
- }
- list vnfr-ids {
- key "vnfr-id";
- leaf vnfr-id {
- type yang:uuid;
- }
- leaf vnfr-name {
- type string;
- }
- leaf mgmt-address {
- type inet:ip-address;
- }
- leaf mgmt-port {
- type inet:port-number;
- }
- list vdu-list {
- key "vm-id port-id";
- leaf port-id {
- rwpb:field-inline "true";
- rwpb:field-string-max 64;
- type string;
- }
- leaf vm-id {
- rwpb:field-inline "true";
- rwpb:field-string-max 64;
- type string;
- }
- leaf name {
- type string;
- }
- leaf address {
- type inet:ip-address;
- }
- leaf port {
- type inet:port-number;
- }
- }
- leaf sff-name {
- description "SFF name useful for non OVS based SFF";
- type string;
- }
- }
- }
- list sff {
- rwpb:msg-new VNFFGSff;
- key "name";
- leaf name {
- type string;
- }
- leaf function-type {
- type string;
- }
- leaf mgmt-address {
- type inet:ip-address;
- }
- leaf mgmt-port {
- type inet:port-number;
- }
- list dp-endpoints {
- key "name";
- leaf name {
- type string;
- }
- leaf address {
- type inet:ip-address;
- }
- leaf port {
- type inet:port-number;
- }
- }
- list vnfr-list {
- key "vnfr-name";
- leaf vnfr-name {
- type string;
- }
- }
- }
- leaf classifier-name {
- type string;
- }
- }
- }
-
- container vnffg-rendered-paths {
- rwpb:msg-new VNFFGRenderedPaths;
- list vnffg-rendered-path {
- key "name";
- rwpb:msg-new VNFFGRenderedPath;
- config false;
- leaf name {
- type string;
- }
- leaf path-id {
- description
- "Unique Identifier for the service path";
- type uint32;
- }
- list rendered-path-hop {
- key "hop-number";
- leaf hop-number {
- type uint8;
- }
- leaf service-index {
- description
- "Location within the service path";
- type uint8;
- }
- leaf vnfr-name {
- type string;
- }
- container service-function-forwarder {
- leaf name {
- description
- "Service Function Forwarder name";
- type string;
- }
- leaf ip-address {
- description
- "Service Function Forwarder Data Plane IP address";
- type inet:ip-address;
- }
- leaf port {
- description
- "Service Function Forwarder Data Plane port";
- type inet:port-number;
- }
- }
- }
- }
- }
-
-
- container vnffg-classifiers {
- list vnffg-classifier {
- key "name";
- rwpb:msg-new VNFFGClassifier;
-
- leaf name {
- type string;
- }
- leaf rsp-name {
- type string;
- }
- leaf rsp-id {
- type yang:uuid;
- }
- leaf port-id {
- rwpb:field-inline "true";
- rwpb:field-string-max 64;
- type string;
- }
- leaf vm-id {
- rwpb:field-inline "true";
- rwpb:field-string-max 64;
- type string;
- }
- leaf sff-name {
- type string;
- }
- container vnffg-metadata {
- leaf ctx1 {
- type string;
- }
- leaf ctx2 {
- type string;
- }
- leaf ctx3 {
- type string;
- }
- leaf ctx4 {
- type string;
- }
- }
- list match-attributes {
- description
- "List of match attributes.";
- key "name";
- leaf name {
- description
- "Name for the Access list";
- type string;
- }
-
- leaf ip-proto {
- description
- "IP Protocol.";
- type uint8;
- }
-
- leaf source-ip-address {
- description
- "Source IP address.";
- type inet:ip-prefix;
- }
-
- leaf destination-ip-address {
- description
- "Destination IP address.";
- type inet:ip-prefix;
- }
-
- leaf source-port {
- description
- "Source port number.";
- type inet:port-number;
- }
-
- leaf destination-port {
- description
- "Destination port number.";
- type inet:port-number;
- }
- } //match-attributes
- }
- }
-
-}
-
-/* vim: set ts=2:sw=2: */
--- /dev/null
+
+/*
+ *
+ * Copyright 2016-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.
+ *
+ *
+ */
+
+module rwsdnal
+{
+ namespace "http://riftio.com/ns/riftware-1.0/rwsdnal";
+ prefix "rwsdnal";
+
+ import rw-base {
+ prefix rwbase;
+ }
+
+ import rw-pb-ext {
+ prefix "rwpb";
+ }
+
+ import rw-yang-types {
+ prefix "rwt";
+ }
+
+ import rw-log {
+ prefix "rwlog";
+ }
+
+ import mano-types {
+ prefix "manotypes";
+ }
+
+ import ietf-inet-types {
+ prefix "inet";
+ }
+
+ import ietf-yang-types {
+ prefix "yang";
+ }
+
+
+ revision 2014-12-30 {
+ description
+ "Initial revision.";
+ reference
+ "RIFT RWSDN cloud data";
+ }
+
+ typedef sdn-connection-status-enum {
+ description "Connection status for the sdn account";
+ type enumeration {
+ enum unknown;
+ enum validating;
+ enum success;
+ enum failure;
+ }
+ }
+
+ grouping connection-status {
+ container connection-status {
+ config false;
+ rwpb:msg-new SdnConnectionStatus;
+ leaf status {
+ type sdn-connection-status-enum;
+ }
+ leaf details {
+ type string;
+ }
+ }
+ }
+
+ uses connection-status;
+
+ typedef sdn-account-type {
+ description "SDN account type";
+ type enumeration {
+ enum odl;
+ enum mock;
+ enum sdnsim;
+ enum openstack;
+ }
+ }
+
+ grouping sdn-provider-auth {
+ leaf account-type {
+ type sdn-account-type;
+ }
+
+ choice provider-specific-info {
+ container odl {
+ leaf username {
+ type string {
+ length "1..255";
+ }
+ }
+
+ leaf password {
+ type string {
+ length "1..32";
+ }
+ }
+
+ leaf url {
+ type string {
+ length "1..255";
+ }
+ }
+ leaf plugin-name {
+ type string;
+ default "rwsdn_odl";
+ }
+ }
+ container mock {
+ leaf username {
+ type string;
+ }
+ leaf plugin-name {
+ type string;
+ default "rwsdn_mock";
+ }
+ }
+
+ container sdnsim {
+ leaf username {
+ type string;
+ }
+ leaf topology-source {
+ type string;
+ }
+ leaf plugin-name {
+ type string;
+ default "rwsdn_sim";
+ }
+ }
+
+ container openstack {
+ leaf key {
+ type string;
+ mandatory true;
+ }
+
+ leaf secret {
+ type string;
+ mandatory true;
+ }
+
+ leaf auth_url {
+ type string;
+ mandatory true;
+ }
+
+ leaf tenant {
+ type string;
+ mandatory true;
+ }
+
+ leaf admin {
+ type boolean;
+ default false;
+ }
+
+ leaf user-domain {
+ type string;
+ default "Default";
+ description "Domain of the OpenStack user";
+ }
+
+ leaf project-domain {
+ type string;
+ default "Default";
+ description "Domain of the OpenStack project";
+ }
+
+ leaf region {
+ type string;
+ default "RegionOne";
+ }
+
+ leaf plugin-name {
+ type string;
+ default "rwsdn_openstack";
+ }
+
+ leaf cert-validate {
+ type boolean;
+ default false;
+ description "Certificate validatation policy in case of SSL/TLS connection";
+ }
+ }
+
+ }
+ }
+
+ container sdn-accounts {
+ list sdn-account-list {
+ rwpb:msg-new SDNAccount;
+ key "name";
+
+ leaf name {
+ type string;
+ }
+
+ uses sdn-provider-auth;
+ uses connection-status;
+ }
+ }
+
+ container vnffgs {
+ list vnffg-chain {
+ key "name";
+ rwpb:msg-new VNFFGChain;
+
+ leaf name {
+ type string;
+ }
+
+ list vnf-chain-path {
+ key "order";
+ leaf order {
+ type uint32;
+ description " Order of the VNF in VNFFG chain";
+ }
+ leaf service-function-type {
+ type string;
+ }
+ leaf nsh-aware {
+ type boolean;
+ }
+ leaf transport-type {
+ type string;
+ }
+ list vnfr-ids {
+ key "vnfr-id";
+ leaf vnfr-id {
+ type yang:uuid;
+ }
+ leaf vnfr-name {
+ type string;
+ }
+ leaf mgmt-address {
+ type inet:ip-address;
+ }
+ leaf mgmt-port {
+ type inet:port-number;
+ }
+ list vdu-list {
+ key "vm-id port-id";
+ leaf port-id {
+ rwpb:field-inline "true";
+ rwpb:field-string-max 64;
+ type string;
+ }
+ leaf vm-id {
+ rwpb:field-inline "true";
+ rwpb:field-string-max 64;
+ type string;
+ }
+ leaf name {
+ type string;
+ }
+ leaf address {
+ type inet:ip-address;
+ }
+ leaf port {
+ type inet:port-number;
+ }
+ }
+ leaf sff-name {
+ description "SFF name useful for non OVS based SFF";
+ type string;
+ }
+ }
+ }
+ list sff {
+ rwpb:msg-new VNFFGSff;
+ key "name";
+ leaf name {
+ type string;
+ }
+ leaf function-type {
+ type string;
+ }
+ leaf mgmt-address {
+ type inet:ip-address;
+ }
+ leaf mgmt-port {
+ type inet:port-number;
+ }
+ list dp-endpoints {
+ key "name";
+ leaf name {
+ type string;
+ }
+ leaf address {
+ type inet:ip-address;
+ }
+ leaf port {
+ type inet:port-number;
+ }
+ }
+ list vnfr-list {
+ key "vnfr-name";
+ leaf vnfr-name {
+ type string;
+ }
+ }
+ }
+ leaf classifier-name {
+ type string;
+ }
+ }
+ }
+
+ container vnffg-rendered-paths {
+ rwpb:msg-new VNFFGRenderedPaths;
+ list vnffg-rendered-path {
+ key "name";
+ rwpb:msg-new VNFFGRenderedPath;
+ config false;
+ leaf name {
+ type string;
+ }
+ leaf path-id {
+ description
+ "Unique Identifier for the service path";
+ type uint32;
+ }
+ list rendered-path-hop {
+ key "hop-number";
+ leaf hop-number {
+ type uint8;
+ }
+ leaf service-index {
+ description
+ "Location within the service path";
+ type uint8;
+ }
+ leaf vnfr-name {
+ type string;
+ }
+ container service-function-forwarder {
+ leaf name {
+ description
+ "Service Function Forwarder name";
+ type string;
+ }
+ leaf ip-address {
+ description
+ "Service Function Forwarder Data Plane IP address";
+ type inet:ip-address;
+ }
+ leaf port {
+ description
+ "Service Function Forwarder Data Plane port";
+ type inet:port-number;
+ }
+ }
+ }
+ }
+ }
+
+
+ container vnffg-classifiers {
+ list vnffg-classifier {
+ key "name";
+ rwpb:msg-new VNFFGClassifier;
+
+ leaf name {
+ type string;
+ }
+ leaf rsp-name {
+ type string;
+ }
+ leaf rsp-id {
+ type yang:uuid;
+ }
+ leaf port-id {
+ rwpb:field-inline "true";
+ rwpb:field-string-max 64;
+ type string;
+ }
+ leaf vm-id {
+ rwpb:field-inline "true";
+ rwpb:field-string-max 64;
+ type string;
+ }
+ leaf sff-name {
+ type string;
+ }
+ container vnffg-metadata {
+ leaf ctx1 {
+ type string;
+ }
+ leaf ctx2 {
+ type string;
+ }
+ leaf ctx3 {
+ type string;
+ }
+ leaf ctx4 {
+ type string;
+ }
+ }
+ list match-attributes {
+ description
+ "List of match attributes.";
+ key "name";
+ leaf name {
+ description
+ "Name for the Access list";
+ type string;
+ }
+
+ leaf ip-proto {
+ description
+ "IP Protocol.";
+ type uint8;
+ }
+
+ leaf source-ip-address {
+ description
+ "Source IP address.";
+ type inet:ip-prefix;
+ }
+
+ leaf destination-ip-address {
+ description
+ "Destination IP address.";
+ type inet:ip-prefix;
+ }
+
+ leaf source-port {
+ description
+ "Source port number.";
+ type inet:port-number;
+ }
+
+ leaf destination-port {
+ description
+ "Destination port number.";
+ type inet:port-number;
+ }
+ } //match-attributes
+ }
+ }
+
+}
+
+/* vim: set ts=2:sw=2: */
prefix "rwcal";
}
- import rwsdn {
- prefix "rwsdn";
+ import rwsdnal {
+ prefix "rwsdnal";
}
import pytest
import gi
-gi.require_version('RwsdnYang', '1.0')
+gi.require_version('RwsdnalYang', '1.0')
-from gi.repository import RwsdnYang
+from gi.repository import RwsdnalYang
@pytest.mark.setup('sdn')
@pytest.mark.feature('sdn')
Asserts:
SDN name and accout type.
'''
- proxy = mgmt_session.proxy(RwsdnYang)
- sdn_account = RwsdnYang.SDNAccount(
+ proxy = mgmt_session.proxy(RwsdnalYang)
+ sdn_account = RwsdnalYang.SDNAccount(
name=sdn_account_name,
account_type=sdn_account_type)
xpath = "/sdn-accounts/sdn-account-list[name='%s']" % sdn_account_name
Asserts:
sdn_account.account_type is what was configured
'''
- proxy = mgmt_session.proxy(RwsdnYang)
+ proxy = mgmt_session.proxy(RwsdnalYang)
xpath = "/sdn-accounts/sdn-account-list[name='%s']" % sdn_account_name
sdn_account = proxy.get_config(xpath)
assert sdn_account.account_type == sdn_account_type
class TestSdnTeardown:
def test_delete_odl_sdn_account(self, mgmt_session, sdn_account_name):
'''Unconfigure sdn account'''
- proxy = mgmt_session.proxy(RwsdnYang)
+ proxy = mgmt_session.proxy(RwsdnalYang)
xpath = "/sdn-accounts/sdn-account-list[name='%s']" % sdn_account_name
proxy.delete_config(xpath)