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:
parent
4b448b82f0
commit
ee589db437
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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]
|
||||
|
@ -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
|
@ -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>
|
@ -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')
|
||||
)
|
@ -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)
|
@ -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']))
|
@ -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)
|
@ -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))
|
@ -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))
|
@ -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'
|
||||
|
@ -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")
|
||||
|
@ -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`
|
||||
|
@ -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
|
||||
|
@ -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"))
|
||||
|
@ -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'
|
||||
|
@ -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"))
|
||||
|
@ -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'
|
||||
|
@ -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"))
|
||||
|
@ -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)
|
@ -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)
|
@ -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
|
@ -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']
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
#
|
@ -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
|
@ -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)
|
@ -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
|
||||
"""
|
@ -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'
|
@ -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)
|
||||
|
@ -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"""
|
||||
|
@ -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")
|
@ -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
|
@ -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()
|
@ -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
|
@ -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
|
@ -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')
|
@ -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.
|
||||
#
|
@ -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
|
@ -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)
|
@ -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)
|
@ -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)
|
1
setup.py
1
setup.py
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user