From: Sumit Naiksatam Date: Sun, 7 Aug 2011 11:58:50 +0000 (-0700) Subject: Changes to enhance L2 network plugin framework. X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=e3b8bafbb9f3b70e7086ef69adf4f78dc2faa4d3;p=openstack-build%2Fneutron-build.git Changes to enhance L2 network plugin framework. --- diff --git a/quantum/plugins/cisco/README b/quantum/plugins/cisco/README index 36ea4ea27..ee0321959 100644 --- a/quantum/plugins/cisco/README +++ b/quantum/plugins/cisco/README @@ -1,6 +1,8 @@ L2 Network Plugin ================== +*** Reference implementation of plugin framework for L2 network *** +*** Multi-switch (devices and types) capability *** *** Current support for UCS (blade servers) with M81KR VIC (Palo) for 802.1Qbh *** *** Also supports Nexus 7k *** @@ -10,6 +12,7 @@ * RHEL 6.1 * UCS & VIC installation (support for KVM) - please consult the accompanying installation guide available at: http://wikicentral.cisco.com/display/GROUP/SAVBU+Palo+VM-FEX+for+Linux+KVM +* Package python-configobj-4.6.0-3.el6.noarch * If you have a Nexus switch in your topology and decide to turn on Nexus support, you will need: - ncclcient v0.3.1 - Python library for NETCONF clients (http://schmizz.net/ncclient/). diff --git a/quantum/plugins/cisco/common/cisco_constants.py b/quantum/plugins/cisco/common/cisco_constants.py index b14ce0934..71ae304d1 100644 --- a/quantum/plugins/cisco/common/cisco_constants.py +++ b/quantum/plugins/cisco/common/cisco_constants.py @@ -96,3 +96,8 @@ RHEL_DEVICE_NAME_REPFIX = "eth" UCS_PLUGIN = 'ucs_plugin' NEXUS_PLUGIN = 'nexus_plugin' + +PLUGIN_OBJ_REF = 'plugin-obj-ref' +PARAM_LIST = 'param-list' + +DEVICE_IP = 'device-ip' diff --git a/quantum/plugins/cisco/conf/l2network_plugin.ini b/quantum/plugins/cisco/conf/l2network_plugin.ini index 5a0d7d7a9..3a740a971 100644 --- a/quantum/plugins/cisco/conf/l2network_plugin.ini +++ b/quantum/plugins/cisco/conf/l2network_plugin.ini @@ -1,6 +1,6 @@ [VLANS] -vlan_start=100 -vlan_end=3000 +vlan_start= +vlan_end= vlan_name_prefix=q- [PORTS] @@ -11,3 +11,6 @@ max_port_profiles=65568 [NETWORKS] max_networks=65568 + +[MODEL] +model_class=quantum.plugins.cisco.l2network_model.L2NetworkModel diff --git a/quantum/plugins/cisco/l2device_plugin_base.py b/quantum/plugins/cisco/l2device_plugin_base.py new file mode 100644 index 000000000..b108d0242 --- /dev/null +++ b/quantum/plugins/cisco/l2device_plugin_base.py @@ -0,0 +1,152 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2011 Cisco Systems, Inc. All rights reserved. +# +# 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. +# +# @author: Sumit Naiksatam, Cisco Systems, Inc. +# + +import inspect +from abc import ABCMeta, abstractmethod + + +class L2DevicePluginBase(object): + + __metaclass__ = ABCMeta + + @abstractmethod + def get_all_networks(self, tenant_id, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id, + **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def delete_network(self, tenant_id, net_id, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def get_network_details(self, tenant_id, net_id, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def rename_network(self, tenant_id, net_id, new_name, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def get_all_ports(self, tenant_id, net_id, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def create_port(self, tenant_id, net_id, port_state, port_id, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def delete_port(self, tenant_id, net_id, port_id, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def get_port_details(self, tenant_id, net_id, port_id, **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id, + **kwargs): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def unplug_interface(self, tenant_id, net_id, port_id, **kwargs): + """ + :returns: + :raises: + """ + pass + + @classmethod + def __subclasshook__(cls, klass): + """ + The __subclasshook__ method is a class method + that will be called everytime a class is tested + using issubclass(klass, Plugin). + In that case, it will check that every method + marked with the abstractmethod decorator is + provided by the plugin class. + """ + if cls is QuantumPluginBase: + for method in cls.__abstractmethods__: + method_ok = False + for base in klass.__mro__: + if method in base.__dict__: + fn_obj = base.__dict__[method] + if inspect.isfunction(fn_obj): + abstract_fn_obj = cls.__dict__[method] + arg_count = fn_obj.func_code.co_argcount + expected_arg_count = \ + abstract_fn_obj.func_code.co_argcount + method_ok = arg_count == expected_arg_count + if method_ok: + continue + return NotImplemented + return True + return NotImplemented diff --git a/quantum/plugins/cisco/l2network_model.py b/quantum/plugins/cisco/l2network_model.py new file mode 100644 index 000000000..3fa986b2a --- /dev/null +++ b/quantum/plugins/cisco/l2network_model.py @@ -0,0 +1,105 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2011 Cisco Systems, Inc. All rights reserved. +# +# 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. +# +# @author: Sumit Naiksatam, Cisco Systems, Inc. +# + +import inspect +import logging as LOG + +from quantum.common import utils +from quantum.plugins.cisco.l2network_model_base import L2NetworkModelBase +from quantum.plugins.cisco import l2network_plugin_configuration as conf +from quantum.plugins.cisco.common import cisco_constants as const + +LOG.basicConfig(level=LOG.WARN) +LOG.getLogger(const.LOGGER_COMPONENT_NAME) + + +class L2NetworkModel(L2NetworkModelBase): + _plugins = {} + + def __init__(self): + for key in conf.plugins[const.PLUGINS].keys(): + self._plugins[key] = utils.import_object( + conf.plugins[const.PLUGINS][key]) + LOG.debug("Loaded device plugin %s\n" % \ + conf.plugins[const.PLUGINS][key]) + + def _funcName(self, offset=0): + return inspect.stack()[1 + offset][3] + + def _invokeAllDevicePlugins(self, function_name, args, kwargs): + for pluginObjRef in self._plugins.values(): + getattr(pluginObjRef, function_name)(*args, **kwargs) + + def _invokeUCSPlugin(self, function_name, args, kwargs): + getattr(self._plugins[const.UCS_PLUGIN], + function_name)(*args, **kwargs) + + def _invokeNexusPlugin(self, function_name, args, kwargs): + getattr(self._plugins[const.NEXUS_PLUGIN], + function_name)(*args, **kwargs) + + def get_all_networks(self, args): + pass + + def create_network(self, args): + deviceParams = {const.DEVICE_IP: ""} + self._invokeAllDevicePlugins(self._funcName(), args, deviceParams) + + def delete_network(self, args): + deviceParams = {const.DEVICE_IP: ""} + self._invokeAllDevicePlugins(self._funcName(), args, deviceParams) + + def get_network_details(self, args): + pass + + def rename_network(self, args): + deviceParams = {const.DEVICE_IP: ""} + self._invokeAllDevicePlugins(self._funcName(), args, deviceParams) + + def get_all_ports(self, args): + pass + + def create_port(self, args): + deviceParams = {const.DEVICE_IP: ""} + self._invokeUCSPlugin(self._funcName(), args, deviceParams) + + def delete_port(self, args): + deviceParams = {const.DEVICE_IP: ""} + self._invokeUCSPlugin(self._funcName(), args, deviceParams) + + def update_port(self, args): + pass + + def get_port_details(self, args): + pass + + def plug_interface(self, args): + deviceParams = {const.DEVICE_IP: ""} + self._invokeUCSPlugin(self._funcName(), args, deviceParams) + + def unplug_interface(self, args): + deviceParams = {const.DEVICE_IP: ""} + self._invokeUCSPlugin(self._funcName(), args, deviceParams) + + +def main(): + client = L2NetworkModel() + +if __name__ == '__main__': + main() diff --git a/quantum/plugins/cisco/l2network_model_base.py b/quantum/plugins/cisco/l2network_model_base.py new file mode 100644 index 000000000..f23fce4cf --- /dev/null +++ b/quantum/plugins/cisco/l2network_model_base.py @@ -0,0 +1,150 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2011 Cisco Systems, Inc. All rights reserved. +# +# 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. +# +# @author: Sumit Naiksatam, Cisco Systems, Inc. +# + +import inspect +from abc import ABCMeta, abstractmethod + + +class L2NetworkModelBase(object): + + __metaclass__ = ABCMeta + + @abstractmethod + def get_all_networks(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def create_network(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def delete_network(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def get_network_details(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def rename_network(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def get_all_ports(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def create_port(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def delete_port(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def update_port(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def get_port_details(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def plug_interface(self, args): + """ + :returns: + :raises: + """ + pass + + @abstractmethod + def unplug_interface(self, args): + """ + :returns: + :raises: + """ + pass + + @classmethod + def __subclasshook__(cls, klass): + """ + The __subclasshook__ method is a class method + that will be called everytime a class is tested + using issubclass(klass, Plugin). + In that case, it will check that every method + marked with the abstractmethod decorator is + provided by the plugin class. + """ + if cls is QuantumPluginBase: + for method in cls.__abstractmethods__: + method_ok = False + for base in klass.__mro__: + if method in base.__dict__: + fn_obj = base.__dict__[method] + if inspect.isfunction(fn_obj): + abstract_fn_obj = cls.__dict__[method] + arg_count = fn_obj.func_code.co_argcount + expected_arg_count = \ + abstract_fn_obj.func_code.co_argcount + method_ok = arg_count == expected_arg_count + if method_ok: + continue + return NotImplemented + return True + return NotImplemented diff --git a/quantum/plugins/cisco/l2network_plugin.py b/quantum/plugins/cisco/l2network_plugin.py index 7149bc5f1..f627de254 100644 --- a/quantum/plugins/cisco/l2network_plugin.py +++ b/quantum/plugins/cisco/l2network_plugin.py @@ -17,6 +17,7 @@ # @author: Sumit Naiksatam, Cisco Systems, Inc. # +import inspect import logging as LOG from quantum.common import exceptions as exc @@ -24,9 +25,7 @@ from quantum.common import utils from quantum.quantum_plugin_base import QuantumPluginBase from quantum.plugins.cisco import l2network_plugin_configuration as conf from quantum.plugins.cisco.common import cisco_constants as const -from quantum.plugins.cisco.common import cisco_credentials as cred from quantum.plugins.cisco.common import cisco_exceptions as cexc -from quantum.plugins.cisco.common import cisco_utils as cutil LOG.basicConfig(level=LOG.WARN) LOG.getLogger(const.LOGGER_COMPONENT_NAME) @@ -36,18 +35,13 @@ class L2Network(QuantumPluginBase): _networks = {} _tenants = {} _portprofiles = {} - _plugins = {} def __init__(self): self._net_counter = 0 self._portprofile_counter = 0 self._port_counter = 0 self._vlan_counter = int(conf.VLAN_START) - 1 - for key in conf.plugins[const.PLUGINS].keys(): - self._plugins[key] = utils.import_object( - conf.plugins[const.PLUGINS][key]) - LOG.debug("Loaded device plugin %s\n" % \ - conf.plugins[const.PLUGINS][key]) + self._model = utils.import_object(conf.MODEL_CLASS) """ Core API implementation @@ -59,6 +53,7 @@ class L2Network(QuantumPluginBase): the specified tenant. """ LOG.debug("get_all_networks() called\n") + self._invokeDevicePlugins(self._funcName(), [tenant_id]) return self._networks.values() def create_network(self, tenant_id, net_name): @@ -70,9 +65,9 @@ class L2Network(QuantumPluginBase): new_net_id = self._get_unique_net_id(tenant_id) vlan_id = self._get_vlan_for_tenant(tenant_id, net_name) vlan_name = self._get_vlan_name(new_net_id, str(vlan_id)) - for pluginClass in self._plugins.values(): - pluginClass.create_network(tenant_id, net_name, - new_net_id, vlan_name, vlan_id) + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_name, + new_net_id, vlan_name, + vlan_id]) new_net_dict = {const.NET_ID: new_net_id, const.NET_NAME: net_name, const.NET_PORTS: {}, @@ -92,8 +87,6 @@ class L2Network(QuantumPluginBase): """ LOG.debug("delete_network() called\n") net = self._networks.get(net_id) - # TODO (Sumit) : Verify that no attachments are plugged into the - # network if net: if len(net[const.NET_PORTS].values()) > 0: ports_on_net = net[const.NET_PORTS].values() @@ -102,10 +95,8 @@ class L2Network(QuantumPluginBase): raise exc.NetworkInUse(net_id=net_id) for port in ports_on_net: self.delete_port(tenant_id, net_id, port[const.PORT_ID]) - # TODO (Sumit) : Before deleting the network, make sure all the - # ports associated with this network are also deleted - for pluginClass in self._plugins.values(): - pluginClass.delete_network(tenant_id, net_id) + + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id]) self._networks.pop(net_id) tenant = self._get_tenant(tenant_id) tenant_networks = tenant[const.TENANT_NETWORKS] @@ -119,6 +110,7 @@ class L2Network(QuantumPluginBase): Gets the details of a particular network """ LOG.debug("get_network_details() called\n") + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id]) network = self._get_network(tenant_id, net_id) ports_on_net = network[const.NET_PORTS].values() return {const.NET_ID: network[const.NET_ID], @@ -131,8 +123,8 @@ class L2Network(QuantumPluginBase): Virtual Network. """ LOG.debug("rename_network() called\n") - for pluginClass in self._plugins.values(): - pluginClass.rename_network(tenant_id, net_id, new_name) + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id, + new_name]) network = self._get_network(tenant_id, net_id) network[const.NET_NAME] = new_name return network @@ -143,6 +135,7 @@ class L2Network(QuantumPluginBase): specified Virtual Network. """ LOG.debug("get_all_ports() called\n") + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id]) network = self._get_network(tenant_id, net_id) ports_on_net = network[const.NET_PORTS].values() return ports_on_net @@ -155,9 +148,9 @@ class L2Network(QuantumPluginBase): net = self._get_network(tenant_id, net_id) ports = net[const.NET_PORTS] unique_port_id_string = self._get_unique_port_id(tenant_id, net_id) - self._plugins[const.UCS_PLUGIN].create_port(tenant_id, net_id, - port_state, - unique_port_id_string) + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id, + port_state, + unique_port_id_string]) new_port_dict = {const.PORT_ID: unique_port_id_string, const.PORT_STATE: const.PORT_UP, const.ATTACHMENT: None} @@ -179,8 +172,8 @@ class L2Network(QuantumPluginBase): try: #TODO (Sumit): Before deleting port profile make sure that there # is no VM using this port profile - self._plugins[const.UCS_PLUGIN].delete_port(tenant_id, net_id, - port_id) + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id, + port_id]) net = self._get_network(tenant_id, net_id) net[const.NET_PORTS].pop(port_id) except KeyError: @@ -191,6 +184,8 @@ class L2Network(QuantumPluginBase): Updates the state of a port on the specified Virtual Network. """ LOG.debug("update_port() called\n") + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id, + port_id, port_state]) port = self._get_port(tenant_id, net_id, port_id) self._validate_port_state(port_state) port[const.PORT_STATE] = port_state @@ -202,6 +197,8 @@ class L2Network(QuantumPluginBase): that is attached to this particular port. """ LOG.debug("get_port_details() called\n") + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id, + port_id]) return self._get_port(tenant_id, net_id, port_id) def plug_interface(self, tenant_id, net_id, port_id, @@ -217,9 +214,9 @@ class L2Network(QuantumPluginBase): if port[const.ATTACHMENT]: raise exc.PortInUse(net_id=net_id, port_id=port_id, att_id=port[const.ATTACHMENT]) - self._plugins[const.UCS_PLUGIN].plug_interface(tenant_id, - net_id, port_id, - remote_interface_id) + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id, + port_id, + remote_interface_id]) port[const.ATTACHMENT] = remote_interface_id def unplug_interface(self, tenant_id, net_id, port_id): @@ -229,8 +226,8 @@ class L2Network(QuantumPluginBase): """ LOG.debug("unplug_interface() called\n") port = self._get_port(tenant_id, net_id, port_id) - self._plugins[const.UCS_PLUGIN].unplug_interface(tenant_id, net_id, - port_id) + self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id, + port_id]) port[const.ATTACHMENT] = None """ @@ -290,6 +287,12 @@ class L2Network(QuantumPluginBase): """ Private functions """ + def _invokeDevicePlugins(self, function_name, args): + """ + All device-specific calls are delegate to the model + """ + getattr(self._model, function_name)(args) + def _get_vlan_for_tenant(self, tenant_id, net_name): # TODO (Sumit): # The VLAN ID for a tenant might need to be obtained from @@ -382,12 +385,18 @@ class L2Network(QuantumPluginBase): # ID will be generated by DB return id + def _funcName(self, offset=0): + return inspect.stack()[1 + offset][3] + def main(): client = L2Network() + """ client.create_portprofile("12345", "tpp1", "2") client.create_portprofile("12345", "tpp2", "3") print ("%s\n") % client.get_all_portprofiles("12345") + """ + if __name__ == '__main__': main() diff --git a/quantum/plugins/cisco/l2network_plugin_configuration.py b/quantum/plugins/cisco/l2network_plugin_configuration.py index fe619ddfc..81f221f03 100644 --- a/quantum/plugins/cisco/l2network_plugin_configuration.py +++ b/quantum/plugins/cisco/l2network_plugin_configuration.py @@ -40,6 +40,9 @@ MAX_PORT_PROFILES = section['max_port_profiles'] section = cp['NETWORKS'] MAX_NETWORKS = section['max_networks'] +section = cp['MODEL'] +MODEL_CLASS = section['model_class'] + CONF_FILE = "conf/plugins.ini" cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \ diff --git a/quantum/plugins/cisco/nexus/cisco_nexus_plugin.py b/quantum/plugins/cisco/nexus/cisco_nexus_plugin.py index 8fa6424f9..fdb4ef446 100644 --- a/quantum/plugins/cisco/nexus/cisco_nexus_plugin.py +++ b/quantum/plugins/cisco/nexus/cisco_nexus_plugin.py @@ -25,13 +25,14 @@ from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_credentials as cred from quantum.plugins.cisco.common import cisco_exceptions as cexc from quantum.plugins.cisco.common import cisco_utils as cutil +from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase from quantum.plugins.cisco.nexus import cisco_nexus_configuration as conf LOG.basicConfig(level=LOG.WARN) LOG.getLogger(const.LOGGER_COMPONENT_NAME) -class NexusPlugin(object): +class NexusPlugin(L2DevicePluginBase): _networks = {} def __init__(self): @@ -52,7 +53,8 @@ class NexusPlugin(object): LOG.debug("NexusPlugin:get_all_networks() called\n") return self._networks.values() - def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id): + def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id, + **kwargs): """ Create a VLAN in the switch, and configure the appropriate interfaces for this VLAN @@ -69,7 +71,7 @@ class NexusPlugin(object): self._networks[net_id] = new_net_dict return new_net_dict - def delete_network(self, tenant_id, net_id): + def delete_network(self, tenant_id, net_id, **kwargs): """ Deletes a VLAN in the switch, and removes the VLAN configuration from the relevant interfaces @@ -85,7 +87,7 @@ class NexusPlugin(object): # Network not found raise exc.NetworkNotFound(net_id=net_id) - def get_network_details(self, tenant_id, net_id): + def get_network_details(self, tenant_id, net_id, **kwargs): """ Returns the details of a particular network """ @@ -93,7 +95,7 @@ class NexusPlugin(object): network = self._get_network(tenant_id, net_id) return network - def rename_network(self, tenant_id, net_id, new_name): + def rename_network(self, tenant_id, net_id, new_name, **kwargs): """ Updates the symbolic name belonging to a particular Virtual Network. @@ -104,49 +106,50 @@ class NexusPlugin(object): network[const.NET_NAME] = new_name return network - def get_all_ports(self, tenant_id, net_id): + def get_all_ports(self, tenant_id, net_id, **kwargs): """ This is probably not applicable to the Nexus plugin. Delete if not required. """ LOG.debug("NexusPlugin:get_all_ports() called\n") - def create_port(self, tenant_id, net_id, port_state, port_id): + def create_port(self, tenant_id, net_id, port_state, port_id, **kwargs): """ This is probably not applicable to the Nexus plugin. Delete if not required. """ LOG.debug("NexusPlugin:create_port() called\n") - def delete_port(self, tenant_id, net_id, port_id): + def delete_port(self, tenant_id, net_id, port_id, **kwargs): """ This is probably not applicable to the Nexus plugin. Delete if not required. """ LOG.debug("NexusPlugin:delete_port() called\n") - def update_port(self, tenant_id, net_id, port_id, port_state): + def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs): """ This is probably not applicable to the Nexus plugin. Delete if not required. """ LOG.debug("NexusPlugin:update_port() called\n") - def get_port_details(self, tenant_id, net_id, port_id): + def get_port_details(self, tenant_id, net_id, port_id, **kwargs): """ This is probably not applicable to the Nexus plugin. Delete if not required. """ LOG.debug("NexusPlugin:get_port_details() called\n") - def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id): + def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id, + **kwargs): """ This is probably not applicable to the Nexus plugin. Delete if not required. """ LOG.debug("NexusPlugin:plug_interface() called\n") - def unplug_interface(self, tenant_id, net_id, port_id): + def unplug_interface(self, tenant_id, net_id, port_id, **kwargs): """ This is probably not applicable to the Nexus plugin. Delete if not required. diff --git a/quantum/plugins/cisco/ucs/cisco_ucs_plugin.py b/quantum/plugins/cisco/ucs/cisco_ucs_plugin.py index f7969cab1..ad70c74b5 100644 --- a/quantum/plugins/cisco/ucs/cisco_ucs_plugin.py +++ b/quantum/plugins/cisco/ucs/cisco_ucs_plugin.py @@ -24,14 +24,15 @@ from quantum.common import utils from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_credentials as cred from quantum.plugins.cisco.common import cisco_exceptions as cexc -from quantum.plugins.cisco.ucs import cisco_ucs_configuration as conf from quantum.plugins.cisco.common import cisco_utils as cutil +from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase +from quantum.plugins.cisco.ucs import cisco_ucs_configuration as conf LOG.basicConfig(level=LOG.WARN) LOG.getLogger(const.LOGGER_COMPONENT_NAME) -class UCSVICPlugin(object): +class UCSVICPlugin(L2DevicePluginBase): _networks = {} def __init__(self): @@ -45,7 +46,7 @@ class UCSVICPlugin(object): # TODO (Sumit) Make the counter per UCSM self._port_profile_counter = 0 - def get_all_networks(self, tenant_id): + def get_all_networks(self, tenant_id, **kwargs): """ Returns a dictionary containing all for @@ -54,7 +55,8 @@ class UCSVICPlugin(object): LOG.debug("UCSVICPlugin:get_all_networks() called\n") return self._networks.values() - def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id): + def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id, + **kwargs): """ Creates a new Virtual Network, and assigns it a symbolic name. @@ -70,7 +72,7 @@ class UCSVICPlugin(object): self._networks[net_id] = new_net_dict return new_net_dict - def delete_network(self, tenant_id, net_id): + def delete_network(self, tenant_id, net_id, **kwargs): """ Deletes the network with the specified network identifier belonging to the specified tenant. @@ -88,7 +90,7 @@ class UCSVICPlugin(object): return net raise exc.NetworkNotFound(net_id=net_id) - def get_network_details(self, tenant_id, net_id): + def get_network_details(self, tenant_id, net_id, **kwargs): """ Deletes the Virtual Network belonging to a the spec @@ -97,7 +99,7 @@ class UCSVICPlugin(object): network = self._get_network(tenant_id, net_id) return network - def rename_network(self, tenant_id, net_id, new_name): + def rename_network(self, tenant_id, net_id, new_name, **kwargs): """ Updates the symbolic name belonging to a particular Virtual Network. @@ -107,7 +109,7 @@ class UCSVICPlugin(object): network[const.NET_NAME] = new_name return network - def get_all_ports(self, tenant_id, net_id): + def get_all_ports(self, tenant_id, net_id, **kwargs): """ Retrieves all port identifiers belonging to the specified Virtual Network. @@ -117,7 +119,7 @@ class UCSVICPlugin(object): ports_on_net = network[const.NET_PORTS].values() return ports_on_net - def create_port(self, tenant_id, net_id, port_state, port_id): + def create_port(self, tenant_id, net_id, port_state, port_id, **kwargs): """ Creates a port on the specified Virtual Network. """ @@ -145,7 +147,7 @@ class UCSVICPlugin(object): ports[port_id] = new_port_dict return new_port_dict - def delete_port(self, tenant_id, net_id, port_id): + def delete_port(self, tenant_id, net_id, port_id, **kwargs): """ Deletes a port on a specified Virtual Network, if the port contains a remote interface attachment, @@ -172,7 +174,7 @@ class UCSVICPlugin(object): except KeyError: raise exc.PortNotFound(net_id=net_id, port_id=port_id) - def update_port(self, tenant_id, net_id, port_id, port_state): + def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs): """ Updates the state of a port on the specified Virtual Network. """ @@ -182,7 +184,7 @@ class UCSVICPlugin(object): port[const.PORT_STATE] = port_state return port - def get_port_details(self, tenant_id, net_id, port_id): + def get_port_details(self, tenant_id, net_id, port_id, **kwargs): """ This method allows the user to retrieve a remote interface that is attached to this particular port. @@ -190,7 +192,8 @@ class UCSVICPlugin(object): LOG.debug("UCSVICPlugin:get_port_details() called\n") return self._get_port(tenant_id, net_id, port_id) - def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id): + def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id, + **kwargs): """ Attaches a remote interface to the specified port on the specified Virtual Network. @@ -215,7 +218,7 @@ class UCSVICPlugin(object): port_profile[const.PROFILE_VLAN_NAME] = new_vlan_name port_profile[const.PROFILE_VLAN_ID] = new_vlan_id - def unplug_interface(self, tenant_id, net_id, port_id): + def unplug_interface(self, tenant_id, net_id, port_id, **kwargs): """ Detaches a remote interface from the specified port on the specified Virtual Network.