From: Sumit Naiksatam Date: Mon, 22 Aug 2011 11:16:03 +0000 (-0700) Subject: Missed adding a file earlier, fixed a small issue. X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=88dad10e4d7c60e922fc9da7348713a94dabe3cf;p=openstack-build%2Fneutron-build.git Missed adding a file earlier, fixed a small issue. --- diff --git a/quantum/plugins/cisco/l2device_inventory_base.py b/quantum/plugins/cisco/l2device_inventory_base.py new file mode 100644 index 000000000..9ecbed3fe --- /dev/null +++ b/quantum/plugins/cisco/l2device_inventory_base.py @@ -0,0 +1,343 @@ +""" +# 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 L2NetworkDeviceInventoryBase(object): + """ + Base class for L2 Network Device Inventory + This is used by the L2Nework Model to get information about + the actual devices of a particular type in a given deployment. + For instance, an implementation in the context of UCS will + know what UCSMs, chasses, blades, and dynamic vnics are + present in a particular deployment. + Similarly, an implementation in the context of Nexus switches + will know which switches are present in the system, and how they + are interconnected to other switches/devices. + """ + + __metaclass__ = ABCMeta + + @abstractmethod + def get_all_networks(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def create_network(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def delete_network(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def get_network_details(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def rename_network(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def get_all_ports(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def create_port(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def delete_port(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def update_port(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def get_port_details(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def plug_interface(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :raises: + """ + pass + + @abstractmethod + def unplug_interface(self, args): + """ + Returns a dictionary containing the first element as a device + IP address list. The model then invokes the device-specific plugin + for each device IP in that list. This is followed by zero or more + key-value pairs (specific to each operation, device type, and + deployment. + The model implementation may or may not process the returned + values, but needs to pass them to the device-specific plugin. + Since the device-specific plugin and this inventory implementation + are assumed to be implemented by the same entity, the + device-sepcific knows how to process this dictionary. + :returns: a dictionary with the following signature: + {'device_ip': [] + 'key-1': "value 1", + ... + 'key-n': "value n" + } + :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 L2NetworkDeviceInventoryBase: + 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/models/l2network_multi_blade.py b/quantum/plugins/cisco/models/l2network_multi_blade.py index a2d57e65a..9f8958b2b 100644 --- a/quantum/plugins/cisco/models/l2network_multi_blade.py +++ b/quantum/plugins/cisco/models/l2network_multi_blade.py @@ -72,11 +72,15 @@ class L2NetworkMultiBlade(L2NetworkModelBase): device_params = self._invoke_inventory(plugin_key, function_name, args) device_ips = device_params[const.DEVICE_IP] - for device_ip in device_ips: - new_device_params = deepcopy(device_params) - new_device_params[const.DEVICE_IP] = device_ip + if not device_ips: self._invoke_plugin(plugin_key, function_name, args, - new_device_params) + device_params) + else: + for device_ip in device_ips: + new_device_params = deepcopy(device_params) + new_device_params[const.DEVICE_IP] = device_ip + self._invoke_plugin(plugin_key, function_name, args, + new_device_params) def _invoke_inventory(self, plugin_key, function_name, args): """Invoke only the inventory implementation""" @@ -84,8 +88,9 @@ class L2NetworkMultiBlade(L2NetworkModelBase): LOG.warn("No %s inventory loaded" % plugin_key) LOG.warn("%s: %s with args %s ignored" \ % (plugin_key, function_name, args)) - return - return getattr(self._inventory[plugin_key], function_name)(args) + return {const.DEVICE_IP: []} + else: + return getattr(self._inventory[plugin_key], function_name)(args) def _invoke_plugin(self, plugin_key, function_name, args, kwargs): """Invoke only the device plugin"""