Pylint fixes.

This commit is contained in:
Sumit Naiksatam 2011-08-15 20:19:54 -07:00
parent 4b16715fa6
commit b1e5581668
18 changed files with 287 additions and 223 deletions

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,3 +17,4 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,3 +17,4 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,34 +17,23 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import logging as LOG
import os
from configobj import ConfigObj
from validate import Validator
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_exceptions as cexc
LOG.basicConfig(level=LOG.WARN)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class CiscoConfigParser(ConfigObj):
"""Config Parser based on the ConfigObj module"""
def __init__(self, filename):
super(CiscoConfigParser, self).__init__(filename, raise_errors=True,
file_error=True)
def dummy(self, section, key):
"""Dummy function to return the same key, used in walk"""
return section[key]
def main():
cp = CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
+ "/" + "test.ini")
print ("%s\n") % cp['PLUGIN']['provider']
if __name__ == '__main__':
main()

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,6 +17,7 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
PLUGINS = 'PLUGINS'

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,6 +17,7 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import logging as LOG
import os
@ -34,35 +36,35 @@ _creds_dictionary = cp.walk(cp.dummy)
class Store(object):
"""Credential Store"""
@staticmethod
def putCredential(id, username, password):
"""Set the username and password"""
_creds_dictionary[id] = {const.USERNAME: username,
const.PASSWORD: password}
@staticmethod
def getUsername(id):
"""Get the username"""
return _creds_dictionary[id][const.USERNAME]
@staticmethod
def getPassword(id):
"""Get the password"""
return _creds_dictionary[id][const.PASSWORD]
@staticmethod
def getCredential(id):
"""Get the username and password"""
return _creds_dictionary[id]
@staticmethod
def getCredentials():
"""Get all usernames and passwords"""
return _creds_dictionary
@staticmethod
def deleteCredential(id):
"""Delete a credential"""
return _creds_dictionary.pop(id)
def main():
Store.putCredential("10.10.10.10", "foo", "bar")
print ("%s\n") % Store.getCredentials()
if __name__ == '__main__':
main()

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,65 +17,88 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
# @author: Rohit Agarwalla, Cisco Systems, Inc.
"""
"""
Exceptions used by the Cisco plugin
"""
from quantum.common import exceptions
class NoMoreNics(exceptions.QuantumException):
message = _("Unable to complete operation on port %(port_id)s " \
"for network %(net_id)s. No more dynamic nics are available" \
"in the system.")
"""No more dynamic nics are available in the system"""
message = _("Unable to complete operation. No more dynamic nics are " \
"available in the system.")
class PortProfileLimit(exceptions.QuantumException):
"""Port profile limit has been hit"""
message = _("Unable to complete operation on port %(port_id)s " \
"for network %(net_id)s. The system has reached the maximum" \
"limit of allowed port profiles.")
class UCSMPortProfileLimit(exceptions.QuantumException):
"""UCSM Port profile limit has been hit"""
message = _("Unable to complete operation on port %(port_id)s " \
"for network %(net_id)s. The system has reached the maximum" \
"limit of allowed UCSM port profiles.")
class NetworksLimit(exceptions.QuantumException):
"""Total number of network objects limit has been hit"""
message = _("Unable to create new network. Number of networks" \
"for the system has exceeded the limit")
class PortProfileNotFound(exceptions.QuantumException):
"""Port profile cannot be found"""
message = _("Port profile %(portprofile_id)s could not be found " \
"for tenant %(tenant_id)s")
class PortProfileInvalidDelete(exceptions.QuantumException):
"""Port profile cannot be deleted since its being used"""
message = _("Port profile %(profile_id)s could not be deleted " \
"for tenant %(tenant_id)s since port associations exist")
class NetworkVlanBindingAlreadyExists(exceptions.QuantumException):
"""Binding cannot be created, since it already exists"""
message = _("NetworkVlanBinding for %(vlan_id)s and network " \
"%(network_id)s already exists")
class PortProfileAlreadyExists(exceptions.QuantumException):
"""Port profile cannot be created since it already exisits"""
message = _("PortProfile %(pp_name) for %(tenant_id)s " \
"already exists")
class PortProfileBindingAlreadyExists(exceptions.QuantumException):
"""Binding cannot be created, since it already exists"""
message = _("PortProfileBinding for port profile %(pp_id)s to " \
"port %(port_id) already exists")
class VlanIDNotFound(exceptions.QuantumException):
"""VLAN ID cannot be found"""
message = _("Vlan ID %(vlan_id)s not found")
class VlanIDNotAvailable(exceptions.QuantumException):
"""VLAN ID is reserved"""
message = _("No available Vlan ID found")
try:
_("test")
except NameError:
def _(a_string):
"""
Default implementation of the gettext string
translation function: no translation
"""
return a_string
except TypeError:
# during doctesting, _ might mean something else
pass

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,6 +17,7 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import os
@ -23,20 +25,13 @@ from quantum.plugins.cisco.common import cisco_configparser as confp
CONF_FILE = "../conf/nova.ini"
cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
CP = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
+ "/" + CONF_FILE)
section = cp['NOVA']
DB_SERVER_IP = section['db_server_ip']
DB_NAME = section['db_name']
DB_USERNAME = section['db_username']
DB_PASSWORD = section['db_password']
NOVA_HOST_NAME = section['nova_host_name']
NOVA_PROJ_NAME = section['nova_proj_name']
def main():
print NOVA_PROJ_NAME
if __name__ == '__main__':
main()
SECTION = CP['NOVA']
DB_SERVER_IP = SECTION['db_server_ip']
DB_NAME = SECTION['db_name']
DB_USERNAME = SECTION['db_username']
DB_PASSWORD = SECTION['db_password']
NOVA_HOST_NAME = SECTION['nova_host_name']
NOVA_PROJ_NAME = SECTION['nova_proj_name']

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,16 +17,14 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import hashlib
import logging as LOG
import MySQLdb
import sys
import traceback
from quantum.common import exceptions as exc
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_nova_configuration as conf
LOG.basicConfig(level=LOG.WARN)
@ -33,15 +32,21 @@ LOG.getLogger(const.LOGGER_COMPONENT_NAME)
def get16ByteUUID(uuid):
"""
Return a 16 byte has of the UUID, used when smaller unique
ID is required.
"""
return hashlib.md5(uuid).hexdigest()[:16]
class DBUtils(object):
"""Utilities to use connect to MySQL DB and execute queries"""
def __init__(self):
pass
def _get_db_connection(self):
"""Get a connection to the DB"""
db_ip = conf.DB_SERVER_IP
db_username = conf.DB_USERNAME
db_password = conf.DB_PASSWORD
@ -50,6 +55,7 @@ class DBUtils(object):
return self.db
def execute_db_query(self, sql_query):
"""Execute a DB query"""
db = self._get_db_connection()
cursor = db.cursor()
try:

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,12 +17,19 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import inspect
from abc import ABCMeta, abstractmethod
class L2DevicePluginBase(object):
"""
Base class for a device-specific plugin.
An example of a device-specific plugin is a Nexus switch plugin.
The network model relies on device-category-specific plugins to perform
the configuration on each device.
"""
__metaclass__ = ABCMeta
@ -133,7 +141,7 @@ class L2DevicePluginBase(object):
marked with the abstractmethod decorator is
provided by the plugin class.
"""
if cls is QuantumPluginBase:
if cls is L2DevicePluginBase:
for method in cls.__abstractmethods__:
method_ok = False
for base in klass.__mro__:

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,6 +17,7 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import inspect
import logging as LOG
@ -30,78 +32,92 @@ LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class L2NetworkModel(L2NetworkModelBase):
"""
Implements the L2NetworkModelBase
This implementation works with UCS and Nexus plugin,
with one UCS blade, and one Nexus switch.
"""
_plugins = {}
def __init__(self):
for key in conf.plugins[const.PLUGINS].keys():
for key in conf.PLUGINS[const.PLUGINS].keys():
self._plugins[key] = utils.import_object(
conf.plugins[const.PLUGINS][key])
conf.PLUGINS[const.PLUGINS][key])
LOG.debug("Loaded device plugin %s\n" % \
conf.plugins[const.PLUGINS][key])
conf.PLUGINS[const.PLUGINS][key])
def _funcName(self, offset=0):
def _func_name(self, offset=0):
"""Get the name of the calling function"""
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 _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 _invokeUCSPlugin(self, 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 _invokeNexusPlugin(self, function_name, args, kwargs):
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 get_all_networks(self, args):
"""Not implemented for this model"""
pass
def create_network(self, args):
deviceParams = {const.DEVICE_IP: ""}
self._invokeAllDevicePlugins(self._funcName(), args, deviceParams)
"""Support for the Quantum core API call"""
device_params = {const.DEVICE_IP: ""}
self._invoke_all_device_plugins(self._func_name(), args, device_params)
def delete_network(self, args):
deviceParams = {const.DEVICE_IP: ""}
self._invokeAllDevicePlugins(self._funcName(), args, deviceParams)
"""Support for the Quantum core API call"""
device_params = {const.DEVICE_IP: ""}
self._invoke_all_device_plugins(self._func_name(), args, device_params)
def get_network_details(self, args):
"""Not implemented for this model"""
pass
def rename_network(self, args):
deviceParams = {const.DEVICE_IP: ""}
self._invokeAllDevicePlugins(self._funcName(), args, deviceParams)
"""Support for the Quantum core API call"""
device_params = {const.DEVICE_IP: ""}
self._invoke_all_device_plugins(self._func_name(), args, device_params)
def get_all_ports(self, args):
"""Not implemented for this model"""
pass
def create_port(self, args):
deviceParams = {const.DEVICE_IP: ""}
self._invokeUCSPlugin(self._funcName(), args, deviceParams)
"""Support for the Quantum core API call"""
device_params = {const.DEVICE_IP: ""}
self._invoke_ucs_plugin(self._func_name(), args, device_params)
def delete_port(self, args):
deviceParams = {const.DEVICE_IP: ""}
self._invokeUCSPlugin(self._funcName(), args, deviceParams)
"""Support for the Quantum core API call"""
device_params = {const.DEVICE_IP: ""}
self._invoke_ucs_plugin(self._func_name(), args, device_params)
def update_port(self, args):
"""Not implemented for this model"""
pass
def get_port_details(self, args):
"""Not implemented for this model"""
pass
def plug_interface(self, args):
deviceParams = {const.DEVICE_IP: ""}
self._invokeUCSPlugin(self._funcName(), args, deviceParams)
"""Support for the Quantum core API call"""
device_params = {const.DEVICE_IP: ""}
self._invoke_ucs_plugin(self._func_name(), args, device_params)
def unplug_interface(self, args):
deviceParams = {const.DEVICE_IP: ""}
self._invokeUCSPlugin(self._funcName(), args, deviceParams)
def main():
client = L2NetworkModel()
if __name__ == '__main__':
main()
"""Support for the Quantum core API call"""
device_params = {const.DEVICE_IP: ""}
self._invoke_ucs_plugin(self._func_name(), args, device_params)

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,12 +17,20 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import inspect
from abc import ABCMeta, abstractmethod
class L2NetworkModelBase(object):
"""
Base class for L2 Network Model
It relies on a pluggable network configuration module to gather
knowledge of the system, but knows which device-specific plugins
to invoke for a corresponding core API call, and what parameters to pass
to that plugin.
"""
__metaclass__ = ABCMeta
@ -131,7 +140,7 @@ class L2NetworkModelBase(object):
marked with the abstractmethod decorator is
provided by the plugin class.
"""
if cls is QuantumPluginBase:
if cls is L2NetworkModelBase:
for method in cls.__abstractmethods__:
method_ok = False
for base in klass.__mro__:

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,6 +17,7 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import inspect
import logging as LOG
@ -34,6 +36,7 @@ LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class L2Network(QuantumPluginBase):
""" L2 Network Framework Plugin """
def __init__(self):
self._vlan_counter = int(conf.VLAN_START) - 1
@ -52,7 +55,7 @@ class L2Network(QuantumPluginBase):
the specified tenant.
"""
LOG.debug("get_all_networks() called\n")
self._invokeDevicePlugins(self._funcName(), [tenant_id])
self._invoke_device_plugins(self._func_name(), [tenant_id])
networks_list = db.network_list(tenant_id)
new_networks_list = []
for network in networks_list:
@ -73,7 +76,7 @@ class L2Network(QuantumPluginBase):
new_net_id = new_network[const.UUID]
vlan_id = self._get_vlan_for_tenant(tenant_id, net_name)
vlan_name = self._get_vlan_name(new_net_id, str(vlan_id))
self._invokeDevicePlugins(self._funcName(), [tenant_id, net_name,
self._invoke_device_plugins(self._func_name(), [tenant_id, net_name,
new_net_id, vlan_name,
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name, new_net_id)
@ -98,7 +101,7 @@ class L2Network(QuantumPluginBase):
for port in ports_on_net:
self.delete_port(tenant_id, net_id, port[const.PORTID])
self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id])
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
net_dict = self._make_net_dict(net[const.UUID],
net[const.NETWORKNAME],
[])
@ -114,7 +117,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])
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
network = db.network_get(net_id)
ports_list = network[const.NETWORKPORTS]
ports_on_net = []
@ -137,7 +140,7 @@ class L2Network(QuantumPluginBase):
Virtual Network.
"""
LOG.debug("rename_network() called\n")
self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
new_name])
network = db.network_rename(tenant_id, net_id, new_name)
net_dict = self._make_net_dict(network[const.UUID],
@ -151,7 +154,7 @@ class L2Network(QuantumPluginBase):
specified Virtual Network.
"""
LOG.debug("get_all_ports() called\n")
self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id])
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
network = db.network_get(net_id)
ports_list = network[const.NETWORKPORTS]
ports_on_net = []
@ -171,7 +174,7 @@ class L2Network(QuantumPluginBase):
LOG.debug("create_port() called\n")
port = db.port_create(net_id, port_state)
unique_port_id_string = port[const.UUID]
self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_state,
unique_port_id_string])
new_port_dict = self._make_port_dict(port[const.UUID],
@ -188,7 +191,7 @@ class L2Network(QuantumPluginBase):
then the port can be deleted.
"""
LOG.debug("delete_port() called\n")
self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_id])
db.port_destroy(net_id, port_id)
new_port_dict = self._make_port_dict(port_id, None, None, None)
@ -199,7 +202,7 @@ 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,
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_id, port_state])
self._validate_port_state(port_state)
db.port_set_state(net_id, port_id, port_state)
@ -213,7 +216,7 @@ 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,
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_id])
port = db.port_get(net_id, port_id)
new_port_dict = self._make_port_dict(port[const.UUID],
@ -229,7 +232,7 @@ class L2Network(QuantumPluginBase):
specified Virtual Network.
"""
LOG.debug("plug_interface() called\n")
self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_id,
remote_interface_id])
db.port_set_attachment(net_id, port_id, remote_interface_id)
@ -240,7 +243,7 @@ class L2Network(QuantumPluginBase):
specified Virtual Network.
"""
LOG.debug("unplug_interface() called\n")
self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_id])
db.port_unset_attachment(net_id, port_id)
@ -248,40 +251,42 @@ class L2Network(QuantumPluginBase):
Extension API implementation
"""
def get_all_portprofiles(self, tenant_id):
#return self._portprofiles.values()
"""Get all port profiles"""
pplist = cdb.get_all_portprofiles()
new_pplist = []
for pp in pplist:
for portprofile in pplist:
new_pp = self._make_portprofile_dict(tenant_id,
pp[const.UUID],
pp[const.PPNAME],
pp[const.PPQOS])
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
new_pplist.append(new_pp)
return new_pplist
def get_portprofile_details(self, tenant_id, profile_id):
#return self._get_portprofile(tenant_id, profile_id)
pp = cdb.get_portprofile(tenant_id, profile_id)
"""Get port profile details"""
portprofile = cdb.get_portprofile(tenant_id, profile_id)
new_pp = self._make_portprofile_dict(tenant_id,
pp[const.UUID],
pp[const.PPNAME],
pp[const.PPQOS])
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
return new_pp
def create_portprofile(self, tenant_id, profile_name, qos):
pp = cdb.add_portprofile(tenant_id, profile_name,
"""Create port profile"""
portprofile = cdb.add_portprofile(tenant_id, profile_name,
const.NO_VLAN_ID, qos)
new_pp = self._make_portprofile_dict(tenant_id,
pp[const.UUID],
pp[const.PPNAME],
pp[const.PPQOS])
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
return new_pp
def delete_portprofile(self, tenant_id, profile_id):
"""Delete portprofile"""
try:
pp = cdb.get_portprofile(tenant_id, profile_id)
except Exception, e:
portprofile = cdb.get_portprofile(tenant_id, profile_id)
except Exception, exc:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=profile_id)
@ -293,23 +298,25 @@ class L2Network(QuantumPluginBase):
cdb.remove_portprofile(tenant_id, profile_id)
def rename_portprofile(self, tenant_id, profile_id, new_name):
"""Rename port profile"""
try:
pp = cdb.get_portprofile(tenant_id, profile_id)
except Exception, e:
portprofile = cdb.get_portprofile(tenant_id, profile_id)
except Exception, exc:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=profile_id)
pp = cdb.update_portprofile(tenant_id, profile_id, new_name)
portprofile = cdb.update_portprofile(tenant_id, profile_id, new_name)
new_pp = self._make_portprofile_dict(tenant_id,
pp[const.UUID],
pp[const.PPNAME],
pp[const.PPQOS])
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
return new_pp
def associate_portprofile(self, tenant_id, net_id,
port_id, portprofile_id):
"""Associate port profile"""
try:
pp = cdb.get_portprofile(tenant_id, portprofile_id)
except Exception, e:
portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
except Exception, exc:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=portprofile_id)
@ -317,35 +324,40 @@ class L2Network(QuantumPluginBase):
def disassociate_portprofile(self, tenant_id, net_id,
port_id, portprofile_id):
"""Disassociate port profile"""
try:
pp = cdb.get_portprofile(tenant_id, portprofile_id)
except Exception, e:
portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
except Exception, exc:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=portprofile_id)
cdb.remove_pp_binding(tenant_id, port_id, portprofile_id)
def create_defaultPProfile(self, tenant_id, network_id, profile_name,
def create_default_port_profile(self, tenant_id, network_id, profile_name,
qos):
pp = cdb.add_portprofile(tenant_id, profile_name,
"Create default port profile"""
portprofile = cdb.add_portprofile(tenant_id, profile_name,
const.NO_VLAN_ID, qos)
new_pp = self._make_portprofile_dict(tenant_id,
pp[const.UUID],
pp[const.PPNAME],
pp[const.PPQOS])
cdb.add_pp_binding(tenant_id, port_id, portprofile_id, True)
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
# TODO (Sumit): Need to check the following
port_id = None
cdb.add_pp_binding(tenant_id, port_id, portprofile[const.UUID], True)
return new_pp
"""
Private functions
"""
def _invokeDevicePlugins(self, function_name, args):
def _invoke_device_plugins(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):
"""Get vlan ID"""
# TODO (Sumit):
# The VLAN ID for a tenant might need to be obtained from
# somewhere (from Donabe/Melange?)
@ -355,27 +367,33 @@ class L2Network(QuantumPluginBase):
return cdb.reserve_vlanid()
def _release_vlan_for_tenant(self, tenant_id, net_id):
"""Relase VLAN"""
vlan_binding = cdb.get_vlan_binding(net_id)
return cdb.release_vlanid(vlan_binding[const.VLANID])
def _get_vlan_name(self, net_id, vlan):
"""Getting the vlan name from the tenant and vlan"""
vlan_name = conf.VLAN_NAME_PREFIX + vlan
return vlan_name
def _validate_port_state(self, port_state):
"""Checking the port state"""
if port_state.upper() not in (const.PORT_UP, const.PORT_DOWN):
raise exc.StateInvalid(port_state=port_state)
return True
def _funcName(self, offset=0):
def _func_name(self, offset=0):
"""Getting the name of the calling funciton"""
return inspect.stack()[1 + offset][3]
def _make_net_dict(self, net_id, net_name, ports):
"""Helper funciton"""
res = {const.NET_ID: net_id, const.NET_NAME: net_name}
res[const.NET_PORTS] = ports
return res
def _make_port_dict(self, port_id, port_state, net_id, attachment):
"""Helper funciton"""
res = {const.PORT_ID: port_id, const.PORT_STATE: port_state}
res[const.NET_ID] = net_id
res[const.ATTACHMENT] = attachment
@ -383,6 +401,7 @@ class L2Network(QuantumPluginBase):
def _make_portprofile_dict(self, tenant_id, profile_id, profile_name,
qos):
"""Helper funciton"""
profile_associations = self._make_portprofile_assc_list(tenant_id,
profile_id)
res = {const.PROFILE_ID: str(profile_id),
@ -393,21 +412,10 @@ class L2Network(QuantumPluginBase):
return res
def _make_portprofile_assc_list(self, tenant_id, profile_id):
"""Helper function to create port profile association list"""
plist = cdb.get_pp_binding(tenant_id, profile_id)
assc_list = []
for port in plist:
assc_list.append(port[const.PORTID])
return assc_list
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()

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,6 +17,7 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
# @author: Rohit Agarwalla, Cisco Systems, Inc.
"""
import os
@ -23,45 +25,43 @@ from quantum.plugins.cisco.common import cisco_configparser as confp
CONF_FILE = "conf/l2network_plugin.ini"
cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
+ "/" + CONF_FILE)
CONF_PARSER_OBJ = confp.\
CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
"/" + CONF_FILE)
section = cp['VLANS']
VLAN_NAME_PREFIX = section['vlan_name_prefix']
VLAN_START = section['vlan_start']
VLAN_END = section['vlan_end']
SECTION_CONF = CONF_PARSER_OBJ['VLANS']
VLAN_NAME_PREFIX = SECTION_CONF['vlan_name_prefix']
VLAN_START = SECTION_CONF['vlan_start']
VLAN_END = SECTION_CONF['vlan_end']
section = cp['PORTS']
MAX_PORTS = section['max_ports']
SECTION_CONF = CONF_PARSER_OBJ['PORTS']
MAX_PORTS = SECTION_CONF['max_ports']
section = cp['PORTPROFILES']
MAX_PORT_PROFILES = section['max_port_profiles']
SECTION_CONF = CONF_PARSER_OBJ['PORTPROFILES']
MAX_PORT_PROFILES = SECTION_CONF['max_port_profiles']
section = cp['NETWORKS']
MAX_NETWORKS = section['max_networks']
SECTION_CONF = CONF_PARSER_OBJ['NETWORKS']
MAX_NETWORKS = SECTION_CONF['max_networks']
section = cp['MODEL']
MODEL_CLASS = section['model_class']
SECTION_CONF = CONF_PARSER_OBJ['MODEL']
MODEL_CLASS = SECTION_CONF['model_class']
CONF_FILE = "conf/plugins.ini"
cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
+ "/" + CONF_FILE)
plugins = cp.walk(cp.dummy)
CONF_PARSER_OBJ = confp.\
CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
"/" + CONF_FILE)
PLUGINS = CONF_PARSER_OBJ.walk(CONF_PARSER_OBJ.dummy)
CONF_FILE = "conf/db_conn.ini"
cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
+ "/" + CONF_FILE)
CONF_PARSER_OBJ = confp.\
CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
"/" + CONF_FILE)
section = cp['DATABASE']
DB_NAME = section['name']
DB_USER = section['user']
DB_PASS = section['pass']
DB_HOST = section['host']
def main():
print plugins['PLUGINS']
if __name__ == '__main__':
main()
SECTION_CONF = CONF_PARSER_OBJ['DATABASE']
DB_NAME = SECTION_CONF['name']
DB_USER = SECTION_CONF['user']
DB_PASS = SECTION_CONF['pass']
DB_HOST = SECTION_CONF['host']

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,3 +17,4 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,11 +17,13 @@
#
# @author: Rohit Agarwalla, Cisco Systems Inc.
#
import sys
"""
import subprocess
def get_next_dynic(argv=[]):
"""Get the next available dynamic nic on this host"""
cmd = ["ifconfig", "-a"]
f_cmd_output = subprocess.Popen(cmd, stdout=subprocess.PIPE).\
communicate()[0]
@ -49,8 +52,3 @@ def get_next_dynic(argv=[]):
if not used:
break
return eth
if __name__ == '__main__':
#nic = get_next_dynic(sys.argv)
nic = get_next_dynic()
print nic

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,6 +17,7 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import os
@ -23,22 +25,15 @@ from quantum.plugins.cisco.common import cisco_configparser as confp
CONF_FILE = "../conf/ucs.ini"
cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
CP = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
+ "/" + CONF_FILE)
section = cp['UCSM']
UCSM_IP_ADDRESS = section['ip_address']
DEFAULT_VLAN_NAME = section['default_vlan_name']
DEFAULT_VLAN_ID = section['default_vlan_id']
MAX_UCSM_PORT_PROFILES = section['max_ucsm_port_profiles']
PROFILE_NAME_PREFIX = section['profile_name_prefix']
SECTION = CP['UCSM']
UCSM_IP_ADDRESS = SECTION['ip_address']
DEFAULT_VLAN_NAME = SECTION['default_vlan_name']
DEFAULT_VLAN_ID = SECTION['default_vlan_id']
MAX_UCSM_PORT_PROFILES = SECTION['max_ucsm_port_profiles']
PROFILE_NAME_PREFIX = SECTION['profile_name_prefix']
section = cp['DRIVER']
UCSM_DRIVER = section['name']
def main():
print MAX_UCSM_PORT_PROFILES
if __name__ == '__main__':
main()
SECTION = CP['DRIVER']
UCSM_DRIVER = SECTION['name']

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,16 +17,15 @@
#
# @author: Sumit Naiksatam, Cisco Systems Inc.
#
"""
"""
Implements a UCSM XML API Client
"""
import httplib
import logging as LOG
import string
import subprocess
from xml.etree import ElementTree as et
import urllib
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_exceptions as cexc
@ -114,11 +114,13 @@ PROFILE_NAME + "\" status=\"deleted\"> </vnicProfile>" \
class CiscoUCSMDriver():
"""UCSM Driver"""
def __init__(self):
pass
def _post_data(self, ucsm_ip, ucsm_username, ucsm_password, data):
"""Send command to UCSM in http request"""
conn = httplib.HTTPConnection(ucsm_ip)
login_data = "<aaaLogin inName=\"" + ucsm_username + \
"\" inPassword=\"" + ucsm_password + "\" />"
@ -129,8 +131,8 @@ class CiscoUCSMDriver():
LOG.debug(response.reason)
LOG.debug(response_data)
# TODO (Sumit): If login is not successful, throw exception
xmlTree = et.XML(response_data)
cookie = xmlTree.attrib["outCookie"]
xml_tree = et.XML(response_data)
cookie = xml_tree.attrib["outCookie"]
data = data.replace(COOKIE_VALUE, cookie)
LOG.debug("POST: %s" % data)
@ -150,65 +152,76 @@ class CiscoUCSMDriver():
LOG.debug(response_data)
def _create_vlan_post_data(self, vlan_name, vlan_id):
"""Create command"""
data = CREATE_VLAN.replace(VLAN_NAME, vlan_name)
data = data.replace(VLAN_ID, vlan_id)
return data
def _create_profile_post_data(self, profile_name, vlan_name):
"""Create command"""
data = CREATE_PROFILE.replace(PROFILE_NAME, profile_name)
data = data.replace(VLAN_NAME, vlan_name)
return data
def _create_profile_client_post_data(self, profile_name,
def _create_pclient_post_data(self, profile_name,
profile_client_name):
"""Create command"""
data = ASSOCIATE_PROFILE.replace(PROFILE_NAME, profile_name)
data = data.replace(PROFILE_CLIENT, profile_client_name)
return data
def _change_vlan_in_profile_post_data(self, profile_name, old_vlan_name,
def _change_vlaninprof_post_data(self, profile_name, old_vlan_name,
new_vlan_name):
"""Create command"""
data = CHANGE_VLAN_IN_PROFILE.replace(PROFILE_NAME, profile_name)
data = data.replace(OLD_VLAN_NAME, old_vlan_name)
data = data.replace(VLAN_NAME, new_vlan_name)
return data
def _delete_vlan_post_data(self, vlan_name):
"""Create command"""
data = DELETE_VLAN.replace(VLAN_NAME, vlan_name)
return data
def _delete_profile_post_data(self, profile_name):
"""Create command"""
data = DELETE_PROFILE.replace(PROFILE_NAME, profile_name)
return data
def _get_next_dynamic_nic(self):
"""Get an avaialble dynamic nic on the host"""
dynamic_nic_id = gvif.get_next_dynic()
if len(dynamic_nic_id) > 0:
return dynamic_nic_id
else:
raise cisco_exceptions.NoMoreNics(net_id=net_id, port_id=port_id)
raise cexc.NoMoreNics()
def create_vlan(self, vlan_name, vlan_id, ucsm_ip, ucsm_username,
ucsm_password):
"""Create request for UCSM"""
data = self._create_vlan_post_data(vlan_name, vlan_id)
self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)
def create_profile(self, profile_name, vlan_name, ucsm_ip, ucsm_username,
ucsm_password):
"""Create request for UCSM"""
data = self._create_profile_post_data(profile_name, vlan_name)
self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)
data = self._create_profile_client_post_data(profile_name,
data = self._create_pclient_post_data(profile_name,
profile_name[-16:])
self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)
def change_vlan_in_profile(self, profile_name, old_vlan_name,
new_vlan_name, ucsm_ip, ucsm_username,
ucsm_password):
data = self._change_vlan_in_profile_post_data(profile_name,
"""Create request for UCSM"""
data = self._change_vlaninprof_post_data(profile_name,
old_vlan_name,
new_vlan_name)
self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)
def get_dynamic_nic(self, host):
"""Get an avaialble dynamic nic on the host"""
# TODO (Sumit): Check availability per host
# TODO (Sumit): If not available raise exception
# TODO (Sumit): This simple logic assumes that create-port and
@ -222,36 +235,17 @@ class CiscoUCSMDriver():
return dynamic_nic_name
def delete_vlan(self, vlan_name, ucsm_ip, ucsm_username, ucsm_password):
"""Create request for UCSM"""
data = self._delete_vlan_post_data(vlan_name)
self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)
def delete_profile(self, profile_name, ucsm_ip, ucsm_username,
ucsm_password):
"""Create request for UCSM"""
data = self._delete_profile_post_data(profile_name)
self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)
def release_dynamic_nic(self, host):
"""Release a reserved dynamic nic on the host"""
# TODO (Sumit): Release on a specific host
pass
def main():
client = CiscoUCSMDriver()
#client.create_vlan("quantum-vlan-3", "3","172.20.231.27","admin",
# "c3l12345")
#client.create_profile("q-prof-3", "quantum-vlan-3","172.20.231.27",
# "admin", "c3l12345")
#client.get_dynamic_nic("dummy")
#client.get_dynamic_nic("dummy")
#client.release_dynamic_nic("dummy")
print client.get_dynamic_nic("dummy")
"""
client.change_vlan_in_profile("br100", "default", "test-2",
"172.20.231.27","admin",
"c3l12345")
client.change_vlan_in_profile("br100", "test-2", "default",
"172.20.231.27", "admin", "c3l12345")
"""
if __name__ == '__main__':
main()

View File

@ -1,3 +1,4 @@
"""
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@ -16,6 +17,7 @@
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
#
"""
import logging as LOG
@ -33,6 +35,7 @@ LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class UCSVICPlugin(L2DevicePluginBase):
"""UCS Device Plugin"""
_networks = {}
def __init__(self):
@ -238,18 +241,20 @@ class UCSVICPlugin(L2DevicePluginBase):
port_profile[const.PROFILE_VLAN_ID] = conf.DEFAULT_VLAN_ID
def _get_profile_name(self, port_id):
#profile_name = conf.PROFILE_NAME_PREFIX + port_id
"""Returns the port profile name based on the port UUID"""
profile_name = conf.PROFILE_NAME_PREFIX \
+ cutil.get16ByteUUID(port_id)
return profile_name
def _validate_port_state(self, port_state):
"""Check the port state"""
if port_state.upper() not in (const.PORT_UP, const.PORT_DOWN):
raise exc.StateInvalid(port_state=port_state)
return True
def _validate_attachment(self, tenant_id, network_id, port_id,
remote_interface_id):
"""Check if the VIF can be attached"""
network = self._get_network(tenant_id, network_id)
for port in network[const.NET_PORTS].values():
if port[const.ATTACHMENT] == remote_interface_id:
@ -258,22 +263,26 @@ class UCSVICPlugin(L2DevicePluginBase):
att_id=port[const.ATTACHMENT])
def _get_network(self, tenant_id, network_id):
"""Get the network object ref"""
network = self._networks.get(network_id)
if not network:
raise exc.NetworkNotFound(net_id=network_id)
return network
def _get_vlan_name_for_network(self, tenant_id, network_id):
"""Return the VLAN name as set by the L2 network plugin"""
net = self._get_network(tenant_id, network_id)
vlan_name = net[const.NET_VLAN_NAME]
return vlan_name
def _get_vlan_id_for_network(self, tenant_id, network_id):
"""Return the VLAN id as set by the L2 network plugin"""
net = self._get_network(tenant_id, network_id)
vlan_id = net[const.NET_VLAN_ID]
return vlan_id
def _get_port(self, tenant_id, network_id, port_id):
"""Get the port object ref"""
net = self._get_network(tenant_id, network_id)
port = net[const.NET_PORTS].get(port_id)
if not port:
@ -282,6 +291,7 @@ class UCSVICPlugin(L2DevicePluginBase):
def _create_port_profile(self, tenant_id, net_id, port_id, vlan_name,
vlan_id):
"""Create port profile in UCSM"""
if self._port_profile_counter >= int(conf.MAX_UCSM_PORT_PROFILES):
raise cexc.UCSMPortProfileLimit(net_id=net_id, port_id=port_id)
profile_name = self._get_profile_name(port_id)
@ -294,6 +304,7 @@ class UCSVICPlugin(L2DevicePluginBase):
return new_port_profile
def _delete_port_profile(self, port_id, profile_name):
"""Delete port profile in UCSM"""
self._client.delete_profile(profile_name, self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
self._port_profile_counter -= 1