Cisco plugin cleanup

Removing unused plugins and code from the Cisco plugin framework.

Change-Id: Ib22d173a088ad50b410a51a1d92685259d0af473
Implements: blueprint cisco-plugin-cleanup
This commit is contained in:
Arvind Somya 2013-01-16 13:40:12 -05:00
parent 4b448b82f0
commit ee589db437
46 changed files with 122 additions and 4189 deletions

View File

@ -1,9 +1,6 @@
[PLUGINS]
#ucs_plugin=quantum.plugins.cisco.ucs.cisco_ucs_plugin_v2.UCSVICPlugin
#nexus_plugin=quantum.plugins.cisco.nexus.cisco_nexus_plugin_v2.NexusPlugin
vswitch_plugin=quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2
[INVENTORY]
#ucs_plugin=quantum.plugins.cisco.ucs.cisco_ucs_inventory_v2.UCSInventory
#ucs_plugin=quantum.plugins.cisco.tests.unit.v2.ucs.cisco_ucs_inventory_fake.UCSInventory
#nexus_plugin=quantum.plugins.cisco.nexus.cisco_nexus_inventory.NexusInventory

View File

@ -1,8 +1,3 @@
#Provide the UCSM credentials, make sure you have a separate entry for every UCSM in your deployment
[<put_ucsm_ip_address_here>]
username=<put_user_name_here>
password=<put_password_here>
#Provide the Nexus credentials, if you are using Nexus
[<put_nexus_switch_ip_address_here>]
username=<put_user_name_here>

View File

@ -13,7 +13,6 @@ max_port_profiles=65568
max_networks=65568
[MODEL]
#model_class=quantum.plugins.cisco.models.network_multi_blade_v2.NetworkMultiBladeV2
model_class=quantum.plugins.cisco.models.virt_phy_sw_v2.VirtualPhysicalSwitchModelV2
[SEGMENTATION]

View File

@ -1,12 +0,0 @@
[UCSM]
#change the following to the appropriate UCSM IP address
#if you have more than one UCSM, enter info from any one
ip_address=<put_ucsm_ip_address_here>
default_vlan_name=default
default_vlan_id=1
max_ucsm_port_profiles=1024
profile_name_prefix=q-
[DRIVER]
#name=quantum.plugins.cisco.ucs.cisco_ucs_network_driver.CiscoUCSMDriver
name=quantum.plugins.cisco.tests.unit.v2.ucs.fake_ucs_driver.CiscoUCSMFakeDriver

View File

@ -1,24 +0,0 @@
[ucsm-1]
ip_address = <put_ucsm_ip_address_here>
[[chassis-1]]
chassis_id = <put_the_chassis_id_here>
[[[blade-1]]]
blade_id = <put_blade_id_here>
host_name = <put_hostname_here>
[[[blade-2]]]
blade_id = <put_blade_id_here>
host_name = <put_hostname_here>
[[[blade-3]]]
blade_id = <put_blade_id_here>
host_name = <put_hostname_here>
[ucsm-2]
ip_address = <put_ucsm_ip_address_here>
[[chassis-1]]
chassis_id = <put_the_chassis_id_here>
[[[blade-1]]]
blade_id = <put_blade_id_here>
host_name = <put_hostname_here>
[[[blade-2]]]
blade_id = <put_blade_id_here>
host_name = <put_hostname_here>

View File

@ -0,0 +1,99 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2013 OpenStack LLC
#
# 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.
#
"""cisco plugin cleanup
Revision ID: 2a6d0b51f4bb
Revises: 1d76643bcec4
Create Date: 2013-01-17 22:24:37.730466
"""
# revision identifiers, used by Alembic.
revision = '2a6d0b51f4bb'
down_revision = '1d76643bcec4'
# Change to ['*'] if this migration applies to all plugins
migration_for_plugins = [
'quantum.plugins.cisco.network_plugin.PluginV2'
]
from alembic import op
import sqlalchemy as sa
from quantum.db import migration
def upgrade(active_plugin=None, options=None):
if not migration.should_run(active_plugin, migration_for_plugins):
return
op.drop_table(u'port_bindings')
op.drop_table(u'services_bindings')
op.drop_table(u'portprofiles')
op.drop_table(u'portprofile_bindings')
def downgrade(active_plugin=None, options=None):
if not migration.should_run(active_plugin, migration_for_plugins):
return
op.create_table(
u'port_bindings',
sa.Column(u'id', sa.Integer(), autoincrement=True,
nullable=False),
sa.Column(u'port_id', sa.String(255), nullable=False),
sa.Column(u'blade_intf_dn', sa.String(255), nullable=False),
sa.Column(u'portprofile_name', sa.String(255),
nullable=True),
sa.Column(u'vlan_name', sa.String(255), nullable=True),
sa.Column(u'vlan_id', sa.Integer(), nullable=True),
sa.Column(u'qos', sa.String(255), nullable=True),
sa.Column(u'tenant_id', sa.String(255), nullable=True),
sa.Column(u'vif_id', sa.String(255), nullable=True),
sa.PrimaryKeyConstraint(u'id')
)
op.create_table(
u'service_bindings',
sa.Column(u'id', sa.Integer(), autoincrement=True,
nullable=False),
sa.Column(u'service_id', sa.String(255), nullable=True),
sa.Column(u'mnget_id', sa.String(255), nullable=True),
sa.Column(u'nbnet_id', sa.String(255), nullable=True),
sa.Column(u'sbnet_id', sa.String(255), nullable=True),
sa.PrimaryKeyConstraint(u'id')
)
op.create_table(
u'portprofiles',
sa.Column(u'uuid', sa.String(255), nullable=False),
sa.Column(u'name', sa.String(255), nullable=True),
sa.Column(u'vlan_id', sa.Integer(), nullable=True),
sa.Column(u'qos', sa.String(255), nullable=True),
sa.PrimaryKeyConstraint(u'uuid')
)
op.create_table(
u'portprofile_bindings',
sa.Column(u'id', sa.String(255), nullable=False),
sa.Column(u'tenant_id', sa.String(255), nullable=True),
sa.Column(u'port_id', sa.Integer(), nullable=True),
sa.Column(u'portprofile_id', sa.String(255), nullable=True),
sa.Column(u'portprofile_id', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['portprofile_id'], ['portprofiles.uuid'], ),
sa.ForeignKeyConstraint(['ports'], ['ports.id'], ),
sa.PrimaryKeyConstraint(u'id')
)

View File

@ -1,50 +0,0 @@
# 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: Ying Liu, Cisco Systems, Inc.
#
from quantum.plugins.cisco.common import cisco_constants as const
def get_view_builder(req):
"""get view builder """
base_url = req.application_url
return ViewBuilder(base_url)
class ViewBuilder(object):
"""
ViewBuilder for novatenant,
derived from quantum.views.networks
"""
def __init__(self, base_url):
"""
:param base_url: url of the root wsgi application
"""
self.base_url = base_url
def build_host(self, host_data):
"""Return host description."""
return dict(host_list=host_data[const.HOST_LIST])
def build_vif(self, vif_data):
"""Return VIF description."""
return dict(vif_desc=vif_data[const.VIF_DESC])
def build_result(self, result_data):
"""Return result True/False"""
return dict(result=result_data)

View File

@ -1,61 +0,0 @@
# 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: Ying Liu, Cisco Systems, Inc.
def get_view_builder(req):
"""get view builder"""
base_url = req.application_url
return ViewBuilder(base_url)
class ViewBuilder(object):
"""
ViewBuilder for Portprofile,
derived from quantum.views.networks
"""
def __init__(self, base_url):
"""
:param base_url: url of the root wsgi application
"""
self.base_url = base_url
def build(self, portprofile_data, is_detail=False):
"""Generic method used to generate a portprofile entity."""
if is_detail:
portprofile = self._build_detail(portprofile_data)
else:
portprofile = self._build_simple(portprofile_data)
return portprofile
def _build_simple(self, portprofile_data):
"""Return a simple description of a portprofile"""
return dict(portprofile=dict(id=portprofile_data['profile_id']))
def _build_detail(self, portprofile_data):
"""Return a detailed info of a portprofile."""
if (portprofile_data['assignment'] is None):
return dict(portprofile=dict(
id=portprofile_data['profile_id'],
name=portprofile_data['profile_name'],
qos_name=portprofile_data['qos_name']))
else:
return dict(portprofile=dict(
id=portprofile_data['profile_id'],
name=portprofile_data['profile_name'],
qos_name=portprofile_data['qos_name'],
assignment=portprofile_data['assignment']))

View File

@ -1,110 +0,0 @@
# 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: Ying Liu, Cisco Systems, Inc.
from webob import exc
from quantum.api import api_common as common
from quantum.api import extensions
from quantum.api.views import ports as port_view
from quantum.manager import QuantumManager
from quantum.plugins.cisco.common import cisco_faults as faults
from quantum import wsgi
class Multiport(object):
"""extension class multiport"""
def __init__(self):
pass
@classmethod
def get_name(cls):
""" Returns Ext Resource Name """
return "Cisco Multiport"
@classmethod
def get_alias(cls):
""" Returns Ext Resource Alias """
return "Cisco Multiport"
@classmethod
def get_description(cls):
""" Returns Ext Resource Description """
return "handle multiple ports in one call"
@classmethod
def get_namespace(cls):
""" Returns Ext Resource Namespace """
return "http://docs.ciscocloud.com/api/ext/multiport/v1.0"
@classmethod
def get_updated(cls):
""" Returns Ext Resource Update Time """
return "2011-08-25T13:25:27-06:00"
@classmethod
def get_resources(cls):
""" Returns Ext Resources """
parent_resource = dict(member_name="tenant",
collection_name="extensions/csco/tenants")
controller = MultiportController(QuantumManager.get_plugin())
return [extensions.ResourceExtension('multiport', controller,
parent=parent_resource)]
class MultiportController(common.QuantumController, wsgi.Controller):
""" multiport API controller
based on QuantumController """
_multiport_ops_param_list = [
{'param-name': 'net_id_list', 'required': True},
{'param-name': 'status', 'required': True},
{'param-name': 'ports_desc', 'required': True},
]
_serialization_metadata = {
"application/xml": {
"attributes": {
"multiport": ["id", "name"],
},
},
}
def __init__(self, plugin):
self._resource_name = 'multiport'
self._plugin = plugin
self.version = "1.0"
# pylint: disable-msg=E1101,W0613
def create(self, request, tenant_id):
""" Creates a new multiport for a given tenant """
try:
body = self._deserialize(request.body, request.get_content_type())
req_body = self._prepare_request_body(
body, self._multiport_ops_param_list)
req_params = req_body[self._resource_name]
except exc.HTTPError as exp:
return faults.Fault(exp)
multiports = self._plugin.create_multiport(tenant_id,
req_params['net_id_list'],
req_params['status'],
req_params['ports_desc'])
builder = port_view.get_view_builder(request, self.version)
result = [builder.build(port)['port'] for port in multiports]
return dict(ports=result)

View File

@ -1,185 +0,0 @@
# 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: Ying Liu, Cisco Systems, Inc.
from webob import exc
from quantum.api import api_common as common
from quantum.api import extensions
from quantum.common import exceptions as qexception
from quantum.extensions import _novatenant_view as novatenant_view
from quantum.manager import QuantumManager
from quantum.plugins.cisco.common import cisco_faults as faults
from quantum import wsgi
class Novatenant(object):
"""extension class Novatenant"""
def __init__(self):
pass
@classmethod
def get_name(cls):
""" Returns Ext Resource Name """
return "Cisco Nova Tenant"
@classmethod
def get_alias(cls):
""" Returns Ext Resource alias"""
return "Cisco Nova Tenant"
@classmethod
def get_description(cls):
""" Returns Ext Resource Description """
return "novatenant resource is used by nova side to invoke quantum api"
@classmethod
def get_namespace(cls):
""" Returns Ext Resource Namespace """
return "http://docs.ciscocloud.com/api/ext/novatenant/v1.0"
@classmethod
def get_updated(cls):
""" Returns Ext Resource Updated Time """
return "2011-08-09T13:25:27-06:00"
@classmethod
def get_resources(cls):
""" Returns Ext Resource """
parent_resource = dict(member_name="tenant",
collection_name="extensions/csco/tenants")
member_actions = {'schedule_host': "PUT",
'associate_port': "PUT",
'detach_port': "PUT"}
controller = NovatenantsController(QuantumManager.get_plugin())
return [extensions.ResourceExtension('novatenants', controller,
parent=parent_resource,
member_actions=member_actions)]
class NovatenantsController(common.QuantumController, wsgi.Controller):
""" Novatenant API controller
based on QuantumController """
_Novatenant_ops_param_list = [
{'param-name': 'novatenant_name', 'required': True},
]
_schedule_host_ops_param_list = [
{'param-name': 'instance_id', 'required': True},
{'param-name': 'instance_desc', 'required': True},
]
_serialization_metadata = {
"application/xml": {
"attributes": {
"novatenant": ["id", "name"],
},
},
}
def __init__(self, plugin):
self._resource_name = 'novatenant'
self._plugin = plugin
#added for cisco's extension
# pylint: disable-msg=E1101,W0613
def show(self, request, tenant_id, id):
""" Returns novatenant details for the given novatenant id """
return "novatenant is a dummy resource"
def create(self, request, tenant_id):
""" Creates a new novatenant for a given tenant """
return "novatenant is a dummy resource"
def update(self, request, tenant_id, id):
""" Updates the name for the novatenant with the given id """
return "novatenant is a dummy resource"
def delete(self, request, tenant_id, id):
""" Destroys the Novatenant with the given id """
return "novatenant is a dummy resource"
#added for cisco's extension
def schedule_host(self, request, tenant_id, id):
content_type = request.best_match_content_type()
try:
body = self._deserialize(request.body, content_type)
req_body = self._prepare_request_body(
body, self._schedule_host_ops_param_list)
req_params = req_body[self._resource_name]
except exc.HTTPError as exp:
return faults.Fault(exp)
instance_id = req_params['instance_id']
instance_desc = req_params['instance_desc']
try:
host = self._plugin.schedule_host(tenant_id,
instance_id,
instance_desc)
builder = novatenant_view.get_view_builder(request)
result = builder.build_host(host)
return result
except qexception.PortNotFound as exp:
return faults.Fault(faults.PortNotFound(exp))
def associate_port(self, request, tenant_id, id):
content_type = request.best_match_content_type()
try:
body = self._deserialize(request.body, content_type)
req_body = self._prepare_request_body(
body, self._schedule_host_ops_param_list)
req_params = req_body[self._resource_name]
except exc.HTTPError as exp:
return faults.Fault(exp)
instance_id = req_params['instance_id']
instance_desc = req_params['instance_desc']
try:
vif = self._plugin.associate_port(tenant_id,
instance_id,
instance_desc)
builder = novatenant_view.get_view_builder(request)
result = builder.build_vif(vif)
return result
except qexception.PortNotFound as exp:
return faults.Fault(faults.PortNotFound(exp))
def detach_port(self, request, tenant_id, id):
content_type = request.best_match_content_type()
try:
body = self._deserialize(request.body, content_type)
req_body = self._prepare_request_body(
body, self._schedule_host_ops_param_list)
req_params = req_body[self._resource_name]
except exc.HTTPError as exp:
return faults.Fault(exp)
instance_id = req_params['instance_id']
instance_desc = req_params['instance_desc']
try:
vif = self._plugin.detach_port(tenant_id,
instance_id,
instance_desc)
builder = novatenant_view.get_view_builder(request)
result = builder.build_result(True)
return result
except qexception.PortNotFound as exp:
return faults.Fault(faults.PortNotFound(exp))

View File

@ -1,222 +0,0 @@
# 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: Ying Liu, Cisco Systems, Inc.
from webob import exc
from quantum.api import api_common as common
from quantum.api import extensions
from quantum.common import exceptions as qexception
from quantum.extensions import _pprofiles as pprofiles_view
from quantum.manager import QuantumManager
from quantum.plugins.cisco.common import cisco_exceptions as exception
from quantum.plugins.cisco.common import cisco_faults as faults
from quantum import wsgi
class Portprofile(object):
"""extension class Portprofile"""
def __init__(self):
pass
@classmethod
def get_name(cls):
""" Returns Ext Resource Name """
return "Cisco Port Profile"
@classmethod
def get_alias(cls):
""" Returns Ext Resource alias """
return "Cisco Port Profile"
@classmethod
def get_description(cls):
""" Returns Ext Resource Description """
return "Portprofile include QoS information"
@classmethod
def get_namespace(cls):
""" Returns Ext Resource Namespace """
return "http://docs.ciscocloud.com/api/ext/portprofile/v1.0"
@classmethod
def get_updated(cls):
""" Returns Ext Resource Updated time """
return "2011-07-23T13:25:27-06:00"
@classmethod
def get_resources(cls):
""" Returns all defined resources """
parent_resource = dict(member_name="tenant",
collection_name="extensions/csco/tenants")
member_actions = {'associate_portprofile': "PUT",
'disassociate_portprofile': "PUT"}
controller = PortprofilesController(QuantumManager.get_plugin())
return [extensions.ResourceExtension('portprofiles', controller,
parent=parent_resource,
member_actions=member_actions)]
class PortprofilesController(common.QuantumController, wsgi.Controller):
""" portprofile API controller
based on QuantumController """
def __init__(self, plugin):
self._resource_name = 'portprofile'
self._plugin = plugin
self._portprofile_ops_param_list = [{
'param-name': 'portprofile_name',
'required': True}, {
'param-name': 'qos_name',
'required': True}, {
'param-name': 'assignment',
'required': False}
]
self._assignprofile_ops_param_list = [{
'param-name': 'network-id',
'required': True}, {
'param-name': 'port-id',
'required': True}
]
self._serialization_metadata = {
"application/xml": {
"attributes": {
"portprofile": ["id", "name"],
},
},
}
def index(self, request, tenant_id):
""" Returns a list of portprofile ids """
return self._items(request, tenant_id, is_detail=False)
def _items(self, request, tenant_id, is_detail):
""" Returns a list of portprofiles. """
portprofiles = self._plugin.get_all_portprofiles(tenant_id)
builder = pprofiles_view.get_view_builder(request)
result = [builder.build(portprofile, is_detail)['portprofile']
for portprofile in portprofiles]
return dict(portprofiles=result)
# pylint: disable-msg=E1101
def show(self, request, tenant_id, id):
""" Returns portprofile details for the given portprofile id """
try:
portprofile = self._plugin.get_portprofile_details(tenant_id, id)
builder = pprofiles_view.get_view_builder(request)
#build response with details
result = builder.build(portprofile, True)
return dict(portprofiles=result)
except exception.PortProfileNotFound as exp:
return faults.Fault(faults.PortprofileNotFound(exp))
def create(self, request, tenant_id):
""" Creates a new portprofile for a given tenant """
#look for portprofile name in request
try:
body = self._deserialize(request.body, request.get_content_type())
req_body = \
self._prepare_request_body(body,
self._portprofile_ops_param_list)
req_params = req_body[self._resource_name]
except exc.HTTPError as exp:
return faults.Fault(exp)
portprofile = \
self._plugin.create_portprofile(tenant_id,
req_params['portprofile_name'],
req_params['qos_name'])
builder = pprofiles_view.get_view_builder(request)
result = builder.build(portprofile)
return dict(portprofiles=result)
def update(self, request, tenant_id, id):
""" Updates the name for the portprofile with the given id """
try:
body = self._deserialize(request.body, request.get_content_type())
req_body = \
self._prepare_request_body(body,
self._portprofile_ops_param_list)
req_params = req_body[self._resource_name]
except exc.HTTPError as exp:
return faults.Fault(exp)
try:
portprofile = \
self._plugin.rename_portprofile(tenant_id, id,
req_params['portprofile_name'])
builder = pprofiles_view.get_view_builder(request)
result = builder.build(portprofile, True)
return dict(portprofiles=result)
except exception.PortProfileNotFound as exp:
return faults.Fault(faults.PortprofileNotFound(exp))
def delete(self, request, tenant_id, id):
""" Destroys the portprofile with the given id """
try:
self._plugin.delete_portprofile(tenant_id, id)
return exc.HTTPOk()
except exception.PortProfileNotFound as exp:
return faults.Fault(faults.PortprofileNotFound(exp))
def associate_portprofile(self, request, tenant_id, id):
""" associate a portprofile to the port """
content_type = request.best_match_content_type()
try:
body = self._deserialize(request.body, content_type)
req_body = \
self._prepare_request_body(body,
self._assignprofile_ops_param_list)
req_params = req_body[self._resource_name]
except exc.HTTPError as exp:
return faults.Fault(exp)
net_id = req_params['network-id'].strip()
port_id = req_params['port-id'].strip()
try:
self._plugin.associate_portprofile(tenant_id,
net_id, port_id,
id)
return exc.HTTPOk()
except exception.PortProfileNotFound as exp:
return faults.Fault(faults.PortprofileNotFound(exp))
except qexception.PortNotFound as exp:
return faults.Fault(faults.PortNotFound(exp))
def disassociate_portprofile(self, request, tenant_id, id):
""" Disassociate a portprofile from a port """
content_type = request.best_match_content_type()
try:
body = self._deserialize(request.body, content_type)
req_body = \
self._prepare_request_body(body,
self._assignprofile_ops_param_list)
req_params = req_body[self._resource_name]
except exc.HTTPError as exp:
return faults.Fault(exp)
net_id = req_params['network-id'].strip()
port_id = req_params['port-id'].strip()
try:
self._plugin.disassociate_portprofile(tenant_id,
net_id, port_id, id)
return exc.HTTPOk()
except exception.PortProfileNotFound as exp:
return faults.Fault(faults.PortprofileNotFound(exp))
except qexception.PortNotFound as exp:
return faults.Fault(faults.PortNotFound(exp))

View File

@ -35,11 +35,8 @@ PORTID = 'port_id'
PPNAME = 'name'
PPVLANID = 'vlan_id'
PPQOS = 'qos'
PPID = 'portprofile_id'
PPDEFAULT = 'default'
VLANID = 'vlan_id'
VLANNAME = 'vlan_name'
PORTPROFILENAME = 'portprofile_name'
QOS = 'qos'
ATTACHMENT = 'attachment'
@ -55,18 +52,9 @@ NET_TENANTS = 'net-tenants'
TENANT_ID = 'tenant-id'
TENANT_NETWORKS = 'tenant-networks'
TENANT_NAME = 'tenant-name'
TENANT_PORTPROFILES = 'tenant-portprofiles'
TENANT_QOS_LEVELS = 'tenant-qos-levels'
TENANT_CREDENTIALS = 'tenant-credentials'
PORT_PROFILE = 'port-profile'
PROFILE_ID = 'profile_id'
PROFILE_NAME = 'profile_name'
PROFILE_VLAN_NAME = 'profile-vlan-name'
PROFILE_VLAN_ID = 'vlan-id'
PROFILE_QOS = 'qos_name'
PROFILE_ASSOCIATIONS = 'assignment'
QOS_LEVEL_ID = 'qos_id'
QOS_LEVEL_NAME = 'qos_name'
QOS_LEVEL_ASSOCIATIONS = 'qos-level-associations'
@ -83,40 +71,12 @@ PASSWORD = 'password'
LOGGER_COMPONENT_NAME = "cisco_plugin"
BLADE_INTF_DN = "blade_intf_distinguished_name"
BLADE_INTF_ORDER = "blade-intf-order"
BLADE_INTF_LINK_STATE = "blade-intf-link-state"
BLADE_INTF_OPER_STATE = "blade-intf-operational-state"
BLADE_INTF_INST_TYPE = "blade-intf-inst-type"
BLADE_INTF_RHEL_DEVICE_NAME = "blade-intf-rhel-device-name"
BLADE_INTF_DYNAMIC = "dynamic"
BLADE_INTF_STATE_UNKNOWN = "unknown"
BLADE_INTF_STATE_UNALLOCATED = "unallocated"
BLADE_INTF_RESERVED = "blade-intf-reserved"
BLADE_INTF_UNRESERVED = "blade-intf-unreserved"
BLADE_INTF_RESERVATION = "blade-intf-reservation-status"
BLADE_UNRESERVED_INTF_COUNT = "blade-unreserved-interfaces-count"
BLADE_INTF_DATA = "blade-intf-data"
LEAST_RSVD_BLADE_UCSM = "least-reserved-blade-ucsm"
LEAST_RSVD_BLADE_CHASSIS = "least-reserved-blade-chassis"
LEAST_RSVD_BLADE_ID = "least-reserved-blade-id"
LEAST_RSVD_BLADE_DATA = "least-reserved-blade-data"
RESERVED_NIC_HOSTNAME = "reserved-dynamic-nic-hostname"
RESERVED_NIC_NAME = "reserved-dynamic-nic-device-name"
RESERVED_INTERFACE_UCSM = "reserved-interface-ucsm-ip"
RESERVED_INTERFACE_CHASSIS = "reserved-interface-chassis"
RESERVED_INTERFACE_BLADE = "reserved-interface-blade"
RESERVED_INTERFACE_DN = "reserved-interface-dn"
RHEL_DEVICE_NAME_REPFIX = "eth"
UCS_PLUGIN = 'ucs_plugin'
NEXUS_PLUGIN = 'nexus_plugin'
UCS_INVENTORY = 'ucs_inventory'
NEXUS_INVENTORY = 'nexus_inventory'
VSWITCH_PLUGIN = 'vswitch_plugin'
PLUGIN_OBJ_REF = 'plugin-obj-ref'
@ -131,7 +91,6 @@ HOST_1 = 'host_1'
VIF_DESC = 'vif_desc'
DEVICENAME = 'device'
UCSPROFILE = 'portprofile'
IP_ADDRESS = 'ip_address'
CHASSIS_ID = 'chassis_id'
@ -142,11 +101,6 @@ INSTANCE_ID = 'instance_id'
VIF_ID = 'vif_id'
PROJECT_ID = 'project_id'
UCS_INVENTORY = 'ucs_inventory'
LEAST_RSVD_BLADE_DICT = 'least_rsvd_blade_dict'
UCSM_IP = 'ucsm_ip_address'
NETWORK_ADMIN = 'network_admin'
NETID_LIST = 'net_id_list'

View File

@ -30,62 +30,18 @@ class NoMoreNics(exceptions.QuantumException):
"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 MultiportNotFound(exceptions.QuantumException):
"""Multiport cannot be found"""
message = _("Multiports %(port_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)s 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)s already exists")
class VlanIDNotFound(exceptions.QuantumException):
"""VLAN ID cannot be found"""
message = _("Vlan ID %(vlan_id)s not found")

View File

@ -27,8 +27,6 @@ class Fault(webob.exc.HTTPException):
_fault_names = {
400: "malformedRequest",
401: "unauthorized",
421: "PortprofileInUse",
450: "PortprofileNotFound",
451: "CredentialNotFound",
452: "QoSNotFound",
453: "NovatenantNotFound",
@ -60,21 +58,6 @@ class Fault(webob.exc.HTTPException):
return self.wrapped_exc
class PortprofileNotFound(webob.exc.HTTPClientError):
"""
subclass of :class:`~HTTPClientError`
This indicates that the server did not find the Portprofile specified
in the HTTP request
code: 450, title: Portprofile not Found
"""
code = 450
title = _('Portprofile Not Found')
explanation = _('Unable to find a Portprofile with'
' the specified identifier.')
class PortNotFound(webob.exc.HTTPClientError):
"""
subclass of :class:`~HTTPClientError`
@ -134,21 +117,6 @@ class NovatenantNotFound(webob.exc.HTTPClientError):
' the specified identifier.')
class MultiportNotFound(webob.exc.HTTPClientError):
"""
subclass of :class:`~HTTPClientError`
This indicates that the server did not find the Multiport specified
in the HTTP request
code: 454, title: Multiport not Found
"""
code = 454
title = _('Multiport Not Found')
explanation = _('Unable to find Multiport with'
' the specified identifier.')
class RequestedStateInvalid(webob.exc.HTTPClientError):
"""
subclass of :class:`~HTTPClientError`

View File

@ -47,26 +47,3 @@ def make_port_dict(port_id, port_state, net_id, attachment):
res[const.NET_ID] = net_id
res[const.ATTACHMENT] = attachment
return res
def make_portprofile_dict(tenant_id, profile_id,
profile_name, qos):
"""Helper funciton"""
profile_associations = make_portprofile_assc_list(tenant_id,
profile_id)
res = {const.PROFILE_ID: str(profile_id),
const.PROFILE_NAME: profile_name,
const.PROFILE_ASSOCIATIONS: profile_associations,
const.PROFILE_VLAN_ID: None,
const.PROFILE_QOS: qos}
return res
def make_portprofile_assc_list(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

View File

@ -18,19 +18,20 @@
from sqlalchemy.orm import exc
from quantum.common import exceptions as q_exc
from quantum.openstack.common import log as logging
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
from quantum.plugins.cisco.db import l2network_models
from quantum.plugins.cisco import l2network_plugin_configuration as conf
import logging as LOG
import quantum.plugins.cisco.db.api as db
LOG = logging.getLogger(__name__)
def initialize():
'Establish database connection and load models'
options = {"sql_connection": "mysql://%s:%s@%s/%s" % (conf.DB_USER,
conf.DB_PASS, conf.DB_HOST, conf.DB_NAME)}
db.configure_db(options)
"""Establish database connection and load models"""
db.configure_db()
def create_vlanids():
@ -207,159 +208,6 @@ def update_vlan_binding(netid, newvlanid=None, newvlanname=None):
raise q_exc.NetworkNotFound(net_id=netid)
def get_all_portprofiles():
"""Lists all the port profiles"""
LOG.debug(_("get_all_portprofiles() called"))
session = db.get_session()
try:
pps = session.query(l2network_models.PortProfile).all()
return pps
except exc.NoResultFound:
return []
def get_portprofile(tenantid, ppid):
"""Lists a port profile"""
LOG.debug(_("get_portprofile() called"))
session = db.get_session()
try:
pp = (session.query(l2network_models.PortProfile).
filter_by(uuid=ppid).one())
return pp
except exc.NoResultFound:
raise c_exc.PortProfileNotFound(tenant_id=tenantid,
portprofile_id=ppid)
def add_portprofile(tenantid, ppname, vlanid, qos):
"""Adds a port profile"""
LOG.debug(_("add_portprofile() called"))
session = db.get_session()
try:
pp = (session.query(l2network_models.PortProfile).
filter_by(name=ppname).one())
raise c_exc.PortProfileAlreadyExists(tenant_id=tenantid,
pp_name=ppname)
except exc.NoResultFound:
pp = l2network_models.PortProfile(ppname, vlanid, qos)
session.add(pp)
session.flush()
return pp
def remove_portprofile(tenantid, ppid):
"""Removes a port profile"""
LOG.debug(_("remove_portprofile() called"))
session = db.get_session()
try:
pp = (session.query(l2network_models.PortProfile).
filter_by(uuid=ppid).one())
session.delete(pp)
session.flush()
return pp
except exc.NoResultFound:
pass
def update_portprofile(tenantid, ppid, newppname=None, newvlanid=None,
newqos=None):
"""Updates port profile"""
LOG.debug(_("update_portprofile() called"))
session = db.get_session()
try:
pp = (session.query(l2network_models.PortProfile).
filter_by(uuid=ppid).one())
if newppname:
pp["name"] = newppname
if newvlanid:
pp["vlan_id"] = newvlanid
if newqos:
pp["qos"] = newqos
session.merge(pp)
session.flush()
return pp
except exc.NoResultFound:
raise c_exc.PortProfileNotFound(tenant_id=tenantid,
portprofile_id=ppid)
def get_all_pp_bindings():
"""Lists all the port profiles"""
LOG.debug(_("get_all_pp_bindings() called"))
session = db.get_session()
try:
bindings = session.query(l2network_models.PortProfileBinding).all()
return bindings
except exc.NoResultFound:
return []
def get_pp_binding(tenantid, ppid):
"""Lists a port profile binding"""
LOG.debug(_("get_pp_binding() called"))
session = db.get_session()
try:
binding = (session.query(l2network_models.PortProfileBinding).
filter_by(portprofile_id=ppid).one())
return binding
except exc.NoResultFound:
return []
def add_pp_binding(tenantid, portid, ppid, default):
"""Adds a port profile binding"""
LOG.debug(_("add_pp_binding() called"))
session = db.get_session()
try:
binding = (session.query(l2network_models.PortProfileBinding).
filter_by(portprofile_id=ppid).one())
raise c_exc.PortProfileBindingAlreadyExists(pp_id=ppid,
port_id=portid)
except exc.NoResultFound:
binding = l2network_models.PortProfileBinding(tenantid, portid,
ppid, default)
session.add(binding)
session.flush()
return binding
def remove_pp_binding(tenantid, portid, ppid):
"""Removes a port profile binding"""
LOG.debug(_("remove_pp_binding() called"))
session = db.get_session()
try:
binding = (session.query(l2network_models.PortProfileBinding).
filter_by(portprofile_id=ppid).filter_by(port_id=portid).
one())
session.delete(binding)
session.flush()
return binding
except exc.NoResultFound:
pass
def update_pp_binding(tenantid, ppid, newtenantid=None,
newportid=None, newdefault=None):
"""Updates port profile binding"""
LOG.debug(_("update_pp_binding() called"))
session = db.get_session()
try:
binding = (session.query(l2network_models.PortProfileBinding).
filter_by(portprofile_id=ppid).one())
if newtenantid:
binding["tenant_id"] = newtenantid
if newportid:
binding["port_id"] = newportid
if newdefault:
binding["default"] = newdefault
session.merge(binding)
session.flush()
return binding
except exc.NoResultFound:
raise c_exc.PortProfileNotFound(tenant_id=tenantid,
portprofile_id=ppid)
def get_all_qoss(tenant_id):
"""Lists all the qos to tenant associations"""
LOG.debug(_("get_all_qoss() called"))

View File

@ -99,55 +99,6 @@ class VlanBinding(BASE, L2NetworkBase):
self.network_id)
class PortProfile(BASE, L2NetworkBase):
"""Represents L2 network plugin level PortProfile for a network"""
__tablename__ = 'portprofiles'
uuid = Column(String(255), primary_key=True)
name = Column(String(255))
vlan_id = Column(Integer)
qos = Column(String(255))
def __init__(self, name, vlan_id, qos=None):
self.uuid = uuidutils.generate_uuid()
self.name = name
self.vlan_id = vlan_id
self.qos = qos
def __repr__(self):
return "<PortProfile(%s,%s,%d,%s)>" % (self.uuid,
self.name,
self.vlan_id,
self.qos)
class PortProfileBinding(BASE, L2NetworkBase):
"""Represents PortProfile binding to tenant and network"""
__tablename__ = 'portprofile_bindings'
id = Column(Integer, primary_key=True, autoincrement=True)
tenant_id = Column(String(255))
port_id = Column(String(255), ForeignKey("ports.uuid"), nullable=False)
portprofile_id = Column(String(255), ForeignKey("portprofiles.uuid"),
nullable=False)
default = Column(Boolean)
ports = relation(models.Port)
portprofile = relation(PortProfile, uselist=False)
def __init__(self, tenant_id, port_id, portprofile_id, default):
self.tenant_id = tenant_id
self.port_id = port_id
self.portprofile_id = portprofile_id
self.default = default
def __repr__(self):
return "<PortProfile Binding(%s,%s,%s,%s)>" % (self.tenant_id,
self.port_id,
self.portprofile_id,
self.default)
class QoS(BASE, L2NetworkBase):
"""Represents QoS for a tenant"""
__tablename__ = 'qoss'

View File

@ -16,24 +16,24 @@
#
# @author: Rohit Agarwalla, Cisco Systems, Inc.
import logging as LOG
from sqlalchemy.orm import exc
from quantum.common import exceptions as q_exc
from quantum.db import api as db
from quantum.openstack.common import log as logging
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
from quantum.plugins.cisco.db import network_models_v2
from quantum.plugins.cisco.db import ucs_models_v2
from quantum.plugins.cisco.db import nexus_models_v2
from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.plugins.openvswitch import ovs_models_v2
LOG = logging.getLogger(__name__)
def initialize():
'Establish database connection and load models'
sql_connection = "mysql://%s:%s@%s/%s" % (conf.DB_USER, conf.DB_PASS,
conf.DB_HOST, conf.DB_NAME)
db.configure_db({'sql_connection': sql_connection,
'base': network_models_v2.model_base.BASEV2})
"""Establish database connection and load models"""
db.configure_db()
def create_vlanids():
@ -210,159 +210,6 @@ def update_vlan_binding(netid, newvlanid=None, newvlanname=None):
raise q_exc.NetworkNotFound(net_id=netid)
def get_all_portprofiles():
"""Lists all the port profiles"""
LOG.debug(_("get_all_portprofiles() called"))
session = db.get_session()
try:
pps = session.query(network_models_v2.PortProfile).all()
return pps
except exc.NoResultFound:
return []
def get_portprofile(tenantid, ppid):
"""Lists a port profile"""
LOG.debug(_("get_portprofile() called"))
session = db.get_session()
try:
pp = (session.query(network_models_v2.PortProfile).
filter_by(uuid=ppid).one())
return pp
except exc.NoResultFound:
raise c_exc.PortProfileNotFound(tenant_id=tenantid,
portprofile_id=ppid)
def add_portprofile(tenantid, ppname, vlanid, qos):
"""Adds a port profile"""
LOG.debug(_("add_portprofile() called"))
session = db.get_session()
try:
pp = (session.query(network_models_v2.PortProfile).
filter_by(name=ppname).one())
raise c_exc.PortProfileAlreadyExists(tenant_id=tenantid,
pp_name=ppname)
except exc.NoResultFound:
pp = network_models_v2.PortProfile(ppname, vlanid, qos)
session.add(pp)
session.flush()
return pp
def remove_portprofile(tenantid, ppid):
"""Removes a port profile"""
LOG.debug("remove_portprofile() called")
session = db.get_session()
try:
pp = (session.query(network_models_v2.PortProfile).
filter_by(uuid=ppid).one())
session.delete(pp)
session.flush()
return pp
except exc.NoResultFound:
pass
def update_portprofile(tenantid, ppid, newppname=None, newvlanid=None,
newqos=None):
"""Updates port profile"""
LOG.debug(_("update_portprofile() called"))
session = db.get_session()
try:
pp = (session.query(network_models_v2.PortProfile).
filter_by(uuid=ppid).one())
if newppname:
pp["name"] = newppname
if newvlanid:
pp["vlan_id"] = newvlanid
if newqos:
pp["qos"] = newqos
session.merge(pp)
session.flush()
return pp
except exc.NoResultFound:
raise c_exc.PortProfileNotFound(tenant_id=tenantid,
portprofile_id=ppid)
def get_all_pp_bindings():
"""Lists all the port profiles"""
LOG.debug(_("get_all_pp_bindings() called"))
session = db.get_session()
try:
bindings = session.query(network_models_v2.PortProfileBinding).all()
return bindings
except exc.NoResultFound:
return []
def get_pp_binding(tenantid, ppid):
"""Lists a port profile binding"""
LOG.debug(_("get_pp_binding() called"))
session = db.get_session()
try:
binding = (session.query(network_models_v2.PortProfileBinding).
filter_by(portprofile_id=ppid).one())
return binding
except exc.NoResultFound:
return []
def add_pp_binding(tenantid, portid, ppid, default):
"""Adds a port profile binding"""
LOG.debug(_("add_pp_binding() called"))
session = db.get_session()
try:
binding = (session.query(network_models_v2.PortProfileBinding).
filter_by(portprofile_id=ppid).one())
raise c_exc.PortProfileBindingAlreadyExists(pp_id=ppid,
port_id=portid)
except exc.NoResultFound:
binding = network_models_v2.PortProfileBinding(tenantid, portid,
ppid, default)
session.add(binding)
session.flush()
return binding
def remove_pp_binding(tenantid, portid, ppid):
"""Removes a port profile binding"""
LOG.debug(_("remove_pp_binding() called"))
session = db.get_session()
try:
binding = (session.query(network_models_v2.PortProfileBinding).
filter_by(portprofile_id=ppid).filter_by(port_id=portid).
one())
session.delete(binding)
session.flush()
return binding
except exc.NoResultFound:
pass
def update_pp_binding(tenantid, ppid, newtenantid=None,
newportid=None, newdefault=None):
"""Updates port profile binding"""
LOG.debug(_("update_pp_binding() called"))
session = db.get_session()
try:
binding = (session.query(network_models_v2.PortProfileBinding).
filter_by(portprofile_id=ppid).one())
if newtenantid:
binding["tenant_id"] = newtenantid
if newportid:
binding["port_id"] = newportid
if newdefault:
binding["default"] = newdefault
session.merge(binding)
session.flush()
return binding
except exc.NoResultFound:
raise c_exc.PortProfileNotFound(tenant_id=tenantid,
portprofile_id=ppid)
def get_all_qoss(tenant_id):
"""Lists all the qos to tenant associations"""
LOG.debug(_("get_all_qoss() called"))

View File

@ -100,55 +100,6 @@ class Vlan_Binding(model_base.BASEV2, L2NetworkBase):
self.network_id)
class PortProfile(model_base.BASEV2, L2NetworkBase):
"""Represents L2 network plugin level PortProfile for a network"""
__tablename__ = 'portprofiles'
uuid = Column(String(255), primary_key=True)
name = Column(String(255))
vlan_id = Column(Integer)
qos = Column(String(255))
def __init__(self, name, vlan_id, qos=None):
self.uuid = uuidutils.generate_uuid()
self.name = name
self.vlan_id = vlan_id
self.qos = qos
def __repr__(self):
return "<PortProfile(%s,%s,%d,%s)>" % (self.uuid,
self.name,
self.vlan_id,
self.qos)
class PortProfileBinding(model_base.BASEV2, L2NetworkBase):
"""Represents PortProfile binding to tenant and network"""
__tablename__ = 'portprofile_bindings'
id = Column(Integer, primary_key=True, autoincrement=True)
tenant_id = Column(String(255))
port_id = Column(String(255), ForeignKey("ports.id"), nullable=False)
portprofile_id = Column(String(255), ForeignKey("portprofiles.uuid"),
nullable=False)
default = Column(Boolean)
ports = relation(models.Port)
portprofile = relation(PortProfile, uselist=False)
def __init__(self, tenant_id, port_id, portprofile_id, default):
self.tenant_id = tenant_id
self.port_id = port_id
self.portprofile_id = portprofile_id
self.default = default
def __repr__(self):
return "<PortProfile Binding(%s,%s,%s,%s)>" % (self.tenant_id,
self.port_id,
self.portprofile_id,
self.default)
class QoS(model_base.BASEV2, L2NetworkBase):
"""Represents QoS for a tenant"""
__tablename__ = 'qoss'

View File

@ -29,6 +29,11 @@ from quantum.plugins.cisco.db import nexus_models_v2
LOG = logging.getLogger(__name__)
def initialize():
"""Establish database connection and load models"""
db.configure_db()
def get_all_nexusport_bindings():
"""Lists all the nexusport bindings"""
LOG.debug(_("get_all_nexusport_bindings() called"))

View File

@ -1,42 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011, Cisco Systems, Inc.
#
# 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: Edgar Magana, Cisco Systems, Inc.
from sqlalchemy import Column, Integer, String
from quantum.plugins.cisco.db.l2network_models import L2NetworkBase
from quantum.plugins.cisco.db.models import BASE
class ServicesBinding(BASE, L2NetworkBase):
"""Represents a binding of L2 services to networks"""
__tablename__ = 'services_bindings'
id = Column(Integer, primary_key=True, autoincrement=True)
service_id = Column(String(255))
mngnet_id = Column(String(255))
nbnet_id = Column(String(255))
sbnet_id = Column(String(255))
def __init__(self, service_id, mngnet_id, nbnet_id, sbnet_id):
self.service_id = service_id
self.mngnet_id = mngnet_id
self.nbnet_id = nbnet_id
self.sbnet_id = sbnet_id
def __repr__(self):
return "<ServicesBinding (%s,%d)>" % (self.service_id, self.mngnet_id,
self.nbnet_id, self.sbnet_id)

View File

@ -1,51 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012, Cisco Systems, Inc.
#
# 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: Rohit Agarwalla, Cisco Systems, Inc.
from sqlalchemy import Column, Integer, String
from quantum.db.model_base import BASEV2 as BASE
from quantum.plugins.cisco.db.network_models_v2 import L2NetworkBase
class PortBinding(BASE, L2NetworkBase):
"""Represents Port binding to device interface"""
__tablename__ = 'port_bindings'
id = Column(Integer, primary_key=True, autoincrement=True)
port_id = Column(String(255), nullable=False)
blade_intf_dn = Column(String(255), nullable=False)
portprofile_name = Column(String(255))
vlan_name = Column(String(255))
vlan_id = Column(Integer)
qos = Column(String(255))
tenant_id = Column(String(255))
instance_id = Column(String(255))
vif_id = Column(String(255))
def __init__(self, port_id, blade_intf_dn, portprofile_name,
vlan_name, vlan_id, qos):
self.port_id = port_id
self.blade_intf_dn = blade_intf_dn
self.portprofile_name = portprofile_name
self.vlan_name = vlan_name
self.vlan_id = vlan_id
self.qos = qos
def __repr__(self):
return "<PortProfile Binding(%s,%s,%s,%s,%s,%s)>" % (
self.port_id, self.blade_intf_dn, self.portprofile_name,
self.vlan_name, self.vlan_id, self.qos)

View File

@ -1,340 +0,0 @@
# 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.
from abc import ABCMeta, abstractmethod
import inspect
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 update_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

View File

@ -34,9 +34,6 @@ VLAN_END = SECTION_CONF['vlan_end']
SECTION_CONF = CONF_PARSER_OBJ['PORTS']
MAX_PORTS = SECTION_CONF['max_ports']
SECTION_CONF = CONF_PARSER_OBJ['PORTPROFILES']
MAX_PORT_PROFILES = SECTION_CONF['max_port_profiles']
SECTION_CONF = CONF_PARSER_OBJ['NETWORKS']
MAX_NETWORKS = SECTION_CONF['max_networks']

View File

@ -1,72 +0,0 @@
# 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.
from abc import ABCMeta, abstractmethod
import inspect
class L2NetworkSegmentationMgrBase(object):
"""
Base class for L2 Network Segmentation Manager
"""
__metaclass__ = ABCMeta
@abstractmethod
def reserve_segmentation_id(self, tenant_id, net_name, **kwargs):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def release_segmentation_id(self, tenant_id, net_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 L2NetworkSegmentationMgrBase:
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

View File

@ -38,9 +38,7 @@ class PluginV2(db_base_plugin_v2.QuantumDbPluginV2):
"""
Meta-Plugin with v2 API support for multiple sub-plugins.
"""
supported_extension_aliases = ["Cisco Credential", "Cisco Port Profile",
"Cisco qos", "Cisco Nova Tenant",
"Cisco Multiport"]
supported_extension_aliases = ["Cisco Credential", "Cisco qos"]
_methods_to_delegate = ['create_network', 'create_network_bulk',
'delete_network', 'update_network', 'get_network',
'get_networks',
@ -275,101 +273,6 @@ class PluginV2(db_base_plugin_v2.QuantumDbPluginV2):
"""
Extension API implementation
"""
def get_all_portprofiles(self, tenant_id):
"""Get all port profiles"""
LOG.debug(_("get_all_portprofiles() called"))
pplist = cdb.get_all_portprofiles()
new_pplist = []
for portprofile in pplist:
new_pp = cutil.make_portprofile_dict(tenant_id,
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):
"""Get port profile details"""
LOG.debug(_("get_portprofile_details() called"))
try:
portprofile = cdb.get_portprofile(tenant_id, profile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=profile_id)
new_pp = cutil.make_portprofile_dict(tenant_id,
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
return new_pp
def create_portprofile(self, tenant_id, profile_name, qos):
"""Create port profile"""
LOG.debug(_("create_portprofile() called"))
portprofile = cdb.add_portprofile(tenant_id, profile_name,
const.NO_VLAN_ID, qos)
new_pp = cutil.make_portprofile_dict(tenant_id,
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
return new_pp
def delete_portprofile(self, tenant_id, profile_id):
"""Delete portprofile"""
LOG.debug(_("delete_portprofile() called"))
try:
portprofile = cdb.get_portprofile(tenant_id, profile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=profile_id)
plist = cdb.get_pp_binding(tenant_id, profile_id)
if plist:
raise cexc.PortProfileInvalidDelete(tenant_id=tenant_id,
profile_id=profile_id)
else:
cdb.remove_portprofile(tenant_id, profile_id)
def rename_portprofile(self, tenant_id, profile_id, new_name):
"""Rename port profile"""
LOG.debug(_("rename_portprofile() called"))
try:
portprofile = cdb.get_portprofile(tenant_id, profile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=profile_id)
portprofile = cdb.update_portprofile(tenant_id, profile_id, new_name)
new_pp = cutil.make_portprofile_dict(tenant_id,
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"""
LOG.debug(_("associate_portprofile() called"))
try:
portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=portprofile_id)
cdb.add_pp_binding(tenant_id, port_id, portprofile_id, False)
def disassociate_portprofile(self, tenant_id, net_id,
port_id, portprofile_id):
"""Disassociate port profile"""
LOG.debug(_("disassociate_portprofile() called"))
try:
portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=portprofile_id)
cdb.remove_pp_binding(tenant_id, port_id, portprofile_id)
def get_all_qoss(self, tenant_id):
"""Get all QoS levels"""
LOG.debug(_("get_all_qoss() called"))
@ -486,28 +389,6 @@ class PluginV2(db_base_plugin_v2.QuantumDbPluginV2):
instance_id,
instance_desc])
def create_multiport(self, tenant_id, net_id_list, port_state, ports_desc):
"""
Creates multiple ports on the specified Virtual Network.
"""
LOG.debug(_("create_ports() called"))
ports_num = len(net_id_list)
ports_id_list = []
ports_dict_list = []
for net_id in net_id_list:
db.validate_network_ownership(tenant_id, net_id)
port = db.port_create(net_id, port_state)
ports_id_list.append(port[const.UUID])
port_dict = {const.PORT_ID: port[const.UUID]}
ports_dict_list.append(port_dict)
self._invoke_device_plugins(self._func_name(), [tenant_id,
net_id_list,
ports_num,
ports_id_list])
return ports_dict_list
"""
Private functions
"""

View File

@ -47,6 +47,8 @@ class NexusPlugin(L2DevicePluginBase):
"""
Extracts the configuration parameters from the configuration file
"""
# Initialize the nxos db
nxos_db.initialize()
self._client = importutils.import_object(conf.NEXUS_DRIVER)
LOG.debug(_("Loaded driver %s"), conf.NEXUS_DRIVER)
self._nexus_switches = conf.NEXUS_DETAILS

View File

@ -1,18 +0,0 @@
# 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.
#

View File

@ -1,52 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 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 logging
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.db import network_db_v2 as cdb
from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.plugins.cisco.l2network_segmentation_base import (
L2NetworkSegmentationMgrBase,
)
LOG = logging.getLogger(__name__)
class L2NetworkVLANMgr(L2NetworkSegmentationMgrBase):
"""
VLAN Manager which gets VLAN ID from DB
"""
def __init__(self):
cdb.create_vlanids()
def reserve_segmentation_id(self, tenant_id, net_name, **kwargs):
"""Get an available VLAN ID"""
return cdb.reserve_vlanid()
def release_segmentation_id(self, tenant_id, net_id, **kwargs):
"""Release the ID"""
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

View File

@ -1,70 +0,0 @@
=========================================================================================
README: L2 Network Services Insertion Utility
=========================================================================================
:Authors: Edgar Magana, Mani Ramasamy, Ram Durairaj
:Collaborators: Deepak Khanorkar, Sumit Naiksatam, Nat Chidambaram, Dan Wendlandt
:Contact: netstack@lists.launchpad.net
:Web site: https://blueprints.launchpad.net/quantum/+spec/services-insertion-wrapper
Introduction
------------
This utility offers a simplify way to insert and remove network services
in the path of the traffic to the server VMs, by splitting the network into two,
and having the service bridge between the two, in the process applying the service.
This model is called In-Path (Bump in the Wire)
Pre-requisites
--------------
This integration uses Quantum APIs offered on diablo realease and Nova compute
functionality, basically to create new service instances.
Instructions
------------------------------------------------------
This utility offer four functionalities:
1. insert_inpath_service <tenant_id> <service_image_id>
<management_net_name> <northbound_net_name> <southbound_net_name>
Creates two networks and insert a service vm between them bridging the traffic
path. It also creates a management network to access the service configuration.
2. delete_service <tenant_id> <service_instance_id>
Deletes the service prevopusly inserted as well as the network dependencies.
connect_vm <tenant_id> <vm_image_id> <service_instance_id>
Instanciate a VM which is connected to the southbound network created by
insert_inpath_service. Facilitates the connections of server vms into the
tenant's network.
4. disconnect_vm <vm_instance_id>
Disconnect from the southbound network and terminates the server vm.
Example
------------------------------------------------------
Let's insert a Firewall service between northbound and southbound networks,
the management network will be called mng_net:
#PYTHONPATH=. python quantum/services/service_insertion.py insert_inpath_service
naas ami-00000029 mng_net northnet southnet
"ami-00000029" is the reference id provided by Glance for the Firewall image
service instance id: i-00000091
Now, we can connect a fresh web server in to the southbound network with:
#PYTHONPATH=. python quantum/services/service_insertion.py connect_vm
naas ami-0000002b i-00000091
"ami-0000002b" is the reference id provided by Glace for the Web Server image
and "i-00000091" is the instance id provided by Nova for the FW service instance
previously created.
server instance id: i-00000092
If we want to disconnect and shutdown the vm instance server:
#PYTHONPATH=. python quantum/plugins/cisco/services/service_insertion.py disconnect_vm i-00000092
We can delete the service instance and the network configuration with:
#PYTHONPATH=. python quantum/plugins/cisco/services/service_insertion.py delete_service naas i-00000091
Caveats
------------------------------------------------------
nova-compute service should be running in the same server that Quantum.
Nova API calls will be implemented in the next release (essex-3)

View File

@ -1,19 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack LLC
#
# 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: Edgar Magana, Cisco Systems
"""
L2 Network Services Insertion Utility
"""

View File

@ -1,34 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack LLC
#
# 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: Edgar Magana, Cisco Systems
#
"""
Services Constants for the Services insertion Library
"""
FORMAT = 'json'
ACTION_PREFIX_EXT = '/v1.0'
ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + '/extensions/csco/tenants/{tenant_id}'
NETWORK = 'network'
ID = 'id'
PORTS = 'ports'
PORT = 'port'
NAME = 'name'
ATTACHMENT = 'attachment'
CREATE_VM_CMD = '/usr/bin/euca-run-instances'
DELETE_VM_CMD = '/usr/bin/euca-terminate-instances'
DESCRIBE_VM_CMD = '/usr/bin/euca-describe-instances'

View File

@ -35,9 +35,6 @@ from quantum.api.extensions import (
from quantum.common import config
from quantum.extensions import (
credential,
multiport,
novatenant,
portprofile,
qos,
)
from quantum.manager import QuantumManager
@ -77,266 +74,6 @@ class ExtensionsTestApp(wsgi.Router):
controller=controller)
super(ExtensionsTestApp, self).__init__(mapper)
class PortprofileExtensionTest(unittest.TestCase):
def setUp(self):
""" Set up function """
parent_resource = dict(member_name="tenant",
collection_name="extensions/csco/tenants")
member_actions = {'associate_portprofile': "PUT",
'disassociate_portprofile': "PUT"}
controller = portprofile.PortprofilesController(
QuantumManager.get_plugin())
res_ext = extensions.ResourceExtension('portprofiles', controller,
parent=parent_resource,
member_actions=member_actions)
self.test_app = setup_extensions_test_app(
SimpleExtensionManager(res_ext))
self.contenttype = 'application/json'
self.profile_path = '/extensions/csco/tenants/tt/portprofiles'
self.portprofile_path = '/extensions/csco/tenants/tt/portprofiles/'
self.test_port_profile = {
'portprofile': {
'portprofile_name': 'cisco_test_portprofile',
'qos_name': 'test-qos1',
},
}
self.tenant_id = "test_tenant"
self.network_name = "test_network"
self.api = server.APIRouterV10()
self._l2network_plugin = l2network_plugin.L2Network()
def test_list_portprofile(self):
""" Test List Portprofile"""
LOG.debug("test_list_portprofile - START")
req_body1 = jsonutils.dumps(self.test_port_profile)
create_response1 = self.test_app.post(
self.profile_path, req_body1,
content_type=self.contenttype
)
req_body2 = jsonutils.dumps({
'portprofile': {
'portprofile_name': 'cisco_test_portprofile2',
'qos_name': 'test-qos2',
},
})
create_response2 = self.test_app.post(
self.profile_path, req_body2,
content_type=self.contenttype)
index_response = self.test_app.get(self.profile_path)
index_resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
self.assertEqual(200, index_response.status_int)
resp_body1 = wsgi.Serializer().deserialize(create_response1.body,
self.contenttype)
portprofile_path1_temp = (
self.portprofile_path +
resp_body1['portprofiles']['portprofile']['id'])
portprofile_path1 = str(portprofile_path1_temp)
resp_body2 = wsgi.Serializer().deserialize(create_response2.body,
self.contenttype)
list_all_portprofiles = [resp_body1['portprofiles']['portprofile'],
resp_body2['portprofiles']['portprofile']]
self.assertTrue(index_resp_body['portprofiles'][0] in
list_all_portprofiles)
self.assertTrue(index_resp_body['portprofiles'][1] in
list_all_portprofiles)
portprofile_path2_temp = (
self.portprofile_path +
resp_body2['portprofiles']['portprofile']['id'])
portprofile_path2 = str(portprofile_path2_temp)
# Clean Up - Delete the Port Profiles
self.tear_down_profile(portprofile_path1)
self.tear_down_profile(portprofile_path2)
LOG.debug("test_list_portprofile - END")
def test_create_portprofile(self):
""" Test create Portprofile"""
LOG.debug("test_create_portprofile - START")
req_body = jsonutils.dumps(self.test_port_profile)
index_response = self.test_app.post(self.profile_path, req_body,
content_type=self.contenttype)
self.assertEqual(200, index_response.status_int)
# Clean Up - Delete the Port Profile
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
portprofile_path_temp = (
self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'])
portprofile_path = str(portprofile_path_temp)
self.tear_down_profile(portprofile_path)
LOG.debug("test_create_portprofile - END")
def test_create_portprofileBADRequest(self):
""" Test create Portprofile Bad Request"""
LOG.debug("test_create_portprofileBADRequest - START")
index_response = self.test_app.post(self.profile_path, 'BAD_REQUEST',
content_type=self.contenttype,
status='*')
self.assertEqual(400, index_response.status_int)
LOG.debug("test_create_portprofileBADRequest - END")
def test_show_portprofile(self):
""" Test show Portprofile """
LOG.debug("test_show_portprofile - START")
req_body = jsonutils.dumps(self.test_port_profile)
index_response = self.test_app.post(self.profile_path, req_body,
content_type=self.contenttype)
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
show_path_temp = (self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'])
show_port_path = str(show_path_temp)
show_response = self.test_app.get(show_port_path)
show_resp_dict = wsgi.Serializer().deserialize(show_response.body,
self.contenttype)
self.assertEqual(
show_resp_dict['portprofiles']['portprofile']['qos_name'],
self.test_port_profile['portprofile']['qos_name'])
self.assertEqual(
show_resp_dict['portprofiles']['portprofile']['name'],
self.test_port_profile['portprofile']['portprofile_name'])
self.assertEqual(200, show_response.status_int)
# Clean Up - Delete the Port Profile
self.tear_down_profile(show_port_path)
LOG.debug("test_show_portprofile - END")
def test_show_portprofileDNE(self, portprofile_id='100'):
""" Test show Portprofile does not exist"""
LOG.debug("test_show_portprofileDNE - START")
show_path_temp = self.portprofile_path + portprofile_id
show_port_path = str(show_path_temp)
show_response = self.test_app.get(show_port_path, status='*')
self.assertEqual(450, show_response.status_int)
LOG.debug("test_show_portprofileDNE - END")
def test_update_portprofile(self):
""" Test update Portprofile"""
LOG.debug("test_update_portprofile - START")
req_body = jsonutils.dumps(self.test_port_profile)
index_response = self.test_app.post(
self.profile_path, req_body,
content_type=self.contenttype)
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
rename_port_profile = {
'portprofile': {
'portprofile_name': 'cisco_rename_portprofile',
'qos_name': 'test-qos1',
},
}
rename_req_body = jsonutils.dumps(rename_port_profile)
rename_path_temp = (self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'])
rename_path = str(rename_path_temp)
rename_response = self.test_app.put(rename_path, rename_req_body,
content_type=self.contenttype)
rename_resp_dict = wsgi.Serializer().deserialize(rename_response.body,
self.contenttype)
self.assertEqual(
rename_resp_dict['portprofiles']['portprofile']['qos_name'],
self.test_port_profile['portprofile']['qos_name'])
self.assertEqual(
rename_resp_dict['portprofiles']['portprofile']['name'],
rename_port_profile['portprofile']['portprofile_name'])
self.assertEqual(200, rename_response.status_int)
# Clean Up - Delete the Port Profile
self.tear_down_profile(rename_path)
LOG.debug("test_update_portprofile - END")
def test_update_portprofileBADRequest(self):
""" Test update Portprofile Bad Request"""
LOG.debug("test_update_portprofileBADRequest - START")
req_body = jsonutils.dumps(self.test_port_profile)
index_response = self.test_app.post(
self.profile_path, req_body,
content_type=self.contenttype)
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
rename_path_temp = (self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'])
rename_path = str(rename_path_temp)
rename_response = self.test_app.put(rename_path, 'BAD_REQUEST',
status='*')
self.assertEqual(400, rename_response.status_int)
# Clean Up - Delete the Port Profile
self.tear_down_profile(rename_path)
LOG.debug("test_update_portprofileBADRequest - END")
def test_update_portprofileDNE(self, portprofile_id='100'):
""" Test update Portprofile does not exist"""
LOG.debug("test_update_portprofileiDNE - START")
rename_port_profile = {
'portprofile': {
'portprofile_name': 'cisco_rename_portprofile',
'qos_name': 'test-qos1',
},
}
rename_req_body = jsonutils.dumps(rename_port_profile)
update_path_temp = self.portprofile_path + portprofile_id
update_path = str(update_path_temp)
update_response = self.test_app.put(update_path, rename_req_body,
content_type=self.contenttype,
status='*')
self.assertEqual(450, update_response.status_int)
LOG.debug("test_update_portprofileDNE - START")
def test_delete_portprofile(self):
""" Test delete Portprofile"""
LOG.debug("test_delete_portprofile - START")
req_body = jsonutils.dumps(self.test_port_profile)
index_response = self.test_app.post(
self.profile_path, req_body,
content_type=self.contenttype)
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
delete_path_temp = (self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'])
delete_path = str(delete_path_temp)
delete_response = self.test_app.delete(delete_path)
self.assertEqual(200, delete_response.status_int)
LOG.debug("test_delete_portprofile - END")
def test_delete_portprofileDNE(self, portprofile_id='100'):
""" Test delete Portprofile does not exist"""
LOG.debug("test_delete_portprofileDNE - START")
delete_path_temp = self.portprofile_path + portprofile_id
delete_path = str(delete_path_temp)
delete_response = self.test_app.delete(delete_path, status='*')
self.assertEqual(450, delete_response.status_int)
LOG.debug("test_delete_portprofileDNE - END")
def create_request(self, path, body, content_type, method='GET'):
""" Test create request"""
@ -406,139 +143,12 @@ class PortprofileExtensionTest(unittest.TestCase):
network_req.get_response(self.api)
LOG.debug("Deleting network - END")
def test_associate_portprofile(self):
""" Test associate portprofile"""
LOG.debug("test_associate_portprofile - START")
net_id = self._create_network()
port_id = self._create_port(net_id, "ACTIVE")
req_body = jsonutils.dumps(self.test_port_profile)
index_response = self.test_app.post(
self.profile_path, req_body,
content_type=self.contenttype)
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
test_port_assign_data = {
'portprofile': {
'network-id': net_id,
'port-id': port_id,
},
}
req_assign_body = jsonutils.dumps(test_port_assign_data)
associate_path_temp = (
self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'] +
"/associate_portprofile")
associate_path = str(associate_path_temp)
associate_response = self.test_app.put(
associate_path, req_assign_body,
content_type=self.contenttype)
self.assertEqual(200, associate_response.status_int)
# Clean Up - Disassociate and Delete the Port Profile
disassociate_path_temp = (
self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'] +
"/disassociate_portprofile")
disassociate_path = str(disassociate_path_temp)
delete_path_temp = (self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'])
delete_path = str(delete_path_temp)
self.tear_down_associate_profile(delete_path, disassociate_path,
req_assign_body)
self.tear_down_port_network(net_id, port_id)
LOG.debug("test_associate_portprofile - END")
def test_associate_portprofileDNE(self, portprofile_id='100'):
""" Test associate portprofile does not exist"""
LOG.debug("test_associate_portprofileDNE - START")
test_port_assign_data = {
'portprofile': {
'network-id': '001',
'port-id': '1',
},
}
req_assign_body = jsonutils.dumps(test_port_assign_data)
associate_path = (self.portprofile_path +
portprofile_id +
"/associate_portprofile")
associate_response = self.test_app.put(
associate_path, req_assign_body,
content_type=self.contenttype, status='*')
self.assertEqual(450, associate_response.status_int)
LOG.debug("test_associate_portprofileDNE - END")
def test_disassociate_portprofile(self):
""" Test disassociate portprofile"""
LOG.debug("test_disassociate_portprofile - START")
net_id = self._create_network()
port_id = self._create_port(net_id, "ACTIVE")
req_body = jsonutils.dumps(self.test_port_profile)
index_response = self.test_app.post(
self.profile_path, req_body,
content_type=self.contenttype)
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
test_port_assign_data = {
'portprofile': {
'network-id': net_id,
'port-id': port_id,
},
}
req_assign_body = jsonutils.dumps(test_port_assign_data)
associate_path_temp = (self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'] +
"/associate_portprofile")
associate_path = str(associate_path_temp)
self.test_app.put(associate_path, req_assign_body,
content_type=self.contenttype)
disassociate_path_temp = (
self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'] +
"/disassociate_portprofile")
disassociate_path = str(disassociate_path_temp)
disassociate_response = self.test_app.put(
disassociate_path, req_assign_body,
content_type=self.contenttype)
self.assertEqual(200, disassociate_response.status_int)
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
delete_path_temp = (self.portprofile_path +
resp_body['portprofiles']['portprofile']['id'])
delete_path = str(delete_path_temp)
self.tear_down_profile(delete_path)
self.tear_down_port_network(net_id, port_id)
LOG.debug("test_disassociate_portprofile - END")
def tear_down_port_network(self, net_id, port_id):
""" Tear down port and network """
self._delete_port(net_id, port_id)
self._delete_network(net_id)
def tear_down_profile(self, delete_profile_path):
""" Tear down profile"""
self.test_app.delete(delete_profile_path)
def tear_down_associate_profile(self, delete_profile_path,
dissociate_profile_path, req_body):
""" Tear down associate profile"""
self.test_app.put(dissociate_profile_path, req_body,
content_type=self.contenttype)
self.tear_down_profile(delete_profile_path)
def tearDown(self):
""" Tear down """
@ -546,84 +156,6 @@ class PortprofileExtensionTest(unittest.TestCase):
db.clear_db()
class NovatenantExtensionTest(unittest.TestCase):
def setUp(self):
""" Set up function"""
parent_resource = dict(member_name="tenant",
collection_name="extensions/csco/tenants")
member_actions = {'schedule_host': "PUT",
'associate_port': "PUT"}
controller = novatenant.NovatenantsController(
QuantumManager.get_plugin())
res_ext = extensions.ResourceExtension('novatenants', controller,
parent=parent_resource,
member_actions=member_actions)
self.test_app = setup_extensions_test_app(
SimpleExtensionManager(res_ext))
self.contenttype = 'application/json'
self.novatenants_path = '/extensions/csco/tenants/tt/novatenants/'
self.test_associate_port_data = {
'novatenant': {
'instance_id': 1,
'instance_desc': {
'project_id': 'demo',
'user_id': 'root',
'vif_id': '23432423',
},
},
}
self.test_associate_data = {
'novatenant': {
'instance_id': 1,
'instance_desc': {
'project_id': 'demo',
'user_id': 'root',
},
},
}
self._l2network_plugin = l2network_plugin.L2Network()
def test_schedule_host(self):
""" Test get host"""
LOG.debug("test_schedule_host - START")
req_body = jsonutils.dumps(self.test_associate_data)
host_path = self.novatenants_path + "001/schedule_host"
host_response = self.test_app.put(
host_path, req_body,
content_type=self.contenttype)
self.assertEqual(200, host_response.status_int)
LOG.debug("test_schedule_host - END")
def test_schedule_hostBADRequest(self):
""" Test get host bad request"""
LOG.debug("test_schedule_hostBADRequest - START")
host_path = self.novatenants_path + "001/schedule_host"
host_response = self.test_app.put(
host_path, 'BAD_REQUEST',
content_type=self.contenttype, status='*')
self.assertEqual(400, host_response.status_int)
LOG.debug("test_schedule_hostBADRequest - END")
def test_associate_port(self):
""" Test get associate port """
LOG.debug("test_associate_port - START")
req_body = jsonutils.dumps(self.test_associate_port_data)
associate_port_path = self.novatenants_path + "001/associate_port"
associate_port_response = self.test_app.put(
associate_port_path, req_body,
content_type=self.contenttype)
self.assertEqual(200, associate_port_response.status_int)
LOG.debug("test_associate_port - END")
def tearDown(self):
""" Tear down """
db.clear_db()
class QosExtensionTest(unittest.TestCase):
def setUp(self):
@ -1127,127 +659,6 @@ class CredentialExtensionTest(unittest.TestCase):
db.clear_db()
class MultiPortExtensionTest(unittest.TestCase):
def setUp(self):
""" Set up function """
parent_resource = dict(member_name="tenant",
collection_name="extensions/csco/tenants")
controller = multiport.MultiportController(
QuantumManager.get_plugin())
res_ext = extensions.ResourceExtension('multiport', controller,
parent=parent_resource)
self.test_app = setup_extensions_test_app(
SimpleExtensionManager(res_ext))
self.contenttype = 'application/json'
self.multiport_path = '/extensions/csco/tenants/tt/multiport'
self.multiport_path2 = '/extensions/csco/tenants/tt/multiport/'
self.test_multi_port = {
'multiport': {
'net_id_list': '1',
'status': 'test-qos1',
'ports_desc': 'Port Descr',
},
}
self.tenant_id = "test_tenant"
self.network_name = "test_network"
self.api = server.APIRouterV10()
self._l2network_plugin = l2network_plugin.L2Network()
def create_request(self, path, body, content_type, method='GET'):
""" Test create request"""
LOG.debug("test_create_request - START")
req = webob.Request.blank(path)
req.method = method
req.headers = {}
req.headers['Accept'] = content_type
req.body = body
LOG.debug("test_create_request - END")
return req
def _create_network(self, name=None):
""" Test create network"""
LOG.debug("Creating network - START")
if name:
net_name = name
else:
net_name = self.network_name
net_path = "/tenants/tt/networks"
net_data = {'network': {'name': '%s' % net_name}}
req_body = wsgi.Serializer().serialize(net_data, self.contenttype)
network_req = self.create_request(net_path, req_body,
self.contenttype, 'POST')
network_res = network_req.get_response(self.api)
network_data = wsgi.Serializer().deserialize(network_res.body,
self.contenttype)
LOG.debug("Creating network - END")
return network_data['network']['id']
def _delete_network(self, network_id):
""" Delete network """
LOG.debug("Deleting network %s - START", network_id)
network_path = "/tenants/tt/networks/%s" % network_id
network_req = self.create_request(network_path, None,
self.contenttype, 'DELETE')
network_req.get_response(self.api)
LOG.debug("Deleting network - END")
def test_create_multiport(self):
""" Test create MultiPort"""
LOG.debug("test_create_multiport - START")
net_id = self._create_network('net1')
net_id2 = self._create_network('net2')
test_multi_port = {
'multiport': {
'net_id_list': [net_id, net_id2],
'status': 'ACTIVE',
'ports_desc': {
'key': 'value',
},
},
}
req_body = jsonutils.dumps(test_multi_port)
index_response = self.test_app.post(self.multiport_path, req_body,
content_type=self.contenttype)
resp_body = wsgi.Serializer().deserialize(index_response.body,
self.contenttype)
self.assertEqual(200, index_response.status_int)
self.assertEqual(len(test_multi_port['multiport']['net_id_list']),
len(resp_body['ports']))
# Clean Up - Delete the Port Profile
self._delete_network(net_id)
self._delete_network(net_id2)
LOG.debug("test_create_multiport - END")
def test_create_multiportBADRequest(self):
""" Test create MultiPort Bad Request"""
LOG.debug("test_create_multiportBADRequest - START")
net_id = self._create_network('net1')
net_id2 = self._create_network('net2')
index_response = self.test_app.post(self.multiport_path, 'BAD_REQUEST',
content_type=self.contenttype,
status='*')
self.assertEqual(400, index_response.status_int)
# Clean Up - Delete the Port Profile
self._delete_network(net_id)
self._delete_network(net_id2)
LOG.debug("test_create_multiportBADRequest - END")
def tearDown(self):
db.clear_db()
def app_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)

View File

@ -23,104 +23,14 @@ that tests the database api method calls
import logging as LOG
import unittest
from quantum.openstack.common import log as logging
from quantum.plugins.cisco.common import cisco_constants as const
import quantum.plugins.cisco.db.api as db
import quantum.plugins.cisco.db.l2network_db as l2network_db
import quantum.plugins.cisco.db.nexus_db_v2 as nexus_db
import quantum.plugins.cisco.db.services_db as services_db
import quantum.plugins.cisco.db.ucs_db_v2 as ucs_db
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class UcsDB(object):
"""Class consisting of methods to call ucs db methods"""
def get_all_port_bindings(self):
"""get all port binding"""
port_bindings = []
try:
for bind in ucs_db.get_all_portbindings():
LOG.debug("Getting port binding for port: %s" % bind.port_id)
port_bind_dict = {}
port_bind_dict["port-id"] = bind.port_id
port_bind_dict["blade-intf-dn"] = str(bind.blade_intf_dn)
port_bind_dict["portprofile-name"] = bind.portprofile_name
port_bind_dict["vlan-name"] = bind.vlan_name
port_bind_dict["vlan-id"] = str(bind.vlan_id)
port_bind_dict["qos"] = bind.qos
port_bindings.append(port_bind_dict)
except Exception, exc:
LOG.error("Failed to get all port bindings: %s" % str(exc))
return port_bindings
def get_port_binding(self, port_id):
"""get port binding"""
port_binding = []
try:
for bind in ucs_db.get_portbinding(port_id):
LOG.debug("Getting port binding for port: %s" % bind.port_id)
port_bind_dict = {}
port_bind_dict["port-id"] = bind.port_id
port_bind_dict["blade-intf-dn"] = str(bind.blade_intf_dn)
port_bind_dict["portprofile-name"] = bind.portprofile_name
port_bind_dict["vlan-name"] = bind.vlan_name
port_bind_dict["vlan-id"] = str(bind.vlan_id)
port_bind_dict["qos"] = bind.qos
port_binding.append(port_bind_dict)
except Exception, exc:
LOG.error("Failed to get port binding: %s" % str(exc))
return port_binding
def create_port_binding(self, port_id, blade_intf_dn, portprofile_name,
vlan_name, vlan_id, qos):
"""create port binding"""
port_bind_dict = {}
try:
res = ucs_db.add_portbinding(port_id, blade_intf_dn,
portprofile_name, vlan_name,
vlan_id, qos)
LOG.debug("Created port binding: %s" % res.port_id)
port_bind_dict["port-id"] = res.port_id
port_bind_dict["blade-intf-dn"] = str(res.blade_intf_dn)
port_bind_dict["portprofile-name"] = res.portprofile_name
port_bind_dict["vlan-name"] = res.vlan_name
port_bind_dict["vlan-id"] = str(res.vlan_id)
port_bind_dict["qos"] = res.qos
return port_bind_dict
except Exception, exc:
LOG.error("Failed to create port binding: %s" % str(exc))
def delete_port_binding(self, port_id):
"""delete port binding"""
try:
res = ucs_db.remove_portbinding(port_id)
LOG.debug("Deleted port binding : %s" % res.port_id)
port_bind_dict = {}
port_bind_dict["port-id"] = res.port_id
return port_bind_dict
except Exception, exc:
raise Exception("Failed to delete port profile: %s" % str(exc))
def update_port_binding(self, port_id, blade_intf_dn,
portprofile_name, vlan_name, vlan_id, qos):
"""update port binding"""
try:
res = ucs_db.update_portbinding(port_id, blade_intf_dn,
portprofile_name, vlan_name,
vlan_id, qos)
LOG.debug("Updating port binding: %s" % res.port_id)
port_bind_dict = {}
port_bind_dict["port-id"] = res.port_id
port_bind_dict["dynamic-vnic-id"] = str(res.blade_intf_dn)
port_bind_dict["portprofile-name"] = res.portprofile_name
port_bind_dict["vlan-name"] = res.vlan_name
port_bind_dict["vlan-id"] = str(res.vlan_id)
port_bind_dict["qos"] = res.qos
return port_bind_dict
except Exception, exc:
raise Exception("Failed to update portprofile binding:%s"
% str(exc))
LOG = logging.getLogger(__name__)
class NexusDB(object):
@ -194,59 +104,6 @@ class NexusDB(object):
% str(exc))
class ServicesDB(object):
"""Class consisting of methods to call services db methods"""
def get_all_servicesbindings(self):
"""get all services port bindings"""
bindings = []
try:
for bind in services_db.get_all_services_bindings():
LOG.debug("Getting services bindings : %s" % bind.service_id)
bind_dict = {}
bind_dict["service_id"] = str(bind.service_id)
bind_dict["mngnet_id"] = str(bind.mngnet_id)
bind_dict["nbnet_id"] = str(bind.nbnet_id)
bind_dict["sbnet_id"] = str(bind.sbnet_id)
bindings.append(bind_dict)
except Exception, exc:
LOG.error("Failed to get all bindings: %s" % str(exc))
return bindings
def get_servicebindings(self, service_id):
"""get service binding"""
try:
bind = services_db.get_service_bindings(service_id)
LOG.debug("Getting service binding : %s" % bind.service_id)
return bind
except Exception, exc:
LOG.error("Failed to get service binding: %s" % str(exc))
def create_servicebinding(self, service_id, mngnet_id, nbnet_id, sbnet_id):
"""create service binding"""
bind_dict = {}
try:
res = services_db.add_services_binding(service_id, mngnet_id,
nbnet_id, sbnet_id)
LOG.debug("Created service binding : %s" % res.service_id)
bind_dict["service_id"] = str(res.service_id)
bind_dict["mngnet_id"] = str(res.mngnet_id)
bind_dict["nbnet_id"] = str(res.nbnet_id)
bind_dict["sbnet_id"] = str(res.sbnet_id)
return bind_dict
except Exception, exc:
LOG.error("Failed to create service binding: %s" % str(exc))
def delete_servicebinding(self, service_id):
"""delete service binding"""
try:
bind = services_db.remove_services_binding(service_id)
for res in bind:
LOG.debug("Deleted service binding: %s" % res.service_id)
except Exception, exc:
raise Exception("Failed to delete service binding: %s"
% str(exc))
class L2networkDB(object):
"""Class conisting of methods to call L2network db methods"""
def get_all_vlan_bindings(self):
@ -319,155 +176,6 @@ class L2networkDB(object):
except Exception, exc:
raise Exception("Failed to update vlan binding: %s" % str(exc))
def get_all_portprofiles(self):
"""Get all portprofiles"""
pps = []
try:
for portprof in l2network_db.get_all_portprofiles():
LOG.debug("Getting port profile : %s" % portprof.uuid)
pp_dict = {}
pp_dict["portprofile-id"] = str(portprof.uuid)
pp_dict["portprofile-name"] = portprof.name
pp_dict["vlan-id"] = str(portprof.vlan_id)
pp_dict["qos"] = portprof.qos
pps.append(pp_dict)
except Exception, exc:
LOG.error("Failed to get all port profiles: %s" % str(exc))
return pps
def get_portprofile(self, tenant_id, pp_id):
"""Get a portprofile"""
pp_list = []
try:
for portprof in l2network_db.get_portprofile(tenant_id, pp_id):
LOG.debug("Getting port profile : %s" % portprof.uuid)
pp_dict = {}
pp_dict["portprofile-id"] = str(portprof.uuid)
pp_dict["portprofile-name"] = portprof.name
pp_dict["vlan-id"] = str(portprof.vlan_id)
pp_dict["qos"] = portprof.qos
pp_list.append(pp_dict)
except Exception, exc:
LOG.error("Failed to get port profile: %s" % str(exc))
return pp_list
def create_portprofile(self, tenant_id, name, vlan_id, qos):
"""Create a portprofile"""
pp_dict = {}
try:
res = l2network_db.add_portprofile(tenant_id, name, vlan_id, qos)
LOG.debug("Created port profile: %s" % res.uuid)
pp_dict["portprofile-id"] = str(res.uuid)
pp_dict["portprofile-name"] = res.name
pp_dict["vlan-id"] = str(res.vlan_id)
pp_dict["qos"] = res.qos
return pp_dict
except Exception, exc:
LOG.error("Failed to create port profile: %s" % str(exc))
def delete_portprofile(self, tenant_id, pp_id):
"""Delete a portprofile"""
try:
res = l2network_db.remove_portprofile(tenant_id, pp_id)
LOG.debug("Deleted port profile : %s" % res.uuid)
pp_dict = {}
pp_dict["pp-id"] = str(res.uuid)
return pp_dict
except Exception, exc:
raise Exception("Failed to delete port profile: %s" % str(exc))
def update_portprofile(self, tenant_id, pp_id, name, vlan_id, qos):
"""Update a portprofile"""
try:
res = l2network_db.update_portprofile(tenant_id, pp_id, name,
vlan_id, qos)
LOG.debug("Updating port profile : %s" % res.uuid)
pp_dict = {}
pp_dict["portprofile-id"] = str(res.uuid)
pp_dict["portprofile-name"] = res.name
pp_dict["vlan-id"] = str(res.vlan_id)
pp_dict["qos"] = res.qos
return pp_dict
except Exception, exc:
raise Exception("Failed to update port profile: %s" % str(exc))
def get_all_pp_bindings(self):
"""Get all portprofile bindings"""
pp_bindings = []
try:
for pp_bind in l2network_db.get_all_pp_bindings():
LOG.debug("Getting port profile binding: %s" %
pp_bind.portprofile_id)
ppbinding_dict = {}
ppbinding_dict["portprofile-id"] = str(pp_bind.portprofile_id)
ppbinding_dict["port-id"] = str(pp_bind.port_id)
ppbinding_dict["tenant-id"] = pp_bind.tenant_id
ppbinding_dict["default"] = pp_bind.default
pp_bindings.append(ppbinding_dict)
except Exception, exc:
LOG.error("Failed to get all port profiles: %s" % str(exc))
return pp_bindings
def get_pp_binding(self, tenant_id, pp_id):
"""Get a portprofile binding"""
pp_binding = []
try:
for pp_bind in l2network_db.get_pp_binding(tenant_id, pp_id):
LOG.debug("Getting port profile binding: %s" %
pp_bind.portprofile_id)
ppbinding_dict = {}
ppbinding_dict["portprofile-id"] = str(pp_bind.portprofile_id)
ppbinding_dict["port-id"] = str(pp_bind.port_id)
ppbinding_dict["tenant-id"] = pp_bind.tenant_id
ppbinding_dict["default"] = pp_bind.default
pp_binding.append(ppbinding_dict)
except Exception, exc:
LOG.error("Failed to get port profile binding: %s" % str(exc))
return pp_binding
def create_pp_binding(self, tenant_id, port_id, pp_id, default):
"""Add a portprofile binding"""
ppbinding_dict = {}
try:
res = l2network_db.add_pp_binding(tenant_id, port_id, pp_id,
default)
LOG.debug("Created port profile binding: %s" % res.portprofile_id)
ppbinding_dict["portprofile-id"] = str(res.portprofile_id)
ppbinding_dict["port-id"] = str(res.port_id)
ppbinding_dict["tenant-id"] = res.tenant_id
ppbinding_dict["default"] = res.default
return ppbinding_dict
except Exception, exc:
LOG.error("Failed to create port profile binding: %s" % str(exc))
def delete_pp_binding(self, tenant_id, port_id, pp_id):
"""Delete a portprofile binding"""
try:
res = l2network_db.remove_pp_binding(tenant_id, port_id, pp_id)
LOG.debug("Deleted port profile binding : %s" % res.portprofile_id)
ppbinding_dict = {}
ppbinding_dict["portprofile-id"] = str(res.portprofile_id)
return ppbinding_dict
except Exception, exc:
raise Exception("Failed to delete port profile: %s" % str(exc))
def update_pp_binding(self, tenant_id, pp_id, newtenant_id,
port_id, default):
"""Update portprofile binding"""
try:
res = l2network_db.update_pp_binding(
tenant_id, pp_id, newtenant_id, port_id, default)
LOG.debug("Updating port profile binding: %s" % res.portprofile_id)
ppbinding_dict = {}
ppbinding_dict["portprofile-id"] = str(res.portprofile_id)
ppbinding_dict["port-id"] = str(res.port_id)
ppbinding_dict["tenant-id"] = res.tenant_id
ppbinding_dict["default"] = res.default
return ppbinding_dict
except Exception, exc:
raise Exception("Failed to update portprofile binding:%s"
% str(exc))
class QuantumDB(object):
"""Class conisting of methods to call Quantum db methods"""
@ -638,101 +346,6 @@ class QuantumDB(object):
raise Exception("Failed to unplug interface: %s" % str(exc))
class UcsDBTest(unittest.TestCase):
"""Class conisting of ucs DB unit tests"""
def setUp(self):
"""Setup for ucs db tests"""
l2network_db.initialize()
self.quantum = QuantumDB()
self.dbtest = UcsDB()
LOG.debug("Setup")
def tearDown(self):
"""Tear Down"""
db.clear_db()
def testm_create_portbinding(self):
"""create port binding"""
net1 = self.quantum.create_network("t1", "netid1")
port1 = self.quantum.create_port(net1["net-id"])
port_bind1 = self.dbtest.create_port_binding(
port1["port-id"], "vnic1", "pp1", "vlan1", 10, "qos1")
self.assertTrue(port_bind1["port-id"] == port1["port-id"])
self.teardown_portbinding()
self.teardown_network_port()
def testn_getall_portbindings(self):
"""get all port binding"""
net1 = self.quantum.create_network("t1", "netid1")
port1 = self.quantum.create_port(net1["net-id"])
port2 = self.quantum.create_port(net1["net-id"])
port_bind1 = self.dbtest.create_port_binding(
port1["port-id"], "vnic1", "pp1", "vlan1", 10, "qos1")
port_bind2 = self.dbtest.create_port_binding(
port2["port-id"], "vnic2", "pp2", "vlan2", 20, "qos2")
port_bindings = self.dbtest.get_all_port_bindings()
count = 0
for pbind in port_bindings:
if "vlan" in pbind["vlan-name"]:
count += 1
self.assertTrue(count == 2)
self.teardown_portbinding()
self.teardown_network_port()
def testo_delete_portbinding(self):
"""delete port binding"""
net1 = self.quantum.create_network("t1", "netid1")
port1 = self.quantum.create_port(net1["net-id"])
port_bind1 = self.dbtest.create_port_binding(
port1["port-id"], "vnic1", "pp1", "vlan1", 10, "qos1")
self.dbtest.delete_port_binding(port1["port-id"])
port_bindings = self.dbtest.get_all_port_bindings()
count = 0
for pbind in port_bindings:
if "vlan " in pbind["vlan-name"]:
count += 1
self.assertTrue(count == 0)
self.teardown_portbinding()
self.teardown_network_port()
def testp_update_portbinding(self):
"""update port binding"""
net1 = self.quantum.create_network("t1", "netid1")
port1 = self.quantum.create_port(net1["net-id"])
port_bind1 = self.dbtest.create_port_binding(
port1["port-id"], "vnic1", "pp1", "vlan1", 10, "qos1")
port_bind1 = self.dbtest.update_port_binding(
port1["port-id"], "vnic1", "newpp1", "newvlan1", 11, "newqos1")
port_bindings = self.dbtest.get_all_port_bindings()
count = 0
for pbind in port_bindings:
if "new" in pbind["vlan-name"]:
count += 1
self.assertTrue(count == 1)
self.teardown_portbinding()
self.teardown_network_port()
def teardown_portbinding(self):
"""tear down port binding"""
LOG.debug("Tearing Down Port Binding")
port_bindings = self.dbtest.get_all_port_bindings()
for port_binding in port_bindings:
portid = port_binding["port-id"]
self.dbtest.delete_port_binding(portid)
def teardown_network_port(self):
"""tearDown for Network and Port table"""
networks = self.quantum.get_all_networks("t1")
for net in networks:
netid = net["net-id"]
name = net["net-name"]
if "net" in name:
ports = self.quantum.get_all_ports(netid)
for por in ports:
self.quantum.delete_port(netid, por["port-id"])
self.quantum.delete_network(netid)
class NexusDBTest(unittest.TestCase):
"""Class conisting of nexus DB unit tests"""
def setUp(self):
@ -797,72 +410,6 @@ class NexusDBTest(unittest.TestCase):
self.dbtest.delete_nexusportbinding(vlan_id)
class ServicesDBTest(unittest.TestCase):
"""Class conisting of services DB unit tests"""
def setUp(self):
"""Setup for services db tests"""
l2network_db.initialize()
self.dbtest = ServicesDB()
LOG.debug("Setup")
def tearDown(self):
"""Tear Down"""
db.clear_db()
def testa_create_servicebinding(self):
"""create service binding"""
service_id = self.dbtest.create_servicebinding(
"i-00001", "mng_net", "northb_net", "northb_net")
self.assertTrue(service_id["service_id"] == "i-00001")
self.tearDown_servicebinding()
def testb_get_servicesbindings(self):
"""get all services binding"""
service_id = self.dbtest.create_servicebinding(
"i-00001", "mng_net", "northb_net", "northb_net")
bindings = self.dbtest.get_servicebindings("i-00001")
count = 0
if bindings:
count += 1
self.assertTrue(count == 1)
self.tearDown_servicebinding()
def testb_getall_servicesbindings(self):
"""get all services binding"""
service_id = self.dbtest.create_servicebinding(
"i-00001", "mng_net", "northb_net", "northb_net")
service_id = self.dbtest.create_servicebinding(
"i-00002", "mng_net", "northb_net", "northb_net")
bindings = self.dbtest.get_all_servicesbindings()
count = 0
for bind in bindings:
if "mng_net" in bind["mngnet_id"]:
count += 1
self.assertTrue(count == 2)
self.tearDown_servicebinding()
def testc_delete_servicesbinding(self):
"""delete services binding"""
binding_serv = self.dbtest.create_servicebinding(
"i-00001", "mng_net", "northb_net", "northb_net")
self.dbtest.delete_servicebinding("i-00001")
bindings = self.dbtest.get_all_servicesbindings()
count = 0
for bind in bindings:
if "mng_net" in bind["mngnet_id"]:
count += 1
self.assertTrue(count == 0)
self.tearDown_servicebinding()
def tearDown_servicebinding(self):
"""tear down nexusport binding table"""
LOG.debug("Tearing Down Nexus port Bindings")
binds = self.dbtest.get_all_servicesbindings()
for bind in binds:
service_id = bind["service_id"]
self.dbtest.delete_servicebinding(service_id)
class L2networkDBTest(unittest.TestCase):
"""Class conisting of L2network DB unit tests"""
def setUp(self):
@ -931,133 +478,6 @@ class L2networkDBTest(unittest.TestCase):
self.teardown_vlanbinding()
self.teardown_network()
def teste_create_portprofile(self):
"""test add port profile"""
pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
self.assertTrue(pp1["portprofile-name"] == "portprofile1")
self.teardown_portprofile()
self.teardown_network()
def testf_getall_portprofile(self):
"""test get all portprofiles"""
pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
self.assertTrue(pp1["portprofile-name"] == "portprofile1")
pp2 = self.dbtest.create_portprofile("t1", "portprofile2", 20, "qos2")
self.assertTrue(pp2["portprofile-name"] == "portprofile2")
pps = self.dbtest.get_all_portprofiles()
count = 0
for pprofile in pps:
if "portprofile" in pprofile["portprofile-name"]:
count += 1
self.assertTrue(count == 2)
self.teardown_portprofile()
def testg_delete_portprofile(self):
"""test delete portprofile"""
pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
self.assertTrue(pp1["portprofile-name"] == "portprofile1")
self.dbtest.delete_portprofile("t1", pp1["portprofile-id"])
pps = self.dbtest.get_all_portprofiles()
count = 0
for pprofile in pps:
if "portprofile " in pprofile["portprofile-name"]:
count += 1
self.assertTrue(count == 0)
self.teardown_portprofile()
def testh_update_portprofile(self):
"""test update portprofile"""
pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
self.assertTrue(pp1["portprofile-name"] == "portprofile1")
pp1 = self.dbtest.update_portprofile("t1", pp1["portprofile-id"],
"newportprofile1", 20, "qos2")
pps = self.dbtest.get_all_portprofiles()
count = 0
for pprofile in pps:
if "new" in pprofile["portprofile-name"]:
count += 1
self.assertTrue(count == 1)
self.teardown_portprofile()
def testi_create_portprofilebinding(self):
"""test create portprofile binding"""
net1 = self.quantum.create_network("t1", "netid1")
port1 = self.quantum.create_port(net1["net-id"])
pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
pp_binding1 = self.dbtest.create_pp_binding("t1", port1["port-id"],
pp1["portprofile-id"], "0")
self.assertTrue(pp_binding1["tenant-id"] == "t1")
self.teardown_portprofilebinding()
self.teardown_port()
self.teardown_network()
self.teardown_portprofile()
def testj_getall_portprofilebinding(self):
"""test get all portprofile binding"""
net1 = self.quantum.create_network("t1", "netid1")
port1 = self.quantum.create_port(net1["net-id"])
port2 = self.quantum.create_port(net1["net-id"])
pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
pp2 = self.dbtest.create_portprofile("t1", "portprofile2", 20, "qos2")
pp_binding1 = self.dbtest.create_pp_binding("t1", port1["port-id"],
pp1["portprofile-id"], "0")
self.assertTrue(pp_binding1["tenant-id"] == "t1")
pp_binding2 = self.dbtest.create_pp_binding("t1", port2["port-id"],
pp2["portprofile-id"], "0")
self.assertTrue(pp_binding2["tenant-id"] == "t1")
pp_bindings = self.dbtest.get_all_pp_bindings()
count = 0
for pp_bind in pp_bindings:
if "t1" in pp_bind["tenant-id"]:
count += 1
self.assertTrue(count == 2)
self.teardown_portprofilebinding()
self.teardown_port()
self.teardown_network()
self.teardown_portprofile()
def testk_delete_portprofilebinding(self):
"""test delete portprofile binding"""
net1 = self.quantum.create_network("t1", "netid1")
port1 = self.quantum.create_port(net1["net-id"])
pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
pp_binding1 = self.dbtest.create_pp_binding("t1", port1["port-id"],
pp1["portprofile-id"], "0")
self.assertTrue(pp_binding1["tenant-id"] == "t1")
self.dbtest.delete_pp_binding("t1", port1["port-id"],
pp_binding1["portprofile-id"])
pp_bindings = self.dbtest.get_all_pp_bindings()
count = 0
for pp_bind in pp_bindings:
if "t1 " in pp_bind["tenant-id"]:
count += 1
self.assertTrue(count == 0)
self.teardown_portprofilebinding()
self.teardown_port()
self.teardown_network()
self.teardown_portprofile()
def testl_update_portprofilebinding(self):
"""test update portprofile binding"""
net1 = self.quantum.create_network("t1", "netid1")
port1 = self.quantum.create_port(net1["net-id"])
pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
pp_binding1 = self.dbtest.create_pp_binding("t1", port1["port-id"],
pp1["portprofile-id"], "0")
self.assertTrue(pp_binding1["tenant-id"] == "t1")
pp_binding1 = self.dbtest.update_pp_binding(
"t1", pp1["portprofile-id"], "newt1", port1["port-id"], "1")
pp_bindings = self.dbtest.get_all_pp_bindings()
count = 0
for pp_bind in pp_bindings:
if "new" in pp_bind["tenant-id"]:
count += 1
self.assertTrue(count == 1)
self.teardown_portprofilebinding()
self.teardown_port()
self.teardown_network()
self.teardown_portprofile()
def testm_test_vlanids(self):
"""test vlanid methods"""
l2network_db.create_vlanids()
@ -1097,23 +517,6 @@ class L2networkDBTest(unittest.TestCase):
netid = vlan["net-id"]
self.dbtest.delete_vlan_binding(netid)
def teardown_portprofile(self):
"""tearDown PortProfile table"""
LOG.debug("Tearing Down Port Profile")
pps = self.dbtest.get_all_portprofiles()
for pprofile in pps:
ppid = pprofile["portprofile-id"]
self.dbtest.delete_portprofile("t1", ppid)
def teardown_portprofilebinding(self):
"""tearDown PortProfileBinding table"""
LOG.debug("Tearing Down Port Profile Binding")
pp_bindings = self.dbtest.get_all_pp_bindings()
for pp_binding in pp_bindings:
ppid = pp_binding["portprofile-id"]
portid = pp_binding["port-id"]
self.dbtest.delete_pp_binding("t1", portid, ppid)
class QuantumDBTest(unittest.TestCase):
"""Class conisting of Quantum DB unit tests"""

View File

@ -1,172 +0,0 @@
# 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: Shweta Padubidri, Cisco Systems, Inc.
#
import logging
import unittest
from quantum.plugins.cisco.ucs import cisco_ucs_network_driver
LOG = logging.getLogger('quantum.tests.test_ucs_driver')
CREATE_VLAN_OUTPUT = ('<configConfMos cookie="cookie_placeholder" '
'inHierarchical="true"> <inConfigs><pair '
'key="fabric/lan/net-New Vlan"> '
'<fabricVlan defaultNet="no" '
'dn="fabric/lan/net-New Vlan" id="200" '
'name="New Vlan" status="created"></fabricVlan> '
'</pair> </inConfigs> </configConfMos>')
CREATE_PROFILE_OUTPUT = ('<configConfMos cookie="cookie_placeholder" '
'inHierarchical="true"> <inConfigs><pair '
'key="fabric/lan/profiles/vnic-'
'New Profile"> <vnicProfile descr="Profile created '
'by Cisco OpenStack Quantum Plugin" '
'dn="fabric/lan/profiles/vnic-New Profile" maxPorts='
'"64" name="New Profile" nwCtrlPolicyName="" '
'pinToGroupName="" qosPolicyName="" status="created">'
' <vnicEtherIf defaultNet="yes" name="New Vlan" '
'rn="if-New Vlan" > </vnicEtherIf> </vnicProfile> '
'</pair> </inConfigs> </configConfMos>')
CHANGE_VLAN_OUTPUT = ('<configConfMos cookie="cookie_placeholder" '
'inHierarchical="true"> <inConfigs><pair key="'
'fabric/lan/profiles/vnic-New Profile"> '
'<vnicProfile descr="Profile '
'created by Cisco OpenStack Quantum Plugin" '
'dn="fabric/lan/profiles/vnic-New Profile" maxPorts="64"'
' name="New Profile" nwCtrlPolicyName="" '
'pinToGroupName="" qosPolicyName="" '
'status="created,modified"><vnicEtherIf '
'rn="if-Old Vlan" status="deleted"> </vnicEtherIf> '
'<vnicEtherIf defaultNet="yes" name="New Vlan" '
'rn="if-New Vlan" > </vnicEtherIf> </vnicProfile> '
'</pair></inConfigs> </configConfMos>')
DELETE_VLAN_OUTPUT = ('<configConfMos cookie="cookie_placeholder" '
'inHierarchical="true"> <inConfigs><pair '
'key="fabric/lan/net-New Vlan"> '
'<fabricVlan dn="fabric/lan/net-New Vlan" '
'status="deleted"> </fabricVlan> '
'</pair> </inConfigs></configConfMos>')
DELETE_PROFILE_OUTPUT = ('<configConfMos cookie="cookie_placeholder" '
'inHierarchical="false"> <inConfigs><pair key="'
'fabric/lan/profiles/vnic-New Profile"> <vnicProfile '
'dn="fabric/lan/profiles/vnic-New Profile" '
'status="deleted"> </vnicProfile></pair> '
'</inConfigs> </configConfMos>')
ASSOC_PROFILE_OUTPUT = ('<configConfMos cookie="cookie_placeholder" '
'inHierarchical="true"> <inConfigs> <pair key='
'"fabric/lan/profiles/vnic-New Profile/cl-New '
'Profile Client"> <vmVnicProfCl dcName=".*" '
'descr="" dn="fabric/lan/profiles/vnic-'
'New Profile/cl-New Profile Client"name="New '
'Profile Client" orgPath=".*" status="created" '
'swName="default$"> </vmVnicProfCl>'
'</pair> </inConfigs> </configConfMos>')
class TestUCSDriver(unittest.TestCase):
def setUp(self):
""" Set up function"""
self.ucsm_driver = cisco_ucs_network_driver.CiscoUCSMDriver()
self.vlan_name = 'New Vlan'
self.vlan_id = '200'
self.profile_name = 'New Profile'
self.old_vlan_name = 'Old Vlan'
self.profile_client_name = 'New Profile Client'
def test_create_vlan_post_data(self, expected_output=CREATE_VLAN_OUTPUT):
"""
Tests creation of vlan post Data
"""
LOG.debug("test_create_vlan")
vlan_details = self.ucsm_driver._create_vlan_post_data(
self.vlan_name, self.vlan_id)
self.assertEqual(vlan_details, expected_output)
LOG.debug("test_create_vlan - END")
def test_create_profile_post_data(self,
expected_output=CREATE_PROFILE_OUTPUT):
"""
Tests creation of profile post Data
"""
LOG.debug("test_create_profile_post_data - START")
profile_details = self.ucsm_driver._create_profile_post_data(
self.profile_name, self.vlan_name)
self.assertEqual(profile_details, expected_output)
LOG.debug("test_create_profile_post - END")
def test_change_vlan_profile_data(self,
expected_output=CHANGE_VLAN_OUTPUT):
"""
Tests creation of change vlan in profile post Data
"""
LOG.debug("test_create_profile_post_data - START")
profile_details = self.ucsm_driver._change_vlaninprof_post_data(
self.profile_name, self.old_vlan_name, self.vlan_name)
self.assertEqual(profile_details, expected_output)
LOG.debug("test_create_profile_post - END")
def test_delete_vlan_post_data(self, expected_output=DELETE_VLAN_OUTPUT):
"""
Tests deletion of vlan post Data
"""
LOG.debug("test_create_profile_post_data - START")
self.ucsm_driver._create_vlan_post_data(
self.vlan_name, self.vlan_id)
vlan_delete_details = self.ucsm_driver._delete_vlan_post_data(
self.vlan_name)
self.assertEqual(vlan_delete_details, expected_output)
LOG.debug("test_create_profile_post - END")
def test_delete_profile_post_data(self,
expected_output=DELETE_PROFILE_OUTPUT):
"""
Tests deletion of profile post Data
"""
LOG.debug("test_create_profile_post_data - START")
self.ucsm_driver._create_profile_post_data(
self.profile_name, self.vlan_name)
profile_delete_details = self.ucsm_driver._delete_profile_post_data(
self.profile_name)
self.assertEqual(profile_delete_details, expected_output)
LOG.debug("test_create_profile_post - END")
def test_create_profile_client_data(self,
expected_output=ASSOC_PROFILE_OUTPUT):
"""
Tests creation of profile client post Data
"""
LOG.debug("test_create_profile_client_data - START")
profile_details = self.ucsm_driver._create_pclient_post_data(
self.profile_name, self.profile_client_name)
self.assertEqual(profile_details, expected_output)
LOG.debug("test_create_profile_post - END")

View File

@ -1,32 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 OpenStack LLC.
# 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.
import __builtin__
import unittest
setattr(__builtin__, '_', lambda x: x)
class BaseTest(unittest.TestCase):
def setUp(self):
pass
def setUp():
pass

View File

@ -1,58 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 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 logging
import os
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_configparser as confp
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_credentials_v2 as cred
from quantum.plugins.cisco.ucs import (
cisco_ucs_inventory_configuration as conf,
)
from quantum.plugins.cisco.ucs import cisco_ucs_inventory_v2
LOG = logging.getLogger(__name__)
def curdir(*p):
return os.path.join(os.path.dirname(__file__), *p)
class UCSInventory(cisco_ucs_inventory_v2.UCSInventory):
"""
Inventory implementation for testing
"""
def __init__(self):
fake_ucs_driver = "quantum.plugins.cisco.tests.unit.v2.ucs." + \
"fake_ucs_driver.CiscoUCSMFakeDriver"
self._client = importutils.import_object(fake_ucs_driver)
conf_parser = confp.CiscoConfigParser(curdir("fake_ucs_inventory.ini"))
conf.INVENTORY = conf_parser.walk(conf_parser.dummy)
for ucsm in conf.INVENTORY.keys():
ucsm_ip = conf.INVENTORY[ucsm][const.IP_ADDRESS]
try:
cred.Store.put_credential(ucsm_ip, "username", "password")
except:
pass
self._load_inventory()

View File

@ -1,96 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 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.
# @author: Rohit Agarwalla, Cisco Systems, Inc.
from quantum.plugins.cisco.common import cisco_constants as const
class CiscoUCSMFakeDriver():
"""UCSM Fake Driver"""
def __init__(self):
pass
def _get_blade_interfaces(self, chassis_number, blade_number, ucsm_ip,
ucsm_username, ucsm_password):
blade_interfaces = {}
for element in range(20):
dist_name = "dn" + str(element)
if dist_name:
order = str(element)
rhel_name = "eth" + str(element)
blade_interface = {
const.BLADE_INTF_DN: dist_name,
const.BLADE_INTF_ORDER: order,
const.BLADE_INTF_LINK_STATE: None,
const.BLADE_INTF_OPER_STATE: None,
const.BLADE_INTF_INST_TYPE: const.BLADE_INTF_DYNAMIC,
const.BLADE_INTF_RHEL_DEVICE_NAME: rhel_name,
}
blade_interfaces[dist_name] = blade_interface
return blade_interfaces
def _get_blade_interface_state(self, blade_intf, ucsm_ip,
ucsm_username, ucsm_password):
blade_intf[const.BLADE_INTF_LINK_STATE] = \
const.BLADE_INTF_STATE_UNKNOWN
blade_intf[const.BLADE_INTF_OPER_STATE] = \
const.BLADE_INTF_STATE_UNKNOWN
blade_intf[const.BLADE_INTF_INST_TYPE] = \
const.BLADE_INTF_DYNAMIC
def create_vlan(self, vlan_name, vlan_id, ucsm_ip, ucsm_username,
ucsm_password):
pass
def create_profile(self, profile_name, vlan_name, ucsm_ip, ucsm_username,
ucsm_password):
pass
def change_vlan_in_profile(self, profile_name, old_vlan_name,
new_vlan_name, ucsm_ip, ucsm_username,
ucsm_password):
pass
def get_blade_data(self, chassis_number, blade_number, ucsm_ip,
ucsm_username, ucsm_password):
"""
Returns only the dynamic interfaces on the blade
"""
blade_interfaces = self._get_blade_interfaces(chassis_number,
blade_number,
ucsm_ip,
ucsm_username,
ucsm_password)
for blade_intf in blade_interfaces.keys():
self._get_blade_interface_state(blade_interfaces[blade_intf],
ucsm_ip, ucsm_username,
ucsm_password)
if ((blade_interfaces[blade_intf][const.BLADE_INTF_INST_TYPE] !=
const.BLADE_INTF_DYNAMIC)):
blade_interfaces.pop(blade_intf)
return blade_interfaces
def delete_vlan(self, vlan_name, ucsm_ip, ucsm_username, ucsm_password):
pass
def delete_profile(self, profile_name, ucsm_ip, ucsm_username,
ucsm_password):
pass

View File

@ -1,7 +0,0 @@
[ucsm-1]
ip_address = 192.168.100.2
[[chassis-1]]
chassis_id = 1
[[[blade-1]]]
blade_id = 1
host_name = blade1

View File

@ -1,126 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 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: Shubhangi Satras, Cisco Systems, Inc.
# @author: Tyler Smith, Cisco Systems, Inc.
import logging
import unittest
from quantum.openstack.common import uuidutils
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_credentials_v2 as creds
from quantum.plugins.cisco.db import network_db_v2 as cdb
from quantum.plugins.cisco.tests.unit.v2.ucs.cisco_ucs_inventory_fake import (
UCSInventory,
)
LOG = logging.getLogger(__name__)
# Set some data to use in tests
tenant = 'shubh'
net_name = 'TestNetwork1'
port_state = const.PORT_UP
interface_id = 'vif-01'
class TestUCSInventory(unittest.TestCase):
"""
Tests for the UCS Inventory. Each high-level operation should return
some information about which devices to perform the action on.
"""
def setUp(self):
"""Setup our tests"""
cdb.initialize()
creds.Store.initialize()
# Create the ucs inventory object
self._ucs_inventory = UCSInventory()
self.inventory = self._ucs_inventory._inventory
def assertValidUCM(self, ip_address):
"""Asserts that the given ip is in the UCS inventory"""
if ip_address in self.inventory.keys():
assert(1)
return
assert(0)
def _test_get_all_ucms(self, cmd):
"""Runs tests for commands that expect a list of all UCMS"""
LOG.debug("test_%s - START", cmd)
results = getattr(self._ucs_inventory, cmd)([])
self.assertEqual(results[const.DEVICE_IP], self.inventory.keys())
LOG.debug("test_%s - END", cmd)
def _test_with_port_creation(self, cmd, params=None):
"""Tests commands that requires a port to exist"""
LOG.debug("test_%s - START", cmd)
net_uuid = uuidutils.generate_uuid()
device_params = self._ucs_inventory.create_port(tenant, net_uuid,
port_state,
state=port_state)
args = [tenant, net_uuid, port[const.PORT_ID]]
if params is not None:
args.extend(params)
ip_address = getattr(self._ucs_inventory, cmd)(args)
ip_address = ip_address[const.DEVICE_IP][0]
self.assertValidUCM(ip_address)
cdb.clear_db()
LOG.debug("test_%s - END", cmd)
def test_create_port(self):
"""Test that the UCS Inventory returns the correct devices to use"""
LOG.debug("test_create_port - START")
results = self._ucs_inventory.create_port([])
results = results[const.LEAST_RSVD_BLADE_DICT]
ip_address = results[const.LEAST_RSVD_BLADE_UCSM]
chassis = results[const.LEAST_RSVD_BLADE_CHASSIS]
blade = results[const.LEAST_RSVD_BLADE_ID]
if blade not in self.inventory[ip_address][chassis]:
self.assertEqual(0, 1)
self.assertEqual(1, 1)
LOG.debug("test_create_port - END")
def test_get_all_networks(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('get_all_networks')
def test_create_network(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('create_network')
def test_delete_network(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('delete_network')
def test_get_network_details(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('get_network_details')
def test_update_network(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('update_network')
def test_get_all_ports(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('get_all_ports')

View File

@ -1,18 +0,0 @@
# 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.
#

View File

@ -1,56 +0,0 @@
# 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: Rohit Agarwalla, Cisco Systems Inc.
#
import subprocess
from quantum.common import utils
def get_next_dynic(argv=[]):
"""Get the next available dynamic nic on this host"""
cmd = ["ifconfig", "-a"]
f_cmd_output = (
utils.subprocess_popen(cmd, stdout=subprocess.PIPE).communicate()[0])
eths = [lines.split(' ')[0] for lines in f_cmd_output.splitlines()
if "eth" in lines]
#print eths
for eth in eths:
cmd = ["ethtool", "-i", eth]
f_cmd_output = (
utils.subprocess_popen(cmd,
stdout=subprocess.PIPE).communicate()[0])
bdf = [lines.split(' ')[1] for lines in f_cmd_output.splitlines()
if "bus-info" in lines]
#print bdf
cmd = ["lspci", "-n", "-s", bdf[0]]
f_cmd_output = (utils.subprocess_popen(cmd, stdout=subprocess.PIPE).
communicate()[0])
deviceid = [(lines.split(':')[3]).split(' ')[0]
for lines in f_cmd_output.splitlines()]
#print deviceid
if deviceid[0] == "0044":
cmd = ["/sbin/ip", "link", "show", eth]
f_cmd_output = (
utils.subprocess_popen(cmd, stdout=subprocess.PIPE).
communicate()[0])
used = [lines for lines in f_cmd_output.splitlines()
if "UP" in lines]
if not used:
break
return eth

View File

@ -1,40 +0,0 @@
# 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.
#
from quantum.common.utils import find_config_file
from quantum.plugins.cisco.common import cisco_configparser as confp
CP = confp.CiscoConfigParser(find_config_file({'plugin': 'cisco'},
'ucs.ini'))
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']
CP = confp.CiscoConfigParser(find_config_file({'plugin': 'cisco'},
'ucs_inventory.ini'))
INVENTORY = CP.walk(CP.dummy)

View File

@ -1,27 +0,0 @@
# 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.
#
from quantum.common.utils import find_config_file
from quantum.plugins.cisco.common import cisco_configparser as confp
CONF_FILE = find_config_file({'plugin': 'cisco'}, "ucs_inventory.ini")
CP = confp.CiscoConfigParser(CONF_FILE)
INVENTORY = CP.walk(CP.dummy)

View File

@ -1,313 +0,0 @@
# 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.
#
"""
Implements a UCSM XML API Client
"""
import httplib
import logging
from xml.etree import ElementTree as et
from quantum.plugins.cisco.common import cisco_constants as const
LOG = logging.getLogger(__name__)
COOKIE_VALUE = "cookie_placeholder"
PROFILE_NAME = "profilename_placeholder"
PROFILE_CLIENT = "profileclient_placeholder"
VLAN_NAME = "vlanname_placeholder"
VLAN_ID = "vlanid_placeholder"
OLD_VLAN_NAME = "old_vlanname_placeholder"
BLADE_VALUE = "blade_number_placeholder"
BLADE_DN_VALUE = "blade_dn_placeholder"
CHASSIS_VALUE = "chassis_number_placeholder"
DYNAMIC_NIC_PREFIX = "eth"
# The following are standard strings, messages used to communicate with UCSM,
#only place holder values change for each message
HEADERS = {"Content-Type": "text/xml"}
METHOD = "POST"
URL = "/nuova"
CREATE_VLAN = ('<configConfMos cookie="' + COOKIE_VALUE +
'" inHierarchical="true"> <inConfigs>'
'<pair key="fabric/lan/net-"' + VLAN_NAME +
'"> <fabricVlan defaultNet="no" '
'dn="fabric/lan/net-' + VLAN_NAME +
'" id="' + VLAN_ID + '" name="' +
VLAN_NAME + '" status="created">'
'</fabricVlan> </pair> </inConfigs> </configConfMos>')
CREATE_PROFILE = ('<configConfMos cookie="' + COOKIE_VALUE +
'" inHierarchical="true"> <inConfigs>'
'<pair key="fabric/lan/profiles/vnic-' + PROFILE_NAME +
'"> <vnicProfile descr="Profile created by '
'Cisco OpenStack Quantum Plugin" '
'dn="fabric/lan/profiles/vnic' + PROFILE_NAME +
'" maxPorts="64" name="' + PROFILE_NAME +
'" nwCtrlPolicyName="" pinToGroupName="" '
'qosPolicyName="" status="created"> '
'<vnicEtherIf defaultNet="yes" name="' + VLAN_NAME +
'" rn="if' + VLAN_NAME + '" > </vnicEtherIf> '
'</vnicProfile> </pair> </inConfigs> </configConfMos>')
ASSOCIATE_PROFILE = ('<configConfMos cookie="' + COOKIE_VALUE +
'" inHierarchical="true"> <inConfigs> <pair '
'key="fabric/lan/profiles/vnic' + PROFILE_NAME +
'/cl' + PROFILE_CLIENT + '"> <vmVnicProfCl dcName=".*" '
'descr="" dn="fabric/lan/profiles/vnic' +
PROFILE_NAME + '/cl' + PROFILE_CLIENT +
'"name="' + PROFILE_CLIENT + '" orgPath=".*" '
'status="created" swName="default$"> </vmVnicProfCl>'
'</pair> </inConfigs> </configConfMos>')
CHANGE_VLAN_IN_PROFILE = ('<configConfMos cookie="' + COOKIE_VALUE +
'" inHierarchical="true"> <inConfigs'
'<pair key="fabric/lan/profiles/vnic' +
PROFILE_NAME + '"> <vnicProfile descr="Profile'
'created by Cisco OpenStack Quantum Plugin"'
'dn="fabric/lan/profiles/vnic' +
PROFILE_NAME + '" maxPorts="64" name="' +
PROFILE_NAME + '" nwCtrlPolicyName=""'
'pinToGroupName="" qosPolicyName=""'
'status="created,modified"'
'<vnicEtherIf rn="if' + OLD_VLAN_NAME +
'" status="deleted"> </vnicEtherIf> <vnicEtherIf'
'defaultNet="yes" name="' +
VLAN_NAME + '" rn="if' + VLAN_NAME +
'" > </vnicEtherIf> </vnicProfile> </pair'
'</inConfigs> </configConfMos>')
DELETE_VLAN = ('<configConfMos cookie="' + COOKIE_VALUE +
'" inHierarchical="true"> <inConfigs'
'<pair key="fabric/lan/net' + VLAN_NAME +
'"> <fabricVlan dn="fabric/lan/net' + VLAN_NAME +
'" status="deleted"> </fabricVlan> </pair> </inConfigs'
'</configConfMos')
DELETE_PROFILE = ('<configConfMos cookie="' + COOKIE_VALUE +
'" inHierarchical="false"> <inConfigs'
'<pair key="fabric/lan/profiles/vnic' + PROFILE_NAME +
'"> <vnicProfile dn="fabric/lan/profiles/vnic' +
PROFILE_NAME + '" status="deleted"> </vnicProfile'
'</pair> </inConfigs> </configConfMos')
GET_BLADE_INTERFACE_STATE = ('<configScope cookie="' + COOKIE_VALUE +
'" dn="' + BLADE_DN_VALUE + '" inClass="dcxVIf"' +
'inHierarchical="false" inRecursive="false">' +
'<inFilter> </inFilter> </configScope')
GET_BLADE_INTERFACE = ('<configResolveClass cookie="' + COOKIE_VALUE +
'" classId="vnicEther"' +
' inHierarchical="false"' +
' <inFilter> <eq class="vnicEther" ' +
'property="equipmentDn"' +
' value="sys/chassis' + CHASSIS_VALUE + '/blade' +
BLADE_VALUE + '/adaptor-1/host-eth-?"/>' +
'</inFilter> </configResolveClass')
# TODO (Sumit): Assumes "adaptor-1", check if this has to be discovered too
GET_BLADE_INTERFACES = ('<configResolveChildren cookie="' +
COOKIE_VALUE + '" inDn="sys/chassis' +
CHASSIS_VALUE + '/blade' + BLADE_VALUE +
'/adaptor-1"' +
' inHierarchical="false"> <inFilter> </inFilter' +
' </configResolveChildren')
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.HTTPSConnection(ucsm_ip)
login_data = ("<aaaLogin inName=\"" + ucsm_username +
"\" inPassword=\"" + ucsm_password + "\" />")
conn.request(METHOD, URL, login_data, HEADERS)
response = conn.getresponse()
response_data = response.read()
# TODO (Sumit): If login is not successful, throw exception
xml_tree = et.XML(response_data)
cookie = xml_tree.attrib["outCookie"]
data = data.replace(COOKIE_VALUE, cookie)
conn.request(METHOD, URL, data, HEADERS)
response = conn.getresponse()
response_data = response.read()
post_data_response = response_data
logout_data = "<aaaLogout inCookie=\"" + cookie + "\" />"
conn.request(METHOD, URL, logout_data, HEADERS)
response = conn.getresponse()
response_data = response.read()
return post_data_response
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_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_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_blade_interfaces_post_data(self, chassis_number, blade_number):
"""Create command"""
data = GET_BLADE_INTERFACES.replace(CHASSIS_VALUE, chassis_number)
data = data.replace(BLADE_VALUE, blade_number)
return data
def _get_blade_intf_st_post_data(self, blade_dn):
"""Create command"""
data = GET_BLADE_INTERFACE_STATE.replace(BLADE_DN_VALUE, blade_dn)
return data
def _get_blade_interfaces(self, chassis_number, blade_number, ucsm_ip,
ucsm_username, ucsm_password):
"""Create command"""
data = self._get_blade_interfaces_post_data(chassis_number,
blade_number)
response = self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)
elements = (
et.XML(response).find("outConfigs").findall("adaptorHostEthIf")
)
blade_interfaces = {}
for element in elements:
dist_name = element.get("dn", default=None)
if dist_name:
order = element.get("order", default=None)
blade_interface = {
const.BLADE_INTF_DN: dist_name,
const.BLADE_INTF_ORDER: order,
const.BLADE_INTF_LINK_STATE: None,
const.BLADE_INTF_OPER_STATE: None,
const.BLADE_INTF_INST_TYPE: None,
const.BLADE_INTF_RHEL_DEVICE_NAME:
self._get_rhel_device_name(order),
}
blade_interfaces[dist_name] = blade_interface
return blade_interfaces
def _get_blade_interface_state(self, blade_intf, ucsm_ip,
ucsm_username, ucsm_password):
"""Create command"""
data = (self._get_blade_intf_st_post_data(
blade_intf[const.BLADE_INTF_DN]))
response = self._post_data(ucsm_ip, ucsm_username, ucsm_password, data)
elements = et.XML(response).find("outConfigs").findall("dcxVIf")
for element in elements:
blade_intf[const.BLADE_INTF_LINK_STATE] = element.get("linkState",
default=None)
blade_intf[const.BLADE_INTF_OPER_STATE] = element.get("operState",
default=None)
blade_intf[const.BLADE_INTF_INST_TYPE] = element.get("instType",
default=None)
def _get_rhel_device_name(self, order):
"""Get the device name as on the RHEL host"""
device_name = const.RHEL_DEVICE_NAME_REPFIX + str(int(order) - 1)
return device_name
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_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):
"""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_blade_data(self, chassis_number, blade_number, ucsm_ip,
ucsm_username, ucsm_password):
"""
Returns only the dynamic interfaces on the blade
"""
blade_interfaces = self._get_blade_interfaces(chassis_number,
blade_number,
ucsm_ip,
ucsm_username,
ucsm_password)
for blade_intf in blade_interfaces.keys():
self._get_blade_interface_state(blade_interfaces[blade_intf],
ucsm_ip, ucsm_username,
ucsm_password)
if ((blade_interfaces[blade_intf][const.BLADE_INTF_INST_TYPE] !=
const.BLADE_INTF_DYNAMIC)):
blade_interfaces.pop(blade_intf)
return blade_interfaces
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)

View File

@ -91,7 +91,6 @@ else:
['etc/quantum/plugins/cisco/credentials.ini',
'etc/quantum/plugins/cisco/l2network_plugin.ini',
'etc/quantum/plugins/cisco/nexus.ini',
'etc/quantum/plugins/cisco/ucs.ini',
'etc/quantum/plugins/cisco/cisco_plugins.ini',
'etc/quantum/plugins/cisco/db_conn.ini']),
(bigswitch_plugin_config_path,