#
"""
+from copy import deepcopy
import inspect
import logging as LOG
import platform
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_exceptions as cexc
-from quantum.plugins.cisco.ucs import cisco_ucs_inventory as ucsinv
LOG.basicConfig(level=LOG.WARN)
-LOG.getLogger(const.LOGGER_COMPONENT_NAME)
+LOG.getLogger(__name__)
class L2NetworkMultiBlade(L2NetworkModelBase):
All UCSM connected to a single Nexus Switch
"""
_plugins = {}
+ _inventory = {}
def __init__(self):
for key in conf.PLUGINS[const.PLUGINS].keys():
conf.PLUGINS[const.PLUGINS][key])
LOG.debug("Loaded device plugin %s\n" % \
conf.PLUGINS[const.PLUGINS][key])
-
- self._ucs_inventory = ucsinv.UCSInventory()
+ if key in conf.PLUGINS[const.INVENTORY].keys():
+ self._inventory[key] = utils.import_object(
+ conf.PLUGINS[const.INVENTORY][key])
+ LOG.debug("Loaded device inventory %s\n" % \
+ conf.PLUGINS[const.INVENTORY][key])
def _func_name(self, offset=0):
"""Get the name of the calling function"""
return inspect.stack()[1 + offset][3]
- def _invoke_all_device_plugins(self, function_name, args, kwargs):
- """Invoke all device plugins for this model implementation"""
- for plugin_obj_ref in self._plugins.values():
- getattr(plugin_obj_ref, function_name)(*args, **kwargs)
-
- def _invoke_ucs_plugin(self, function_name, args, kwargs):
- """Invoke only the UCS plugin"""
- if const.UCS_PLUGIN in self._plugins.keys():
- getattr(self._plugins[const.UCS_PLUGIN],
- function_name)(*args, **kwargs)
-
- def _invoke_ucs_plugin_per_device(self, function_name, args):
- """Invoke only UCS plugin for all the UCSMs in the system"""
- ucsm_ips = self._ucs_inventory.get_all_ucsms()
- for ucsm_ip in ucsm_ips:
- device_params = {const.DEVICE_IP: ucsm_ip}
- self._invoke_ucs_plugin(function_name, args, device_params)
-
- def _invoke_nexus_plugin(self, function_name, args, kwargs):
- """Invoke only the Nexus plugin"""
- if const.NEXUS_PLUGIN in self._plugins.keys():
- getattr(self._plugins[const.NEXUS_PLUGIN],
- function_name)(*args, **kwargs)
-
- def _invoke_nexus_plugin_per_device(self, function_name, args):
- """Invoke only the nexus plugin for all the switches in the system"""
- device_params = {const.DEVICE_IP: ""}
- self._invoke_nexus_plugin(self._func_name(), args, device_params)
+ def _invoke_plugin_per_device(self, plugin_key, function_name, args):
+ """Invoke only device plugin for all the devices in the system"""
+ if not plugin_key in self._plugins.keys():
+ LOG.info("No %s Plugin loaded" % plugin_key)
+ LOG.info("%s: %s with args %s ignored" \
+ % (plugin_key, function_name, args))
+ return
+ 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
+ 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"""
+ if not plugin_key in self._inventory.keys():
+ 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)
+
+ def _invoke_plugin(self, plugin_key, function_name, args, kwargs):
+ """Invoke only the device plugin"""
+ return getattr(self._plugins[plugin_key], function_name)(*args,
+ **kwargs)
def get_all_networks(self, args):
"""Not implemented for this model"""
def create_network(self, args):
"""Support for the Quantum core API call"""
- self._invoke_ucs_plugin_per_device(self._func_name(), args)
- self._invoke_nexus_plugin_per_device(self._func_name(), args)
+ self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
+ args)
+ self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
+ self._func_name(), args)
def delete_network(self, args):
"""Support for the Quantum core API call"""
- self._invoke_ucs_plugin_per_device(self._func_name(), args)
- self._invoke_nexus_plugin_per_device(self._func_name(), args)
+ self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
+ args)
+ self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
+ self._func_name(), args)
def get_network_details(self, args):
"""Not implemented for this model"""
def rename_network(self, args):
"""Support for the Quantum core API call"""
- self._invoke_ucs_plugin_per_device(self._func_name(), args)
- self._invoke_nexus_plugin_per_device(self._func_name(), args)
+ self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
+ args)
+ self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
+ self._func_name(), args)
def get_all_ports(self, args):
"""Not implemented for this model"""
def create_port(self, args):
"""Support for the Quantum core API call"""
- if not const.UCS_PLUGIN in self._plugins.keys():
- return
- least_reserved_blade_dict = \
- self._ucs_inventory.get_least_reserved_blade()
- if not least_reserved_blade_dict:
- raise cexc.NoMoreNics()
- ucsm_ip = least_reserved_blade_dict[const.LEAST_RSVD_BLADE_UCSM]
- device_params = {const.DEVICE_IP: ucsm_ip,
- const.UCS_INVENTORY: self._ucs_inventory,
- const.LEAST_RSVD_BLADE_DICT:\
- least_reserved_blade_dict}
- self._invoke_ucs_plugin(self._func_name(), args, device_params)
+ self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
+ args)
def delete_port(self, args):
"""Support for the Quantum core API call"""
- if not const.UCS_PLUGIN in self._plugins.keys():
- return
- rsvd_info = \
- self._ucs_inventory.get_rsvd_blade_intf_by_port(args[0],
- args[2])
- if not rsvd_info:
- raise exc.PortNotFound(net_id=args[1], port_id=args[2])
- device_params = \
- {const.DEVICE_IP: rsvd_info[const.UCSM_IP],
- const.UCS_INVENTORY: self._ucs_inventory,
- const.CHASSIS_ID: rsvd_info[const.CHASSIS_ID],
- const.BLADE_ID: rsvd_info[const.BLADE_ID],
- const.BLADE_INTF_DN: rsvd_info[const.BLADE_INTF_DN]}
- self._invoke_ucs_plugin(self._func_name(), args, device_params)
+ self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
+ args)
def update_port(self, args):
"""Not implemented for this model"""
def plug_interface(self, args):
"""Support for the Quantum core API call"""
- if not const.UCS_PLUGIN in self._plugins.keys():
- return
- rsvd_info = \
- self._ucs_inventory.get_rsvd_blade_intf_by_port(args[0],
- args[2])
- if not rsvd_info:
- raise exc.PortNotFound(net_id=args[1], port_id=args[2])
- device_params = {const.DEVICE_IP: rsvd_info[const.UCSM_IP]}
- self._invoke_ucs_plugin(self._func_name(), args, device_params)
+ self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
+ args)
def unplug_interface(self, args):
"""Support for the Quantum core API call"""
- if not const.UCS_PLUGIN in self._plugins.keys():
- return
- rsvd_info = \
- self._ucs_inventory.get_rsvd_blade_intf_by_port(args[0],
- args[2])
- if not rsvd_info:
- raise exc.PortNotFound(net_id=args[1], port_id=args[2])
- device_params = {const.DEVICE_IP: rsvd_info[const.UCSM_IP]}
- self._invoke_ucs_plugin(self._func_name(), args, device_params)
+ self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
+ args)
def get_host(self, args):
"""Provides the hostname on which a dynamic vnic is reserved"""
LOG.debug("get_host() called\n")
- if not const.UCS_PLUGIN in self._plugins.keys():
- return
- tenant_id = args[0]
- instance_id = args[1]
- host_name = self._ucs_inventory.get_host_name(tenant_id, instance_id)
- host_list = {const.HOST_LIST: {const.HOST_1: host_name}}
- return host_list
+ return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
+ args)
def get_instance_port(self, args):
"""
Get the portprofile name and the device namei for the dynamic vnic
"""
LOG.debug("get_instance_port() called\n")
- if not const.UCS_PLUGIN in self._plugins.keys():
- return
- tenant_id = args[0]
- instance_id = args[1]
- vif_id = args[2]
- vif_info = self._ucs_inventory.get_instance_port(tenant_id,
- instance_id,
- vif_id)
- vif_desc = {const.VIF_DESC: vif_info}
- return vif_desc
+ return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
+ args)
import logging as LOG
from quantum.common import exceptions as exc
+from quantum.plugins.cisco.l2device_inventory_base \
+ import L2NetworkDeviceInventoryBase
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_network_driver
LOG.basicConfig(level=LOG.WARN)
-LOG.getLogger(const.LOGGER_COMPONENT_NAME)
+LOG.getLogger(__name__)
"""
The _inventory data strcuture contains a nested disctioary:
"""
-class UCSInventory(object):
+class UCSInventory(L2NetworkDeviceInventoryBase):
"""
Manages the state of all the UCS chasses, and blades in
the system
const.BLADE_UNRESERVED_INTF_COUNT: unreserved_counter}
return blade_data
- def get_all_ucsms(self):
- """Get the IPs of all the UCSMs in the system"""
- return self._inventory.keys()
+ def _get_all_ucsms(self):
+ """Return a list of the IPs of all the UCSMs in the system"""
+ return {const.DEVICE_IP: self._inventory.keys()}
+
+ def _get_blade_for_port(self, args):
+ """
+ Return the a dict with IP address of the blade
+ on which a dynamic vnic was reserved for this port
+ """
+ tenant_id = args[0]
+ net_id = args[1]
+ port_id = args[2]
+ rsvd_info = self.get_rsvd_blade_intf_by_port(tenant_id, port_id)
+ if not rsvd_info:
+ raise exc.PortNotFound(net_id=net_id, port_id=port_id)
+ device_params = {const.DEVICE_IP: [rsvd_info[const.UCSM_IP]]}
+ return device_params
+
+ def _get_host_name_for_rsvd_intf(self, tenant_id, instance_id):
+ """
+ Return the hostname of the blade with a reserved instance
+ for this tenant
+ """
+ for ucsm_ip in self._inventory_state.keys():
+ ucsm = self._inventory_state[ucsm_ip]
+ for chassis_id in ucsm.keys():
+ for blade_id in ucsm[chassis_id]:
+ blade_data = ucsm[chassis_id][blade_id]
+ blade_intf_data = blade_data[const.BLADE_INTF_DATA]
+ for blade_intf in blade_intf_data.keys():
+ if blade_intf_data[blade_intf]\
+ [const.BLADE_INTF_RESERVATION] == \
+ const.BLADE_INTF_RESERVED and \
+ blade_intf_data[blade_intf]\
+ [const.TENANTID] == tenant_id and \
+ blade_intf_data[blade_intf]\
+ [const.INSTANCE_ID] == None:
+ blade_intf_data[blade_intf]\
+ [const.INSTANCE_ID] = instance_id
+ host_name = self._get_host_name(ucsm_ip,
+ chassis_id,
+ blade_id)
+ port_binding = udb.get_portbinding_dn(blade_intf)
+ port_id = port_binding[const.PORTID]
+ udb.update_portbinding(port_id,
+ instance_id=instance_id)
+ return host_name
+ return None
+
+ def _get_instance_port(self, tenant_id, instance_id, vif_id=None):
+ """
+ Return the device name for a reserved interface
+ """
+ for ucsm_ip in self._inventory_state.keys():
+ ucsm = self._inventory_state[ucsm_ip]
+ for chassis_id in ucsm.keys():
+ for blade_id in ucsm[chassis_id]:
+ blade_data = ucsm[chassis_id][blade_id]
+ blade_intf_data = blade_data[const.BLADE_INTF_DATA]
+ for blade_intf in blade_intf_data.keys():
+ if blade_intf_data[blade_intf]\
+ [const.BLADE_INTF_RESERVATION] == \
+ const.BLADE_INTF_RESERVED and \
+ blade_intf_data[blade_intf]\
+ [const.TENANTID] == tenant_id and \
+ blade_intf_data[blade_intf]\
+ [const.INSTANCE_ID] == instance_id:
+ blade_intf_data[blade_intf][const.VIF_ID] = \
+ vif_id
+ port_binding = udb.get_portbinding_dn(blade_intf)
+ port_id = port_binding[const.PORTID]
+ udb.update_portbinding(port_id,
+ vif_id=vif_id)
+ device_name = blade_intf_data[blade_intf]\
+ [const.BLADE_INTF_RHEL_DEVICE_NAME]
+ profile_name = port_binding[const.PORTPROFILENAME]
+ return {const.DEVICENAME: device_name,
+ const.UCSPROFILE: profile_name}
+ return None
def reload_inventory(self):
"""Reload the inventory from a conf file"""
return blade_intf_info
return None
- def get_host_name(self, tenant_id, instance_id):
+ def add_blade(self, ucsm_ip, chassis_id, blade_id):
+ """Add a blade to the inventory"""
+ # TODO (Sumit)
+ pass
+
+ def get_all_networks(self, args):
+ """Return all UCSM IPs"""
+ LOG.debug("get_all_networks() called\n")
+ return self._get_all_ucsms()
+
+ def create_network(self, args):
+ """Return all UCSM IPs"""
+ LOG.debug("create_network() called\n")
+ return self._get_all_ucsms()
+
+ def delete_network(self, args):
+ """Return all UCSM IPs"""
+ LOG.debug("delete_network() called\n")
+ return self._get_all_ucsms()
+
+ def get_network_details(self, args):
+ """Return all UCSM IPs"""
+ LOG.debug("get_network_details() called\n")
+ return self._get_all_ucsms()
+
+ def rename_network(self, args):
+ """Return all UCSM IPs"""
+ LOG.debug("rename_network() called\n")
+ return self._get_all_ucsms()
+
+ def get_all_ports(self, args):
+ """Return all UCSM IPs"""
+ LOG.debug("get_all_ports() called\n")
+ return self._get_all_ucsms()
+
+ def create_port(self, args):
"""
- Return the hostname of the blade with a reserved instance
- for this tenant
+ Return the a dict with information of the blade
+ on which a dynamic vnic is available
"""
- for ucsm_ip in self._inventory_state.keys():
- ucsm = self._inventory_state[ucsm_ip]
- for chassis_id in ucsm.keys():
- for blade_id in ucsm[chassis_id]:
- blade_data = ucsm[chassis_id][blade_id]
- blade_intf_data = blade_data[const.BLADE_INTF_DATA]
- for blade_intf in blade_intf_data.keys():
- if blade_intf_data[blade_intf]\
- [const.BLADE_INTF_RESERVATION] == \
- const.BLADE_INTF_RESERVED and \
- blade_intf_data[blade_intf]\
- [const.TENANTID] == tenant_id and \
- blade_intf_data[blade_intf]\
- [const.INSTANCE_ID] == None:
- blade_intf_data[blade_intf]\
- [const.INSTANCE_ID] = instance_id
- host_name = self._get_host_name(ucsm_ip,
- chassis_id,
- blade_id)
- port_binding = udb.get_portbinding_dn(blade_intf)
- port_id = port_binding[const.PORTID]
- udb.update_portbinding(port_id,
- instance_id=instance_id)
- return host_name
- return None
+ LOG.debug("create_port() called\n")
+ least_reserved_blade_dict = self.get_least_reserved_blade()
+ if not least_reserved_blade_dict:
+ raise cexc.NoMoreNics()
+ ucsm_ip = least_reserved_blade_dict[const.LEAST_RSVD_BLADE_UCSM]
+ device_params = {const.DEVICE_IP: [ucsm_ip],
+ const.UCS_INVENTORY: self,
+ const.LEAST_RSVD_BLADE_DICT:\
+ least_reserved_blade_dict}
+ return device_params
+
+ def delete_port(self, args):
+ """
+ Return the a dict with information of the blade
+ on which a dynamic vnic was reserved for this port
+ """
+ LOG.debug("delete_port() called\n")
+ tenant_id = args[0]
+ net_id = args[1]
+ port_id = args[2]
+ rsvd_info = self.get_rsvd_blade_intf_by_port(tenant_id, port_id)
+ if not rsvd_info:
+ raise exc.PortNotFound(net_id=net_id, port_id=port_id)
+ device_params = \
+ {const.DEVICE_IP: [rsvd_info[const.UCSM_IP]],
+ const.UCS_INVENTORY: self,
+ const.CHASSIS_ID: rsvd_info[const.CHASSIS_ID],
+ const.BLADE_ID: rsvd_info[const.BLADE_ID],
+ const.BLADE_INTF_DN: rsvd_info[const.BLADE_INTF_DN]}
+ return device_params
+
+ def update_port(self, args):
+ """
+ Return the a dict with IP address of the blade
+ on which a dynamic vnic was reserved for this port
+ """
+ LOG.debug("update_port() called\n")
+ return self._get_blade_for_port(args)
- def get_instance_port(self, tenant_id, instance_id, vif_id=None):
+ def get_port_details(self, args):
"""
- Return the device name for a reserved interface
+ Return the a dict with IP address of the blade
+ on which a dynamic vnic was reserved for this port
"""
- for ucsm_ip in self._inventory_state.keys():
- ucsm = self._inventory_state[ucsm_ip]
- for chassis_id in ucsm.keys():
- for blade_id in ucsm[chassis_id]:
- blade_data = ucsm[chassis_id][blade_id]
- blade_intf_data = blade_data[const.BLADE_INTF_DATA]
- for blade_intf in blade_intf_data.keys():
- if blade_intf_data[blade_intf]\
- [const.BLADE_INTF_RESERVATION] == \
- const.BLADE_INTF_RESERVED and \
- blade_intf_data[blade_intf]\
- [const.TENANTID] == tenant_id and \
- blade_intf_data[blade_intf]\
- [const.INSTANCE_ID] == instance_id:
- blade_intf_data[blade_intf][const.VIF_ID] = \
- vif_id
- port_binding = udb.get_portbinding_dn(blade_intf)
- port_id = port_binding[const.PORTID]
- udb.update_portbinding(port_id,
- vif_id=vif_id)
- device_name = blade_intf_data[blade_intf]\
- [const.BLADE_INTF_RHEL_DEVICE_NAME]
- profile_name = port_binding[const.PORTPROFILENAME]
- return {const.DEVICENAME: device_name,
- const.UCSPROFILE: profile_name}
- return None
+ LOG.debug("get_port_details() called\n")
+ return self._get_blade_for_port(args)
- def add_blade(self, ucsm_ip, chassis_id, blade_id):
- """Add a blade to the inventory"""
- # TODO (Sumit)
- pass
+ def plug_interface(self, args):
+ """
+ Return the a dict with IP address of the blade
+ on which a dynamic vnic was reserved for this port
+ """
+ LOG.debug("plug_interface() called\n")
+ return self._get_blade_for_port(args)
+
+ def unplug_interface(self, args):
+ """
+ Return the a dict with IP address of the blade
+ on which a dynamic vnic was reserved for this port
+ """
+ LOG.debug("unplug_interface() called\n")
+ return self._get_blade_for_port(args)
+
+ def get_host(self, args):
+ """Provides the hostname on which a dynamic vnic is reserved"""
+ LOG.debug("get_host() called\n")
+ tenant_id = args[0]
+ instance_id = args[1]
+ host_name = self._get_host_name_for_rsvd_intf(tenant_id, instance_id)
+ host_list = {const.HOST_LIST: {const.HOST_1: host_name}}
+ return host_list
+
+ def get_instance_port(self, args):
+ """
+ Get the portprofile name and the device name for the dynamic vnic
+ """
+ LOG.debug("get_instance_port() called\n")
+ tenant_id = args[0]
+ instance_id = args[1]
+ vif_id = args[2]
+ vif_info = self._get_instance_port(tenant_id, instance_id, vif_id)
+ vif_desc = {const.VIF_DESC: vif_info}
+ return vif_desc