Missed adding a file earlier, fixed a small issue.
This commit is contained in:
343
quantum/plugins/cisco/l2device_inventory_base.py
Normal file
343
quantum/plugins/cisco/l2device_inventory_base.py
Normal file
@@ -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
|
||||||
@@ -72,6 +72,10 @@ class L2NetworkMultiBlade(L2NetworkModelBase):
|
|||||||
device_params = self._invoke_inventory(plugin_key, function_name,
|
device_params = self._invoke_inventory(plugin_key, function_name,
|
||||||
args)
|
args)
|
||||||
device_ips = device_params[const.DEVICE_IP]
|
device_ips = device_params[const.DEVICE_IP]
|
||||||
|
if not device_ips:
|
||||||
|
self._invoke_plugin(plugin_key, function_name, args,
|
||||||
|
device_params)
|
||||||
|
else:
|
||||||
for device_ip in device_ips:
|
for device_ip in device_ips:
|
||||||
new_device_params = deepcopy(device_params)
|
new_device_params = deepcopy(device_params)
|
||||||
new_device_params[const.DEVICE_IP] = device_ip
|
new_device_params[const.DEVICE_IP] = device_ip
|
||||||
@@ -84,7 +88,8 @@ class L2NetworkMultiBlade(L2NetworkModelBase):
|
|||||||
LOG.warn("No %s inventory loaded" % plugin_key)
|
LOG.warn("No %s inventory loaded" % plugin_key)
|
||||||
LOG.warn("%s: %s with args %s ignored" \
|
LOG.warn("%s: %s with args %s ignored" \
|
||||||
% (plugin_key, function_name, args))
|
% (plugin_key, function_name, args))
|
||||||
return
|
return {const.DEVICE_IP: []}
|
||||||
|
else:
|
||||||
return getattr(self._inventory[plugin_key], function_name)(args)
|
return getattr(self._inventory[plugin_key], function_name)(args)
|
||||||
|
|
||||||
def _invoke_plugin(self, plugin_key, function_name, args, kwargs):
|
def _invoke_plugin(self, plugin_key, function_name, args, kwargs):
|
||||||
|
|||||||
Reference in New Issue
Block a user