From: Abhishek Raut Date: Tue, 11 Aug 2015 03:52:15 +0000 (-0700) Subject: Remove Cisco Meta and N1KV monolithic plugins X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=d12017ad511a202a12422245cce6204a5731250c;p=openstack-build%2Fneutron-build.git Remove Cisco Meta and N1KV monolithic plugins This patch removes the Cisco meta plugin and the Cisco Nexus1000V monolithic plugin as they were deprecated in the previous cycle. Closes-bug: #1473217 Change-Id: Id170b9512b2f52a971264336d83b083d487359ee --- diff --git a/etc/neutron/plugins/cisco/cisco_plugins.ini b/etc/neutron/plugins/cisco/cisco_plugins.ini deleted file mode 100644 index a93bc7f1d..000000000 --- a/etc/neutron/plugins/cisco/cisco_plugins.ini +++ /dev/null @@ -1,107 +0,0 @@ -[cisco] - -# (StrOpt) A short prefix to prepend to the VLAN number when creating a -# VLAN interface. For example, if an interface is being created for -# VLAN 2001 it will be named 'q-2001' using the default prefix. -# -# vlan_name_prefix = q- -# Example: vlan_name_prefix = vnet- - -# (StrOpt) A short prefix to prepend to the VLAN number when creating a -# provider VLAN interface. For example, if an interface is being created -# for provider VLAN 3003 it will be named 'p-3003' using the default prefix. -# -# provider_vlan_name_prefix = p- -# Example: provider_vlan_name_prefix = PV- - -# (BoolOpt) A flag indicating whether Openstack networking should manage the -# creation and removal of VLAN interfaces for provider networks on the Nexus -# switches. If the flag is set to False then Openstack will not create or -# remove VLAN interfaces for provider networks, and the administrator needs -# to manage these interfaces manually or by external orchestration. -# -# provider_vlan_auto_create = True - -# (BoolOpt) A flag indicating whether Openstack networking should manage -# the adding and removing of provider VLANs from trunk ports on the Nexus -# switches. If the flag is set to False then Openstack will not add or -# remove provider VLANs from trunk ports, and the administrator needs to -# manage these operations manually or by external orchestration. -# -# provider_vlan_auto_trunk = True - -# (StrOpt) Period-separated module path to the model class to use for -# the Cisco neutron plugin. -# -# model_class = neutron.plugins.cisco.models.virt_phy_sw_v2.VirtualPhysicalSwitchModelV2 - -# (BoolOpt) A flag to enable Layer 3 support on the Nexus switches. -# Note: This feature is not supported on all models/versions of Cisco -# Nexus switches. To use this feature, all of the Nexus switches in the -# deployment must support it. -# nexus_l3_enable = False - -# (BoolOpt) A flag to enable round robin scheduling of routers for SVI. -# svi_round_robin = False - -# Cisco Nexus Switch configurations. -# Each switch to be managed by Openstack Neutron must be configured here. -# -# N1KV Format. -# [N1KV:] -# username= -# password= -# -# Example: -# [N1KV:2.2.2.2] -# username=admin -# password=mySecretPassword - -[cisco_n1k] - -# (StrOpt) Specify the name of the integration bridge to which the VIFs are -# attached. -# Default value: br-int -# integration_bridge = br-int - -# (StrOpt) Name of the policy profile to be associated with a port when no -# policy profile is specified during port creates. -# Default value: service_profile -# default_policy_profile = service_profile - -# (StrOpt) Name of the policy profile to be associated with a port owned by -# network node (dhcp, router). -# Default value: dhcp_pp -# network_node_policy_profile = dhcp_pp - -# (StrOpt) Name of the network profile to be associated with a network when no -# network profile is specified during network creates. Admin should pre-create -# a network profile with this name. -# Default value: default_network_profile -# default_network_profile = network_pool - -# (IntOpt) Time in seconds for which the plugin polls the VSM for updates in -# policy profiles. -# Default value: 60 -# poll_duration = 60 - -# (BoolOpt) Specify whether tenants are restricted from accessing all the -# policy profiles. -# Default value: False, indicating all tenants can access all policy profiles. -# -# restrict_policy_profiles = False - -# (IntOpt) Number of threads to use to make HTTP requests to the VSM. -# Default value: 4 -# http_pool_size = 4 - -# (IntOpt) Timeout duration in seconds for the http request -# Default value: 15 -# http_timeout = 15 - -# (BoolOpt) Specify whether tenants are restricted from accessing network -# profiles belonging to other tenants. -# Default value: True, indicating other tenants cannot access network -# profiles belonging to a tenant. -# -# restrict_network_profiles = True diff --git a/neutron/db/migration/alembic_migrations/versions/HEADS b/neutron/db/migration/alembic_migrations/versions/HEADS index 9928899ef..2200a5384 100644 --- a/neutron/db/migration/alembic_migrations/versions/HEADS +++ b/neutron/db/migration/alembic_migrations/versions/HEADS @@ -1,2 +1,2 @@ -11926bcfe72d 34af2b5c5a59 +4af11ca47297 diff --git a/neutron/db/migration/alembic_migrations/versions/liberty/contract/4af11ca47297_drop_cisco_monolithic_tables.py b/neutron/db/migration/alembic_migrations/versions/liberty/contract/4af11ca47297_drop_cisco_monolithic_tables.py new file mode 100644 index 000000000..ee39fa952 --- /dev/null +++ b/neutron/db/migration/alembic_migrations/versions/liberty/contract/4af11ca47297_drop_cisco_monolithic_tables.py @@ -0,0 +1,44 @@ +# Copyright 2015 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. +# + +"""Drop cisco monolithic tables + +Revision ID: 4af11ca47297 +Revises: 11926bcfe72d +Create Date: 2015-08-13 08:01:19.709839 + +""" + +# revision identifiers, used by Alembic. +revision = '4af11ca47297' +down_revision = '11926bcfe72d' + +from alembic import op + + +def upgrade(): + op.drop_table('cisco_n1kv_port_bindings') + op.drop_table('cisco_n1kv_network_bindings') + op.drop_table('cisco_n1kv_multi_segments') + op.drop_table('cisco_provider_networks') + op.drop_table('cisco_n1kv_trunk_segments') + op.drop_table('cisco_n1kv_vmnetworks') + op.drop_table('cisco_n1kv_profile_bindings') + op.drop_table('cisco_qos_policies') + op.drop_table('cisco_credentials') + op.drop_table('cisco_n1kv_vlan_allocations') + op.drop_table('cisco_n1kv_vxlan_allocations') + op.drop_table('cisco_network_profiles') + op.drop_table('cisco_policy_profiles') diff --git a/neutron/db/migration/models/head.py b/neutron/db/migration/models/head.py index 72e5e660e..c4ca5e2f3 100644 --- a/neutron/db/migration/models/head.py +++ b/neutron/db/migration/models/head.py @@ -51,8 +51,6 @@ from neutron.plugins.bigswitch.db import consistency_db # noqa from neutron.plugins.bigswitch import routerrule_db # noqa from neutron.plugins.brocade.db import models as brocade_models # noqa from neutron.plugins.cisco.db.l3 import l3_models # noqa -from neutron.plugins.cisco.db import n1kv_models_v2 # noqa -from neutron.plugins.cisco.db import network_models_v2 # noqa from neutron.plugins.ml2.drivers.brocade.db import ( # noqa models as ml2_brocade_models) from neutron.plugins.ml2.drivers import type_flat # noqa diff --git a/neutron/plugins/cisco/README b/neutron/plugins/cisco/README deleted file mode 100644 index 2bedb75b1..000000000 --- a/neutron/plugins/cisco/README +++ /dev/null @@ -1,7 +0,0 @@ -Cisco Neutron Virtual Network Plugin - -This plugin implements Neutron v2 APIs and helps configure -topologies consisting of virtual and physical switches. - -For more details on use please refer to: -http://wiki.openstack.org/cisco-neutron diff --git a/neutron/plugins/cisco/common/cisco_constants.py b/neutron/plugins/cisco/common/cisco_constants.py index b348921bc..43e6e4689 100644 --- a/neutron/plugins/cisco/common/cisco_constants.py +++ b/neutron/plugins/cisco/common/cisco_constants.py @@ -13,96 +13,7 @@ # under the License. -# Attachment attributes -INSTANCE_ID = 'instance_id' -TENANT_ID = 'tenant_id' -TENANT_NAME = 'tenant_name' -HOST_NAME = 'host_name' - -# Network attributes -NET_ID = 'id' -NET_NAME = 'name' -NET_VLAN_ID = 'vlan_id' -NET_VLAN_NAME = 'vlan_name' -NET_PORTS = 'ports' - -CREDENTIAL_ID = 'credential_id' -CREDENTIAL_NAME = 'credential_name' -CREDENTIAL_USERNAME = 'user_name' -CREDENTIAL_PASSWORD = 'password' -CREDENTIAL_TYPE = 'type' -MASKED_PASSWORD = '********' - -USERNAME = 'username' -PASSWORD = 'password' - -LOGGER_COMPONENT_NAME = "cisco_plugin" - -VSWITCH_PLUGIN = 'vswitch_plugin' - -DEVICE_IP = 'device_ip' - -NETWORK_ADMIN = 'network_admin' - -NETWORK = 'network' -PORT = 'port' -BASE_PLUGIN_REF = 'base_plugin_ref' -CONTEXT = 'context' -SUBNET = 'subnet' - -#### N1Kv CONSTANTS -# Special vlan_id value in n1kv_vlan_allocations table indicating flat network -FLAT_VLAN_ID = -1 - -# Topic for tunnel notifications between the plugin and agent -TUNNEL = 'tunnel' - -# Maximum VXLAN range configurable for one network profile. -MAX_VXLAN_RANGE = 1000000 - -# Values for network_type -NETWORK_TYPE_FLAT = 'flat' -NETWORK_TYPE_VLAN = 'vlan' -NETWORK_TYPE_VXLAN = 'vxlan' -NETWORK_TYPE_LOCAL = 'local' -NETWORK_TYPE_NONE = 'none' -NETWORK_TYPE_TRUNK = 'trunk' -NETWORK_TYPE_MULTI_SEGMENT = 'multi-segment' - -# Values for network sub_type -NETWORK_TYPE_OVERLAY = 'overlay' -NETWORK_SUBTYPE_NATIVE_VXLAN = 'native_vxlan' -NETWORK_SUBTYPE_TRUNK_VLAN = NETWORK_TYPE_VLAN -NETWORK_SUBTYPE_TRUNK_VXLAN = NETWORK_TYPE_OVERLAY - -# Prefix for VM Network name -VM_NETWORK_NAME_PREFIX = 'vmn_' - -SET = 'set' -INSTANCE = 'instance' -PROPERTIES = 'properties' -NAME = 'name' -ID = 'id' -POLICY = 'policy' TENANT_ID_NOT_SET = 'TENANT_ID_NOT_SET' -ENCAPSULATIONS = 'encapsulations' -STATE = 'state' -ONLINE = 'online' -MAPPINGS = 'mappings' -MAPPING = 'mapping' -SEGMENTS = 'segments' -SEGMENT = 'segment' -BRIDGE_DOMAIN_SUFFIX = '_bd' -LOGICAL_NETWORK_SUFFIX = '_log_net' -ENCAPSULATION_PROFILE_SUFFIX = '_profile' - -UUID_LENGTH = 36 - -# N1KV vlan and vxlan segment range -N1KV_VLAN_RESERVED_MIN = 3968 -N1KV_VLAN_RESERVED_MAX = 4047 -N1KV_VXLAN_MIN = 4096 -N1KV_VXLAN_MAX = 16000000 # Type and topic for Cisco cfg agent # ================================== @@ -112,7 +23,3 @@ AGENT_TYPE_CFG = 'Cisco cfg agent' CFG_AGENT = 'cisco_cfg_agent' # Topic for routing service helper in Cisco configuration agent CFG_AGENT_L3_ROUTING = 'cisco_cfg_agent_l3_routing' - -# Values for network profile fields -ADD_TENANTS = 'add_tenants' -REMOVE_TENANTS = 'remove_tenants' diff --git a/neutron/plugins/cisco/common/cisco_credentials_v2.py b/neutron/plugins/cisco/common/cisco_credentials_v2.py deleted file mode 100644 index 61112da57..000000000 --- a/neutron/plugins/cisco/common/cisco_credentials_v2.py +++ /dev/null @@ -1,53 +0,0 @@ -# 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. - - -from neutron.plugins.cisco.common import cisco_constants as const -from neutron.plugins.cisco.common import cisco_exceptions as cexc -from neutron.plugins.cisco.common import config -from neutron.plugins.cisco.db import network_db_v2 as cdb - - -class Store(object): - """Credential Store.""" - - @staticmethod - def initialize(): - dev_dict = config.get_device_dictionary() - for key in dev_dict: - dev_id, dev_ip, dev_key = key - if dev_key == const.USERNAME: - try: - cdb.add_credential( - dev_ip, - dev_dict[dev_id, dev_ip, const.USERNAME], - dev_dict[dev_id, dev_ip, const.PASSWORD], - dev_id) - except cexc.CredentialAlreadyExists: - # We are quietly ignoring this, since it only happens - # if this class module is loaded more than once, in - # which case, the credentials are already populated - pass - - @staticmethod - def get_username(cred_name): - """Get the username.""" - credential = cdb.get_credential_name(cred_name) - return credential[const.CREDENTIAL_USERNAME] - - @staticmethod - def get_password(cred_name): - """Get the password.""" - credential = cdb.get_credential_name(cred_name) - return credential[const.CREDENTIAL_PASSWORD] diff --git a/neutron/plugins/cisco/common/cisco_exceptions.py b/neutron/plugins/cisco/common/cisco_exceptions.py deleted file mode 100644 index fd7a38f54..000000000 --- a/neutron/plugins/cisco/common/cisco_exceptions.py +++ /dev/null @@ -1,236 +0,0 @@ -# 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. - -"""Exceptions used by the Cisco plugin.""" - -from neutron.common import exceptions - - -class NetworkSegmentIDNotFound(exceptions.NeutronException): - """Segmentation ID for network is not found.""" - message = _("Segmentation ID for network %(net_id)s is not found.") - - -class NoMoreNics(exceptions.NeutronException): - """No more dynamic NICs are available in the system.""" - message = _("Unable to complete operation. No more dynamic NICs are " - "available in the system.") - - -class NetworkVlanBindingAlreadyExists(exceptions.NeutronException): - """Binding cannot be created, since it already exists.""" - message = _("NetworkVlanBinding for %(vlan_id)s and network " - "%(network_id)s already exists.") - - -class VlanIDNotFound(exceptions.NeutronException): - """VLAN ID cannot be found.""" - message = _("Vlan ID %(vlan_id)s not found.") - - -class VlanIDOutsidePool(exceptions.NeutronException): - """VLAN ID cannot be allocated, since it is outside the configured pool.""" - message = _("Unable to complete operation. VLAN ID exists outside of the " - "configured network segment range.") - - -class VlanIDNotAvailable(exceptions.NeutronException): - """No VLAN ID available.""" - message = _("No Vlan ID available.") - - -class QosNotFound(exceptions.NeutronException): - """QoS level with this ID cannot be found.""" - message = _("QoS level %(qos_id)s could not be found " - "for tenant %(tenant_id)s.") - - -class QosNameAlreadyExists(exceptions.NeutronException): - """QoS Name already exists.""" - message = _("QoS level with name %(qos_name)s already exists " - "for tenant %(tenant_id)s.") - - -class CredentialNotFound(exceptions.NeutronException): - """Credential with this ID cannot be found.""" - message = _("Credential %(credential_id)s could not be found.") - - -class CredentialNameNotFound(exceptions.NeutronException): - """Credential Name could not be found.""" - message = _("Credential %(credential_name)s could not be found.") - - -class CredentialAlreadyExists(exceptions.NeutronException): - """Credential already exists.""" - message = _("Credential %(credential_name)s already exists.") - - -class ProviderNetworkExists(exceptions.NeutronException): - """Provider network already exists.""" - message = _("Provider network %s already exists") - - -class NexusComputeHostNotConfigured(exceptions.NeutronException): - """Connection to compute host is not configured.""" - message = _("Connection to %(host)s is not configured.") - - -class NexusConnectFailed(exceptions.NeutronException): - """Failed to connect to Nexus switch.""" - message = _("Unable to connect to Nexus %(nexus_host)s. Reason: %(exc)s.") - - -class NexusConfigFailed(exceptions.NeutronException): - """Failed to configure Nexus switch.""" - message = _("Failed to configure Nexus: %(config)s. Reason: %(exc)s.") - - -class NexusPortBindingNotFound(exceptions.NeutronException): - """NexusPort Binding is not present.""" - message = _("Nexus Port Binding (%(filters)s) is not present.") - - def __init__(self, **kwargs): - filters = ','.join('%s=%s' % i for i in kwargs.items()) - super(NexusPortBindingNotFound, self).__init__(filters=filters) - - -class NoNexusSviSwitch(exceptions.NeutronException): - """No usable nexus switch found.""" - message = _("No usable Nexus switch found to create SVI interface.") - - -class PortVnicBindingAlreadyExists(exceptions.NeutronException): - """PortVnic Binding already exists.""" - message = _("PortVnic Binding %(port_id)s already exists.") - - -class PortVnicNotFound(exceptions.NeutronException): - """PortVnic Binding is not present.""" - message = _("PortVnic Binding %(port_id)s is not present.") - - -class SubnetNotSpecified(exceptions.NeutronException): - """Subnet id not specified.""" - message = _("No subnet_id specified for router gateway.") - - -class SubnetInterfacePresent(exceptions.NeutronException): - """Subnet SVI interface already exists.""" - message = _("Subnet %(subnet_id)s has an interface on %(router_id)s.") - - -class PortIdForNexusSvi(exceptions.NeutronException): - """Port Id specified for Nexus SVI.""" - message = _('Nexus hardware router gateway only uses Subnet Ids.') - - -class InvalidDetach(exceptions.NeutronException): - message = _("Unable to unplug the attachment %(att_id)s from port " - "%(port_id)s for network %(net_id)s. The attachment " - "%(att_id)s does not exist.") - - -class PolicyProfileAlreadyExists(exceptions.NeutronException): - """Policy Profile cannot be created since it already exists.""" - message = _("Policy Profile %(profile_id)s " - "already exists.") - - -class PolicyProfileIdNotFound(exceptions.NotFound): - """Policy Profile with the given UUID cannot be found.""" - message = _("Policy Profile %(profile_id)s could not be found.") - - -class PolicyProfileNameNotFound(exceptions.NotFound): - """Policy Profile with the given name cannot be found.""" - message = _("Policy Profile %(profile_name)s could not be found.") - - -class NetworkProfileAlreadyExists(exceptions.NeutronException): - """Network Profile cannot be created since it already exists.""" - message = _("Network Profile %(profile_id)s " - "already exists.") - - -class NetworkProfileNotFound(exceptions.NotFound): - """Network Profile with the given UUID/name cannot be found.""" - message = _("Network Profile %(profile)s could not be found.") - - -class NetworkProfileInUse(exceptions.InUse): - """Network Profile with the given UUID is in use.""" - message = _("One or more network segments belonging to network " - "profile %(profile)s is in use.") - - -class NoMoreNetworkSegments(exceptions.NoNetworkAvailable): - """Network segments exhausted for the given network profile.""" - message = _("No more segments available in network segment pool " - "%(network_profile_name)s.") - - -class VMNetworkNotFound(exceptions.NotFound): - """VM Network with the given name cannot be found.""" - message = _("VM Network %(name)s could not be found.") - - -class VxlanIDInUse(exceptions.InUse): - """VXLAN ID is in use.""" - message = _("Unable to create the network. " - "The VXLAN ID %(vxlan_id)s is in use.") - - -class VxlanIDNotFound(exceptions.NotFound): - """VXLAN ID cannot be found.""" - message = _("Vxlan ID %(vxlan_id)s not found.") - - -class VxlanIDOutsidePool(exceptions.NeutronException): - """VXLAN ID cannot be allocated, as it is outside the configured pool.""" - message = _("Unable to complete operation. VXLAN ID exists outside of the " - "configured network segment range.") - - -class VSMConnectionFailed(exceptions.ServiceUnavailable): - """Connection to VSM failed.""" - message = _("Connection to VSM failed: %(reason)s.") - - -class VSMError(exceptions.NeutronException): - """Error has occurred on the VSM.""" - message = _("Internal VSM Error: %(reason)s.") - - -class NetworkBindingNotFound(exceptions.NotFound): - """Network Binding for network cannot be found.""" - message = _("Network Binding for network %(network_id)s could " - "not be found.") - - -class PortBindingNotFound(exceptions.NotFound): - """Port Binding for port cannot be found.""" - message = _("Port Binding for port %(port_id)s could " - "not be found.") - - -class ProfileTenantBindingNotFound(exceptions.NotFound): - """Profile to Tenant binding for given profile ID cannot be found.""" - message = _("Profile-Tenant binding for profile %(profile_id)s could " - "not be found.") - - -class NoClusterFound(exceptions.NotFound): - """No service cluster found to perform multi-segment bridging.""" - message = _("No service cluster found to perform multi-segment bridging.") diff --git a/neutron/plugins/cisco/common/cisco_faults.py b/neutron/plugins/cisco/common/cisco_faults.py deleted file mode 100644 index a2df46c06..000000000 --- a/neutron/plugins/cisco/common/cisco_faults.py +++ /dev/null @@ -1,134 +0,0 @@ -# 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. - -import webob.dec - -from neutron import wsgi - - -class Fault(webob.exc.HTTPException): - """Error codes for API faults.""" - - _fault_names = { - 400: "malformedRequest", - 401: "unauthorized", - 451: "CredentialNotFound", - 452: "QoSNotFound", - 453: "NovatenantNotFound", - 454: "MultiportNotFound", - 470: "serviceUnavailable", - 471: "pluginFault" - } - - def __init__(self, exception): - """Create a Fault for the given webob.exc.exception.""" - self.wrapped_exc = exception - - @webob.dec.wsgify(RequestClass=wsgi.Request) - def __call__(self, req): - """Generate a WSGI response. - - Response is generated based on the exception passed to constructor. - """ - # Replace the body with fault details. - code = self.wrapped_exc.status_int - fault_name = self._fault_names.get(code, "neutronServiceFault") - fault_data = { - fault_name: { - 'code': code, - 'message': self.wrapped_exc.explanation}} - # 'code' is an attribute on the fault tag itself - content_type = req.best_match_content_type() - self.wrapped_exc.body = wsgi.Serializer().serialize( - fault_data, content_type) - self.wrapped_exc.content_type = content_type - return self.wrapped_exc - - -class PortNotFound(webob.exc.HTTPClientError): - """PortNotFound exception. - - subclass of :class:`~HTTPClientError` - - This indicates that the server did not find the port specified - in the HTTP request for a given network - - code: 430, title: Port not Found - """ - code = 430 - title = _('Port not Found') - explanation = _('Unable to find a port with the specified identifier.') - - -class CredentialNotFound(webob.exc.HTTPClientError): - """CredentialNotFound exception. - - subclass of :class:`~HTTPClientError` - - This indicates that the server did not find the Credential specified - in the HTTP request - - code: 451, title: Credential not Found - """ - code = 451 - title = _('Credential Not Found') - explanation = _('Unable to find a Credential with' - ' the specified identifier.') - - -class QosNotFound(webob.exc.HTTPClientError): - """QosNotFound exception. - - subclass of :class:`~HTTPClientError` - - This indicates that the server did not find the QoS specified - in the HTTP request - - code: 452, title: QoS not Found - """ - code = 452 - title = _('QoS Not Found') - explanation = _('Unable to find a QoS with' - ' the specified identifier.') - - -class NovatenantNotFound(webob.exc.HTTPClientError): - """NovatenantNotFound exception. - - subclass of :class:`~HTTPClientError` - - This indicates that the server did not find the Novatenant specified - in the HTTP request - - code: 453, title: Nova tenant not Found - """ - code = 453 - title = _('Nova tenant Not Found') - explanation = _('Unable to find a Novatenant with' - ' the specified identifier.') - - -class RequestedStateInvalid(webob.exc.HTTPClientError): - """RequestedStateInvalid exception. - - subclass of :class:`~HTTPClientError` - - This indicates that the server could not update the port state - to the request value - - code: 431, title: Requested State Invalid - """ - code = 431 - title = _('Requested State Invalid') - explanation = _('Unable to update port state with specified value.') diff --git a/neutron/plugins/cisco/common/config.py b/neutron/plugins/cisco/common/config.py deleted file mode 100644 index 99676b631..000000000 --- a/neutron/plugins/cisco/common/config.py +++ /dev/null @@ -1,138 +0,0 @@ -# Copyright 2013 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. - -from oslo_config import cfg - - -cisco_opts = [ - cfg.StrOpt('vlan_name_prefix', default='q-', - help=_("VLAN Name prefix")), - cfg.StrOpt('provider_vlan_name_prefix', default='p-', - help=_("VLAN Name prefix for provider vlans")), - cfg.BoolOpt('provider_vlan_auto_create', default=True, - help=_('Provider VLANs are automatically created as needed ' - 'on the Nexus switch')), - cfg.BoolOpt('provider_vlan_auto_trunk', default=True, - help=_('Provider VLANs are automatically trunked as needed ' - 'on the ports of the Nexus switch')), - cfg.BoolOpt('nexus_l3_enable', default=False, - help=_("Enable L3 support on the Nexus switches")), - cfg.BoolOpt('svi_round_robin', default=False, - help=_("Distribute SVI interfaces over all switches")), - cfg.StrOpt('model_class', - default='neutron.plugins.cisco.models.virt_phy_sw_v2.' - 'VirtualPhysicalSwitchModelV2', - help=_("Model Class")), -] - -cisco_n1k_opts = [ - cfg.StrOpt('integration_bridge', default='br-int', - help=_("N1K Integration Bridge")), - cfg.BoolOpt('enable_tunneling', default=True, - help=_("N1K Enable Tunneling")), - cfg.StrOpt('tunnel_bridge', default='br-tun', - help=_("N1K Tunnel Bridge")), - cfg.StrOpt('local_ip', default='10.0.0.3', - help=_("N1K Local IP")), - cfg.StrOpt('tenant_network_type', default='local', - help=_("N1K Tenant Network Type")), - cfg.StrOpt('bridge_mappings', default='', - help=_("N1K Bridge Mappings")), - cfg.StrOpt('vxlan_id_ranges', default='5000:10000', - help=_("N1K VXLAN ID Ranges")), - cfg.StrOpt('network_vlan_ranges', default='vlan:1:4095', - help=_("N1K Network VLAN Ranges")), - cfg.StrOpt('default_network_profile', default='default_network_profile', - help=_("N1K default network profile")), - cfg.StrOpt('default_policy_profile', default='service_profile', - help=_("N1K default policy profile")), - cfg.StrOpt('network_node_policy_profile', default='dhcp_pp', - help=_("N1K policy profile for network node")), - cfg.IntOpt('poll_duration', default=60, - help=_("N1K Policy profile polling duration in seconds")), - cfg.BoolOpt('restrict_policy_profiles', default=False, - help=_("Restrict the visibility of policy profiles to the " - "tenants")), - cfg.IntOpt('http_pool_size', default=4, - help=_("Number of threads to use to make HTTP requests")), - cfg.IntOpt('http_timeout', default=15, - help=_("N1K http timeout duration in seconds")), - cfg.BoolOpt('restrict_network_profiles', default=True, - help=_("Restrict tenants from accessing network profiles " - "belonging to some other tenant")), - -] - -cfg.CONF.register_opts(cisco_opts, "CISCO") -cfg.CONF.register_opts(cisco_n1k_opts, "CISCO_N1K") - -# shortcuts -CONF = cfg.CONF -CISCO = cfg.CONF.CISCO -CISCO_N1K = cfg.CONF.CISCO_N1K - -# -# device_dictionary - Contains all external device configuration. -# -# When populated the device dictionary format is: -# {('', '', ''): '', ...} -# -# Example: -# {('NEXUS_SWITCH', '1.1.1.1', 'username'): 'admin', -# ('NEXUS_SWITCH', '1.1.1.1', 'password'): 'mySecretPassword', -# ('NEXUS_SWITCH', '1.1.1.1', 'compute1'): '1/1', ...} -# -device_dictionary = {} - -# -# first_device_ip - IP address of first switch discovered in config -# -# Used for SVI placement when round-robin placement is disabled -# -first_device_ip = None - - -class CiscoConfigOptions(object): - """Cisco Configuration Options Class.""" - - def __init__(self): - self._create_device_dictionary() - - def _create_device_dictionary(self): - """ - Create the device dictionary from the cisco_plugins.ini - device supported sections. Ex. NEXUS_SWITCH, N1KV. - """ - - global first_device_ip - - multi_parser = cfg.MultiConfigParser() - read_ok = multi_parser.read(CONF.config_file) - - if len(read_ok) != len(CONF.config_file): - raise cfg.Error(_("Some config files were not parsed properly")) - - first_device_ip = None - for parsed_file in multi_parser.parsed: - for parsed_item in parsed_file.keys(): - dev_id, sep, dev_ip = parsed_item.partition(':') - if dev_id.lower() == 'n1kv': - for dev_key, value in parsed_file[parsed_item].items(): - if dev_ip and not first_device_ip: - first_device_ip = dev_ip - device_dictionary[dev_id, dev_ip, dev_key] = value[0] - - -def get_device_dictionary(): - return device_dictionary diff --git a/neutron/plugins/cisco/db/n1kv_db_v2.py b/neutron/plugins/cisco/db/n1kv_db_v2.py deleted file mode 100644 index 078e52298..000000000 --- a/neutron/plugins/cisco/db/n1kv_db_v2.py +++ /dev/null @@ -1,1673 +0,0 @@ -# Copyright 2013 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. - -import re - -import netaddr -from oslo_log import log as logging -from sqlalchemy.orm import exc -from sqlalchemy import sql - -from neutron.api.v2 import attributes -from neutron.common import exceptions as n_exc -import neutron.db.api as db -from neutron.db import models_v2 -from neutron.i18n import _LW -from neutron.plugins.cisco.common import cisco_constants as c_const -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.common import config as c_conf -from neutron.plugins.cisco.db import n1kv_models_v2 -from neutron.plugins.common import constants as p_const - - -LOG = logging.getLogger(__name__) - - -def del_trunk_segment_binding(db_session, trunk_segment_id, segment_pairs): - """ - Delete a trunk network binding. - - :param db_session: database session - :param trunk_segment_id: UUID representing the trunk network - :param segment_pairs: List of segment UUIDs in pair - representing the segments that are trunked - """ - with db_session.begin(subtransactions=True): - for (segment_id, dot1qtag) in segment_pairs: - (db_session.query(n1kv_models_v2.N1kvTrunkSegmentBinding). - filter_by(trunk_segment_id=trunk_segment_id, - segment_id=segment_id, - dot1qtag=dot1qtag).delete()) - alloc = (db_session.query(n1kv_models_v2. - N1kvTrunkSegmentBinding). - filter_by(trunk_segment_id=trunk_segment_id).first()) - if not alloc: - binding = get_network_binding(db_session, trunk_segment_id) - binding.physical_network = None - - -def del_multi_segment_binding(db_session, multi_segment_id, segment_pairs): - """ - Delete a multi-segment network binding. - - :param db_session: database session - :param multi_segment_id: UUID representing the multi-segment network - :param segment_pairs: List of segment UUIDs in pair - representing the segments that are bridged - """ - with db_session.begin(subtransactions=True): - for (segment1_id, segment2_id) in segment_pairs: - (db_session.query(n1kv_models_v2. - N1kvMultiSegmentNetworkBinding).filter_by( - multi_segment_id=multi_segment_id, - segment1_id=segment1_id, - segment2_id=segment2_id).delete()) - - -def add_trunk_segment_binding(db_session, trunk_segment_id, segment_pairs): - """ - Create a trunk network binding. - - :param db_session: database session - :param trunk_segment_id: UUID representing the multi-segment network - :param segment_pairs: List of segment UUIDs in pair - representing the segments to be trunked - """ - with db_session.begin(subtransactions=True): - binding = get_network_binding(db_session, trunk_segment_id) - for (segment_id, tag) in segment_pairs: - if not binding.physical_network: - member_seg_binding = get_network_binding(db_session, - segment_id) - binding.physical_network = member_seg_binding.physical_network - trunk_segment_binding = ( - n1kv_models_v2.N1kvTrunkSegmentBinding( - trunk_segment_id=trunk_segment_id, - segment_id=segment_id, dot1qtag=tag)) - db_session.add(trunk_segment_binding) - - -def add_multi_segment_binding(db_session, multi_segment_id, segment_pairs): - """ - Create a multi-segment network binding. - - :param db_session: database session - :param multi_segment_id: UUID representing the multi-segment network - :param segment_pairs: List of segment UUIDs in pair - representing the segments to be bridged - """ - with db_session.begin(subtransactions=True): - for (segment1_id, segment2_id) in segment_pairs: - multi_segment_binding = ( - n1kv_models_v2.N1kvMultiSegmentNetworkBinding( - multi_segment_id=multi_segment_id, - segment1_id=segment1_id, - segment2_id=segment2_id)) - db_session.add(multi_segment_binding) - - -def add_multi_segment_encap_profile_name(db_session, multi_segment_id, - segment_pair, profile_name): - """ - Add the encapsulation profile name to the multi-segment network binding. - - :param db_session: database session - :param multi_segment_id: UUID representing the multi-segment network - :param segment_pair: set containing the segment UUIDs that are bridged - """ - with db_session.begin(subtransactions=True): - binding = get_multi_segment_network_binding(db_session, - multi_segment_id, - segment_pair) - binding.encap_profile_name = profile_name - - -def get_multi_segment_network_binding(db_session, - multi_segment_id, segment_pair): - """ - Retrieve multi-segment network binding. - - :param db_session: database session - :param multi_segment_id: UUID representing the trunk network whose binding - is to fetch - :param segment_pair: set containing the segment UUIDs that are bridged - :returns: binding object - """ - try: - (segment1_id, segment2_id) = segment_pair - return (db_session.query( - n1kv_models_v2.N1kvMultiSegmentNetworkBinding). - filter_by(multi_segment_id=multi_segment_id, - segment1_id=segment1_id, - segment2_id=segment2_id)).one() - except exc.NoResultFound: - raise c_exc.NetworkBindingNotFound(network_id=multi_segment_id) - - -def get_multi_segment_members(db_session, multi_segment_id): - """ - Retrieve all the member segments of a multi-segment network. - - :param db_session: database session - :param multi_segment_id: UUID representing the multi-segment network - :returns: a list of tuples representing the mapped segments - """ - with db_session.begin(subtransactions=True): - allocs = (db_session.query( - n1kv_models_v2.N1kvMultiSegmentNetworkBinding). - filter_by(multi_segment_id=multi_segment_id)) - return [(a.segment1_id, a.segment2_id) for a in allocs] - - -def get_multi_segment_encap_dict(db_session, multi_segment_id): - """ - Retrieve the encapsulation profiles for every segment pairs bridged. - - :param db_session: database session - :param multi_segment_id: UUID representing the multi-segment network - :returns: a dictionary of lists containing the segment pairs in sets - """ - with db_session.begin(subtransactions=True): - encap_dict = {} - allocs = (db_session.query( - n1kv_models_v2.N1kvMultiSegmentNetworkBinding). - filter_by(multi_segment_id=multi_segment_id)) - for alloc in allocs: - if alloc.encap_profile_name not in encap_dict: - encap_dict[alloc.encap_profile_name] = [] - seg_pair = (alloc.segment1_id, alloc.segment2_id) - encap_dict[alloc.encap_profile_name].append(seg_pair) - return encap_dict - - -def get_trunk_network_binding(db_session, trunk_segment_id, segment_pair): - """ - Retrieve trunk network binding. - - :param db_session: database session - :param trunk_segment_id: UUID representing the trunk network whose binding - is to fetch - :param segment_pair: set containing the segment_id and dot1qtag - :returns: binding object - """ - try: - (segment_id, dot1qtag) = segment_pair - return (db_session.query(n1kv_models_v2.N1kvTrunkSegmentBinding). - filter_by(trunk_segment_id=trunk_segment_id, - segment_id=segment_id, - dot1qtag=dot1qtag)).one() - except exc.NoResultFound: - raise c_exc.NetworkBindingNotFound(network_id=trunk_segment_id) - - -def get_trunk_members(db_session, trunk_segment_id): - """ - Retrieve all the member segments of a trunk network. - - :param db_session: database session - :param trunk_segment_id: UUID representing the trunk network - :returns: a list of tuples representing the segment and their - corresponding dot1qtag - """ - with db_session.begin(subtransactions=True): - allocs = (db_session.query(n1kv_models_v2.N1kvTrunkSegmentBinding). - filter_by(trunk_segment_id=trunk_segment_id)) - return [(a.segment_id, a.dot1qtag) for a in allocs] - - -def is_trunk_member(db_session, segment_id): - """ - Checks if a segment is a member of a trunk segment. - - :param db_session: database session - :param segment_id: UUID of the segment to be checked - :returns: boolean - """ - with db_session.begin(subtransactions=True): - ret = (db_session.query(n1kv_models_v2.N1kvTrunkSegmentBinding). - filter_by(segment_id=segment_id).first()) - return bool(ret) - - -def is_multi_segment_member(db_session, segment_id): - """ - Checks if a segment is a member of a multi-segment network. - - :param db_session: database session - :param segment_id: UUID of the segment to be checked - :returns: boolean - """ - with db_session.begin(subtransactions=True): - ret1 = (db_session.query( - n1kv_models_v2.N1kvMultiSegmentNetworkBinding). - filter_by(segment1_id=segment_id).first()) - ret2 = (db_session.query( - n1kv_models_v2.N1kvMultiSegmentNetworkBinding). - filter_by(segment2_id=segment_id).first()) - return bool(ret1 or ret2) - - -def get_network_binding(db_session, network_id): - """ - Retrieve network binding. - - :param db_session: database session - :param network_id: UUID representing the network whose binding is - to fetch - :returns: binding object - """ - try: - return (db_session.query(n1kv_models_v2.N1kvNetworkBinding). - filter_by(network_id=network_id). - one()) - except exc.NoResultFound: - raise c_exc.NetworkBindingNotFound(network_id=network_id) - - -def add_network_binding(db_session, network_id, network_type, - physical_network, segmentation_id, - multicast_ip, network_profile_id, add_segments): - """ - Create network binding. - - :param db_session: database session - :param network_id: UUID representing the network - :param network_type: string representing type of network (VLAN, OVERLAY, - MULTI_SEGMENT or TRUNK) - :param physical_network: Only applicable for VLAN networks. It - represents a L2 Domain - :param segmentation_id: integer representing VLAN or VXLAN ID - :param multicast_ip: Native VXLAN technology needs a multicast IP to be - associated with every VXLAN ID to deal with broadcast - packets. A single multicast IP can be shared by - multiple VXLAN IDs. - :param network_profile_id: network profile ID based on which this network - is created - :param add_segments: List of segment UUIDs in pairs to be added to either a - multi-segment or trunk network - """ - with db_session.begin(subtransactions=True): - binding = n1kv_models_v2.N1kvNetworkBinding( - network_id=network_id, - network_type=network_type, - physical_network=physical_network, - segmentation_id=segmentation_id, - multicast_ip=multicast_ip, - profile_id=network_profile_id) - db_session.add(binding) - if add_segments is None: - pass - elif network_type == c_const.NETWORK_TYPE_MULTI_SEGMENT: - add_multi_segment_binding(db_session, network_id, add_segments) - elif network_type == c_const.NETWORK_TYPE_TRUNK: - add_trunk_segment_binding(db_session, network_id, add_segments) - - -def get_segment_range(network_profile): - """ - Get the segment range min and max for a network profile. - - :params network_profile: object of type network profile - :returns: integer values representing minimum and maximum segment - range value - """ - # Sort the range to ensure min, max is in order - seg_min, seg_max = sorted( - int(i) for i in network_profile.segment_range.split('-')) - LOG.debug("seg_min %(seg_min)s, seg_max %(seg_max)s", - {'seg_min': seg_min, 'seg_max': seg_max}) - return seg_min, seg_max - - -def get_multicast_ip(network_profile): - """ - Retrieve a multicast ip from the defined pool. - - :params network_profile: object of type network profile - :returns: string representing multicast IP - """ - # Round robin multicast ip allocation - min_ip, max_ip = _get_multicast_ip_range(network_profile) - addr_list = list((netaddr.iter_iprange(min_ip, max_ip))) - mul_ip_str = str(addr_list[network_profile.multicast_ip_index]) - - network_profile.multicast_ip_index += 1 - if network_profile.multicast_ip_index == len(addr_list): - network_profile.multicast_ip_index = 0 - return mul_ip_str - - -def _get_multicast_ip_range(network_profile): - """ - Helper method to retrieve minimum and maximum multicast ip. - - :params network_profile: object of type network profile - :returns: two strings representing minimum multicast ip and - maximum multicast ip - """ - # Assumption: ip range belongs to the same subnet - # Assumption: ip range is already sorted - return network_profile.multicast_ip_range.split('-') - - -def get_port_binding(db_session, port_id): - """ - Retrieve port binding. - - :param db_session: database session - :param port_id: UUID representing the port whose binding is to fetch - :returns: port binding object - """ - try: - return (db_session.query(n1kv_models_v2.N1kvPortBinding). - filter_by(port_id=port_id). - one()) - except exc.NoResultFound: - raise c_exc.PortBindingNotFound(port_id=port_id) - - -def add_port_binding(db_session, port_id, policy_profile_id): - """ - Create port binding. - - Bind the port with policy profile. - :param db_session: database session - :param port_id: UUID of the port - :param policy_profile_id: UUID of the policy profile - """ - with db_session.begin(subtransactions=True): - binding = n1kv_models_v2.N1kvPortBinding(port_id=port_id, - profile_id=policy_profile_id) - db_session.add(binding) - - -def delete_segment_allocations(db_session, net_p): - """ - Delete the segment allocation entry from the table. - - :params db_session: database session - :params net_p: network profile object - """ - with db_session.begin(subtransactions=True): - seg_min, seg_max = get_segment_range(net_p) - if net_p['segment_type'] == c_const.NETWORK_TYPE_VLAN: - db_session.query(n1kv_models_v2.N1kvVlanAllocation).filter( - (n1kv_models_v2.N1kvVlanAllocation.physical_network == - net_p['physical_network']), - (n1kv_models_v2.N1kvVlanAllocation.vlan_id >= seg_min), - (n1kv_models_v2.N1kvVlanAllocation.vlan_id <= - seg_max)).delete() - elif net_p['segment_type'] == c_const.NETWORK_TYPE_OVERLAY: - db_session.query(n1kv_models_v2.N1kvVxlanAllocation).filter( - (n1kv_models_v2.N1kvVxlanAllocation.vxlan_id >= seg_min), - (n1kv_models_v2.N1kvVxlanAllocation.vxlan_id <= - seg_max)).delete() - - -def sync_vlan_allocations(db_session, net_p): - """ - Synchronize vlan_allocations table with configured VLAN ranges. - - Sync the network profile range with the vlan_allocations table for each - physical network. - :param db_session: database session - :param net_p: network profile dictionary - """ - with db_session.begin(subtransactions=True): - seg_min, seg_max = get_segment_range(net_p) - for vlan_id in range(seg_min, seg_max + 1): - try: - get_vlan_allocation(db_session, - net_p['physical_network'], - vlan_id) - except c_exc.VlanIDNotFound: - alloc = n1kv_models_v2.N1kvVlanAllocation( - physical_network=net_p['physical_network'], - vlan_id=vlan_id, - network_profile_id=net_p['id']) - db_session.add(alloc) - - -def get_vlan_allocation(db_session, physical_network, vlan_id): - """ - Retrieve vlan allocation. - - :param db_session: database session - :param physical network: string name for the physical network - :param vlan_id: integer representing the VLAN ID. - :returns: allocation object for given physical network and VLAN ID - """ - try: - return (db_session.query(n1kv_models_v2.N1kvVlanAllocation). - filter_by(physical_network=physical_network, - vlan_id=vlan_id).one()) - except exc.NoResultFound: - raise c_exc.VlanIDNotFound(vlan_id=vlan_id) - - -def reserve_vlan(db_session, network_profile): - """ - Reserve a VLAN ID within the range of the network profile. - - :param db_session: database session - :param network_profile: network profile object - """ - seg_min, seg_max = get_segment_range(network_profile) - segment_type = c_const.NETWORK_TYPE_VLAN - - with db_session.begin(subtransactions=True): - alloc = (db_session.query(n1kv_models_v2.N1kvVlanAllocation). - filter(sql.and_( - n1kv_models_v2.N1kvVlanAllocation.vlan_id >= seg_min, - n1kv_models_v2.N1kvVlanAllocation.vlan_id <= seg_max, - n1kv_models_v2.N1kvVlanAllocation.physical_network == - network_profile['physical_network'], - n1kv_models_v2.N1kvVlanAllocation.allocated == - sql.false()) - )).first() - if alloc: - segment_id = alloc.vlan_id - physical_network = alloc.physical_network - alloc.allocated = True - return (physical_network, segment_type, segment_id, "0.0.0.0") - raise c_exc.NoMoreNetworkSegments( - network_profile_name=network_profile.name) - - -def reserve_vxlan(db_session, network_profile): - """ - Reserve a VXLAN ID within the range of the network profile. - - :param db_session: database session - :param network_profile: network profile object - """ - seg_min, seg_max = get_segment_range(network_profile) - segment_type = c_const.NETWORK_TYPE_OVERLAY - physical_network = "" - - with db_session.begin(subtransactions=True): - alloc = (db_session.query(n1kv_models_v2.N1kvVxlanAllocation). - filter(sql.and_( - n1kv_models_v2.N1kvVxlanAllocation.vxlan_id >= - seg_min, - n1kv_models_v2.N1kvVxlanAllocation.vxlan_id <= - seg_max, - n1kv_models_v2.N1kvVxlanAllocation.allocated == - sql.false()) - ).first()) - if alloc: - segment_id = alloc.vxlan_id - alloc.allocated = True - if network_profile.sub_type == (c_const. - NETWORK_SUBTYPE_NATIVE_VXLAN): - return (physical_network, segment_type, - segment_id, get_multicast_ip(network_profile)) - else: - return (physical_network, segment_type, segment_id, "0.0.0.0") - raise n_exc.NoNetworkAvailable() - - -def alloc_network(db_session, network_profile_id, tenant_id): - """ - Allocate network using first available free segment ID in segment range. - - :param db_session: database session - :param network_profile_id: UUID representing the network profile - """ - with db_session.begin(subtransactions=True): - network_profile = get_network_profile(db_session, - network_profile_id, tenant_id) - if network_profile.segment_type == c_const.NETWORK_TYPE_VLAN: - return reserve_vlan(db_session, network_profile) - if network_profile.segment_type == c_const.NETWORK_TYPE_OVERLAY: - return reserve_vxlan(db_session, network_profile) - return (None, network_profile.segment_type, 0, "0.0.0.0") - - -def reserve_specific_vlan(db_session, physical_network, vlan_id): - """ - Reserve a specific VLAN ID for the network. - - :param db_session: database session - :param physical_network: string representing the name of physical network - :param vlan_id: integer value of the segmentation ID to be reserved - """ - with db_session.begin(subtransactions=True): - try: - alloc = (db_session.query(n1kv_models_v2.N1kvVlanAllocation). - filter_by(physical_network=physical_network, - vlan_id=vlan_id). - one()) - if alloc.allocated: - if vlan_id == c_const.FLAT_VLAN_ID: - raise n_exc.FlatNetworkInUse( - physical_network=physical_network) - else: - raise n_exc.VlanIdInUse(vlan_id=vlan_id, - physical_network=physical_network) - LOG.debug("Reserving specific vlan %(vlan)s on physical network " - "%(network)s from pool", - {"vlan": vlan_id, "network": physical_network}) - alloc.allocated = True - db_session.add(alloc) - except exc.NoResultFound: - raise c_exc.VlanIDOutsidePool() - - -def release_vlan(db_session, physical_network, vlan_id): - """ - Release a given VLAN ID. - - :param db_session: database session - :param physical_network: string representing the name of physical network - :param vlan_id: integer value of the segmentation ID to be released - """ - with db_session.begin(subtransactions=True): - try: - alloc = (db_session.query(n1kv_models_v2.N1kvVlanAllocation). - filter_by(physical_network=physical_network, - vlan_id=vlan_id). - one()) - alloc.allocated = False - except exc.NoResultFound: - LOG.warning(_LW("vlan_id %(vlan)s on physical network %(network)s " - "not found"), - {"vlan": vlan_id, "network": physical_network}) - - -def sync_vxlan_allocations(db_session, net_p): - """ - Synchronize vxlan_allocations table with configured vxlan ranges. - - :param db_session: database session - :param net_p: network profile dictionary - """ - seg_min, seg_max = get_segment_range(net_p) - if seg_max + 1 - seg_min > c_const.MAX_VXLAN_RANGE: - msg = (_("Unreasonable vxlan ID range %(vxlan_min)s - %(vxlan_max)s") % - {"vxlan_min": seg_min, "vxlan_max": seg_max}) - raise n_exc.InvalidInput(error_message=msg) - with db_session.begin(subtransactions=True): - for vxlan_id in range(seg_min, seg_max + 1): - try: - get_vxlan_allocation(db_session, vxlan_id) - except c_exc.VxlanIDNotFound: - alloc = n1kv_models_v2.N1kvVxlanAllocation( - network_profile_id=net_p['id'], vxlan_id=vxlan_id) - db_session.add(alloc) - - -def get_vxlan_allocation(db_session, vxlan_id): - """ - Retrieve VXLAN allocation for the given VXLAN ID. - - :param db_session: database session - :param vxlan_id: integer value representing the segmentation ID - :returns: allocation object - """ - try: - return (db_session.query(n1kv_models_v2.N1kvVxlanAllocation). - filter_by(vxlan_id=vxlan_id).one()) - except exc.NoResultFound: - raise c_exc.VxlanIDNotFound(vxlan_id=vxlan_id) - - -def reserve_specific_vxlan(db_session, vxlan_id): - """ - Reserve a specific VXLAN ID. - - :param db_session: database session - :param vxlan_id: integer value representing the segmentation ID - """ - with db_session.begin(subtransactions=True): - try: - alloc = (db_session.query(n1kv_models_v2.N1kvVxlanAllocation). - filter_by(vxlan_id=vxlan_id). - one()) - if alloc.allocated: - raise c_exc.VxlanIDInUse(vxlan_id=vxlan_id) - LOG.debug("Reserving specific vxlan %s from pool", vxlan_id) - alloc.allocated = True - db_session.add(alloc) - except exc.NoResultFound: - raise c_exc.VxlanIDOutsidePool() - - -def release_vxlan(db_session, vxlan_id): - """ - Release a given VXLAN ID. - - :param db_session: database session - :param vxlan_id: integer value representing the segmentation ID - """ - with db_session.begin(subtransactions=True): - try: - alloc = (db_session.query(n1kv_models_v2.N1kvVxlanAllocation). - filter_by(vxlan_id=vxlan_id). - one()) - alloc.allocated = False - except exc.NoResultFound: - LOG.warning(_LW("vxlan_id %s not found"), vxlan_id) - - -def set_port_status(port_id, status): - """ - Set the status of the port. - - :param port_id: UUID representing the port - :param status: string representing the new status - """ - db_session = db.get_session() - try: - port = db_session.query(models_v2.Port).filter_by(id=port_id).one() - port.status = status - except exc.NoResultFound: - raise n_exc.PortNotFound(port_id=port_id) - - -def get_vm_network(db_session, policy_profile_id, network_id): - """ - Retrieve a vm_network based on policy profile and network id. - - :param db_session: database session - :param policy_profile_id: UUID representing policy profile - :param network_id: UUID representing network - :returns: VM network object - """ - try: - return (db_session.query(n1kv_models_v2.N1kVmNetwork). - filter_by(profile_id=policy_profile_id, - network_id=network_id).one()) - except exc.NoResultFound: - name = (c_const.VM_NETWORK_NAME_PREFIX + policy_profile_id - + "_" + network_id) - raise c_exc.VMNetworkNotFound(name=name) - - -def add_vm_network(db_session, - name, - policy_profile_id, - network_id, - port_count): - """ - Create a VM network. - - Add a VM network for a unique combination of network and - policy profile. All ports having the same policy profile - on one network will be associated with one VM network. - :param db_session: database session - :param name: string representing the name of the VM network - :param policy_profile_id: UUID representing policy profile - :param network_id: UUID representing a network - :param port_count: integer representing the number of ports on vm network - """ - with db_session.begin(subtransactions=True): - vm_network = n1kv_models_v2.N1kVmNetwork( - name=name, - profile_id=policy_profile_id, - network_id=network_id, - port_count=port_count) - db_session.add(vm_network) - return vm_network - - -def update_vm_network_port_count(db_session, name, port_count): - """ - Update a VM network with new port count. - - :param db_session: database session - :param name: string representing the name of the VM network - :param port_count: integer representing the number of ports on VM network - """ - try: - with db_session.begin(subtransactions=True): - vm_network = (db_session.query(n1kv_models_v2.N1kVmNetwork). - filter_by(name=name).one()) - if port_count is not None: - vm_network.port_count = port_count - return vm_network - except exc.NoResultFound: - raise c_exc.VMNetworkNotFound(name=name) - - -def delete_vm_network(db_session, policy_profile_id, network_id): - """ - Delete a VM network. - - :param db_session: database session - :param policy_profile_id: UUID representing a policy profile - :param network_id: UUID representing a network - :returns: deleted VM network object - """ - with db_session.begin(subtransactions=True): - try: - vm_network = get_vm_network(db_session, - policy_profile_id, - network_id) - db_session.delete(vm_network) - db_session.query(n1kv_models_v2.N1kVmNetwork).filter_by( - name=vm_network["name"]).delete() - return vm_network - except exc.NoResultFound: - name = (c_const.VM_NETWORK_NAME_PREFIX + policy_profile_id + - "_" + network_id) - raise c_exc.VMNetworkNotFound(name=name) - - -def create_network_profile(db_session, network_profile): - """Create a network profile.""" - LOG.debug("create_network_profile()") - with db_session.begin(subtransactions=True): - kwargs = {"name": network_profile["name"], - "segment_type": network_profile["segment_type"]} - if network_profile["segment_type"] == c_const.NETWORK_TYPE_VLAN: - kwargs["physical_network"] = network_profile["physical_network"] - kwargs["segment_range"] = network_profile["segment_range"] - elif network_profile["segment_type"] == c_const.NETWORK_TYPE_OVERLAY: - kwargs["multicast_ip_index"] = 0 - kwargs["multicast_ip_range"] = network_profile[ - "multicast_ip_range"] - kwargs["segment_range"] = network_profile["segment_range"] - kwargs["sub_type"] = network_profile["sub_type"] - elif network_profile["segment_type"] == c_const.NETWORK_TYPE_TRUNK: - kwargs["sub_type"] = network_profile["sub_type"] - net_profile = n1kv_models_v2.NetworkProfile(**kwargs) - db_session.add(net_profile) - return net_profile - - -def delete_network_profile(db_session, id, tenant_id=None): - """Delete Network Profile.""" - LOG.debug("delete_network_profile()") - with db_session.begin(subtransactions=True): - try: - network_profile = get_network_profile(db_session, id, tenant_id) - db_session.delete(network_profile) - (db_session.query(n1kv_models_v2.ProfileBinding). - filter_by(profile_id=id).delete()) - return network_profile - except exc.NoResultFound: - raise c_exc.ProfileTenantBindingNotFound(profile_id=id) - - -def update_network_profile(db_session, id, network_profile, tenant_id=None): - """Update Network Profile.""" - LOG.debug("update_network_profile()") - with db_session.begin(subtransactions=True): - profile = get_network_profile(db_session, id, tenant_id) - profile.update(network_profile) - return profile - - -def get_network_profile(db_session, id, tenant_id=None): - """Get Network Profile.""" - LOG.debug("get_network_profile()") - if tenant_id and c_conf.CISCO_N1K.restrict_network_profiles: - if _profile_binding_exists(db_session=db_session, - tenant_id=tenant_id, - profile_id=id, - profile_type=c_const.NETWORK) is None: - raise c_exc.ProfileTenantBindingNotFound(profile_id=id) - try: - return db_session.query(n1kv_models_v2.NetworkProfile).filter_by( - id=id).one() - except exc.NoResultFound: - raise c_exc.NetworkProfileNotFound(profile=id) - - -def _get_network_profiles(db_session=None, physical_network=None): - """ - Retrieve all network profiles. - - Get Network Profiles on a particular physical network, if physical - network is specified. If no physical network is specified, return - all network profiles. - """ - db_session = db_session or db.get_session() - if physical_network: - return (db_session.query(n1kv_models_v2.NetworkProfile). - filter_by(physical_network=physical_network)) - return db_session.query(n1kv_models_v2.NetworkProfile) - - -def create_policy_profile(policy_profile): - """Create Policy Profile.""" - LOG.debug("create_policy_profile()") - db_session = db.get_session() - with db_session.begin(subtransactions=True): - p_profile = n1kv_models_v2.PolicyProfile(id=policy_profile["id"], - name=policy_profile["name"]) - db_session.add(p_profile) - return p_profile - - -def delete_policy_profile(id): - """Delete Policy Profile.""" - LOG.debug("delete_policy_profile()") - db_session = db.get_session() - with db_session.begin(subtransactions=True): - policy_profile = get_policy_profile(db_session, id) - db_session.delete(policy_profile) - - -def update_policy_profile(db_session, id, policy_profile): - """Update a policy profile.""" - LOG.debug("update_policy_profile()") - with db_session.begin(subtransactions=True): - _profile = get_policy_profile(db_session, id) - _profile.update(policy_profile) - return _profile - - -def get_policy_profile(db_session, id): - """Get Policy Profile.""" - LOG.debug("get_policy_profile()") - try: - return db_session.query( - n1kv_models_v2.PolicyProfile).filter_by(id=id).one() - except exc.NoResultFound: - raise c_exc.PolicyProfileIdNotFound(profile_id=id) - - -def get_policy_profiles(): - """Retrieve all policy profiles.""" - db_session = db.get_session() - with db_session.begin(subtransactions=True): - return db_session.query(n1kv_models_v2.PolicyProfile) - - -def create_profile_binding(db_session, tenant_id, profile_id, profile_type): - """Create Network/Policy Profile association with a tenant.""" - db_session = db_session or db.get_session() - if profile_type not in ["network", "policy"]: - raise n_exc.NeutronException(_("Invalid profile type")) - - if _profile_binding_exists(db_session, - tenant_id, - profile_id, - profile_type): - return get_profile_binding(db_session, tenant_id, profile_id) - - with db_session.begin(subtransactions=True): - binding = n1kv_models_v2.ProfileBinding(profile_type=profile_type, - profile_id=profile_id, - tenant_id=tenant_id) - db_session.add(binding) - return binding - - -def _profile_binding_exists(db_session, tenant_id, profile_id, profile_type): - """Check if the profile-tenant binding exists.""" - LOG.debug("_profile_binding_exists()") - db_session = db_session or db.get_session() - return (db_session.query(n1kv_models_v2.ProfileBinding). - filter_by(tenant_id=tenant_id, profile_id=profile_id, - profile_type=profile_type).first()) - - -def get_profile_binding(db_session, tenant_id, profile_id): - """Get Network/Policy Profile - Tenant binding.""" - LOG.debug("get_profile_binding()") - try: - return (db_session.query(n1kv_models_v2.ProfileBinding).filter_by( - tenant_id=tenant_id, profile_id=profile_id).one()) - except exc.NoResultFound: - raise c_exc.ProfileTenantBindingNotFound(profile_id=profile_id) - - -def delete_profile_binding(db_session, tenant_id, profile_id): - """Delete Policy Binding.""" - LOG.debug("delete_profile_binding()") - db_session = db_session or db.get_session() - try: - binding = get_profile_binding(db_session, tenant_id, profile_id) - with db_session.begin(subtransactions=True): - db_session.delete(binding) - except c_exc.ProfileTenantBindingNotFound: - LOG.debug("Profile-Tenant binding missing for profile ID " - "%(profile_id)s and tenant ID %(tenant_id)s", - {"profile_id": profile_id, "tenant_id": tenant_id}) - return - - -def update_profile_binding(db_session, profile_id, tenants, profile_type): - """Updating Profile Binding.""" - LOG.debug('update_profile_binding()') - if profile_type not in ("network", "policy"): - raise n_exc.NeutronException(_("Invalid profile type")) - db_session = db_session or db.get_session() - with db_session.begin(subtransactions=True): - db_session.query(n1kv_models_v2.ProfileBinding).filter_by( - profile_id=profile_id, profile_type=profile_type).delete() - new_tenants_set = set(tenants) - for tenant_id in new_tenants_set: - tenant = n1kv_models_v2.ProfileBinding(profile_type=profile_type, - tenant_id=tenant_id, - profile_id=profile_id) - db_session.add(tenant) - - -def _get_profile_bindings(db_session, profile_type=None): - """ - Retrieve a list of profile bindings. - - Get all profile-tenant bindings based on profile type. - If profile type is None, return profile-tenant binding for all - profile types. - """ - if profile_type: - return (db_session.query(n1kv_models_v2.ProfileBinding). - filter_by(profile_type=profile_type)) - return db_session.query(n1kv_models_v2.ProfileBinding) - - -def _get_profile_bindings_by_uuid(db_session, profile_id): - """ - Retrieve a list of profile bindings. - - Get all profile-tenant bindings based on profile UUID. - """ - return (db_session.query(n1kv_models_v2.ProfileBinding). - filter_by(profile_id=profile_id)) - - -class NetworkProfile_db_mixin(object): - - """Network Profile Mixin.""" - - def _replace_fake_tenant_id_with_real(self, context): - """ - Replace default tenant-id with admin tenant-ids. - - Default tenant-ids are populated in profile bindings when plugin is - initialized. Replace these tenant-ids with admin's tenant-id. - :param context: neutron api request context - """ - if context.is_admin and context.tenant_id: - tenant_id = context.tenant_id - db_session = context.session - with db_session.begin(subtransactions=True): - (db_session.query(n1kv_models_v2.ProfileBinding). - filter_by(tenant_id=c_const.TENANT_ID_NOT_SET). - update({'tenant_id': tenant_id})) - - def _get_network_collection_for_tenant(self, db_session, model, tenant_id): - net_profile_ids = (db_session.query(n1kv_models_v2.ProfileBinding. - profile_id). - filter_by(tenant_id=tenant_id). - filter_by(profile_type=c_const.NETWORK).all()) - if not net_profile_ids: - return [] - network_profiles = (db_session.query(model).filter(model.id.in_( - pid[0] for pid in net_profile_ids))) - return [self._make_network_profile_dict(p) for p in network_profiles] - - def _make_profile_bindings_dict(self, profile_binding, fields=None): - res = {"profile_id": profile_binding["profile_id"], - "tenant_id": profile_binding["tenant_id"]} - return self._fields(res, fields) - - def _make_network_profile_dict(self, network_profile, fields=None): - res = {"id": network_profile["id"], - "name": network_profile["name"], - "segment_type": network_profile["segment_type"], - "sub_type": network_profile["sub_type"], - "segment_range": network_profile["segment_range"], - "multicast_ip_index": network_profile["multicast_ip_index"], - "multicast_ip_range": network_profile["multicast_ip_range"], - "physical_network": network_profile["physical_network"]} - return self._fields(res, fields) - - def _segment_in_use(self, db_session, network_profile): - """Verify whether a segment is allocated for given network profile.""" - with db_session.begin(subtransactions=True): - return (db_session.query(n1kv_models_v2.N1kvNetworkBinding). - filter_by(profile_id=network_profile['id'])).first() - - def get_network_profile_bindings(self, context, filters=None, fields=None): - """ - Retrieve a list of profile bindings for network profiles. - - :param context: neutron api request context - :param filters: a dictionary with keys that are valid keys for a - profile bindings object. Values in this dictiontary are - an iterable containing values that will be used for an - exact match comparison for that value. Each result - returned by this function will have matched one of the - values for each key in filters - :params fields: a list of strings that are valid keys in a profile - bindings dictionary. Only these fields will be returned - :returns: list of profile bindings - """ - if context.is_admin: - profile_bindings = _get_profile_bindings( - context.session, - profile_type=c_const.NETWORK) - return [self._make_profile_bindings_dict(pb) - for pb in profile_bindings] - - def create_network_profile(self, context, network_profile): - """ - Create a network profile. - - :param context: neutron api request context - :param network_profile: network profile dictionary - :returns: network profile dictionary - """ - self._replace_fake_tenant_id_with_real(context) - p = network_profile["network_profile"] - self._validate_network_profile_args(context, p) - with context.session.begin(subtransactions=True): - net_profile = create_network_profile(context.session, p) - if net_profile.segment_type == c_const.NETWORK_TYPE_VLAN: - sync_vlan_allocations(context.session, net_profile) - elif net_profile.segment_type == c_const.NETWORK_TYPE_OVERLAY: - sync_vxlan_allocations(context.session, net_profile) - create_profile_binding(context.session, - context.tenant_id, - net_profile.id, - c_const.NETWORK) - if p.get(c_const.ADD_TENANTS): - for tenant in p[c_const.ADD_TENANTS]: - self.add_network_profile_tenant(context.session, - net_profile.id, - tenant) - return self._make_network_profile_dict(net_profile) - - def delete_network_profile(self, context, id): - """ - Delete a network profile. - - :param context: neutron api request context - :param id: UUID representing network profile to delete - :returns: deleted network profile dictionary - """ - # Check whether the network profile is in use. - if self._segment_in_use(context.session, - get_network_profile(context.session, id, - context.tenant_id)): - raise c_exc.NetworkProfileInUse(profile=id) - # Delete and return the network profile if it is not in use. - _profile = delete_network_profile(context.session, id, - context.tenant_id) - return self._make_network_profile_dict(_profile) - - def update_network_profile(self, context, id, network_profile): - """ - Update a network profile. - - Add/remove network profile to tenant-id binding for the corresponding - options and if user is admin. - :param context: neutron api request context - :param id: UUID representing network profile to update - :param network_profile: network profile dictionary - :returns: updated network profile dictionary - """ - # Flag to check whether network profile is updated or not. - is_updated = False - p = network_profile["network_profile"] - original_net_p = get_network_profile(context.session, id, - context.tenant_id) - # Update network profile to tenant id binding. - if context.is_admin and c_const.ADD_TENANTS in p: - profile_bindings = _get_profile_bindings_by_uuid(context.session, - profile_id=id) - for bindings in profile_bindings: - p[c_const.ADD_TENANTS].append(bindings.tenant_id) - update_profile_binding(context.session, id, - p[c_const.ADD_TENANTS], c_const.NETWORK) - is_updated = True - if context.is_admin and c_const.REMOVE_TENANTS in p: - for remove_tenant in p[c_const.REMOVE_TENANTS]: - if remove_tenant == context.tenant_id: - continue - delete_profile_binding(context.session, remove_tenant, id) - is_updated = True - if original_net_p.segment_type == c_const.NETWORK_TYPE_TRUNK: - #TODO(abhraut): Remove check when Trunk supports segment range. - if p.get('segment_range'): - msg = _("segment_range not required for TRUNK") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - if original_net_p.segment_type in [c_const.NETWORK_TYPE_VLAN, - c_const.NETWORK_TYPE_TRUNK]: - if p.get("multicast_ip_range"): - msg = _("multicast_ip_range not required") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - # Update segment range if network profile is not in use. - if (p.get("segment_range") and - p.get("segment_range") != original_net_p.segment_range): - if not self._segment_in_use(context.session, original_net_p): - delete_segment_allocations(context.session, original_net_p) - updated_net_p = update_network_profile(context.session, id, p, - context.tenant_id) - self._validate_segment_range_uniqueness(context, - updated_net_p, id) - if original_net_p.segment_type == c_const.NETWORK_TYPE_VLAN: - sync_vlan_allocations(context.session, updated_net_p) - if original_net_p.segment_type == c_const.NETWORK_TYPE_OVERLAY: - sync_vxlan_allocations(context.session, updated_net_p) - is_updated = True - else: - raise c_exc.NetworkProfileInUse(profile=id) - if (p.get('multicast_ip_range') and - (p.get("multicast_ip_range") != - original_net_p.get("multicast_ip_range"))): - self._validate_multicast_ip_range(p) - if not self._segment_in_use(context.session, original_net_p): - is_updated = True - else: - raise c_exc.NetworkProfileInUse(profile=id) - # Update network profile if name is updated and the network profile - # is not yet updated. - if "name" in p and not is_updated: - is_updated = True - # Return network profile if it is successfully updated. - if is_updated: - return self._make_network_profile_dict( - update_network_profile(context.session, id, p, - context.tenant_id)) - - def get_network_profile(self, context, id, fields=None): - """ - Retrieve a network profile. - - :param context: neutron api request context - :param id: UUID representing the network profile to retrieve - :params fields: a list of strings that are valid keys in a network - profile dictionary. Only these fields will be returned - :returns: network profile dictionary - """ - profile = get_network_profile(context.session, id, context.tenant_id) - return self._make_network_profile_dict(profile, fields) - - def get_network_profiles(self, context, filters=None, fields=None): - """ - Retrieve a list of all network profiles. - - Retrieve all network profiles if tenant is admin. For a non-admin - tenant, retrieve all network profiles belonging to this tenant only. - :param context: neutron api request context - :param filters: a dictionary with keys that are valid keys for a - network profile object. Values in this dictiontary are - an iterable containing values that will be used for an - exact match comparison for that value. Each result - returned by this function will have matched one of the - values for each key in filters - :params fields: a list of strings that are valid keys in a network - profile dictionary. Only these fields will be returned - :returns: list of all network profiles - """ - if context.is_admin: - return self._get_collection(context, n1kv_models_v2.NetworkProfile, - self._make_network_profile_dict, - filters=filters, fields=fields) - return self._get_network_collection_for_tenant(context.session, - n1kv_models_v2. - NetworkProfile, - context.tenant_id) - - def add_network_profile_tenant(self, - db_session, - network_profile_id, - tenant_id): - """ - Add a tenant to a network profile. - - :param db_session: database session - :param network_profile_id: UUID representing network profile - :param tenant_id: UUID representing the tenant - :returns: profile binding object - """ - return create_profile_binding(db_session, - tenant_id, - network_profile_id, - c_const.NETWORK) - - def network_profile_exists(self, context, id): - """ - Verify whether a network profile for given id exists. - - :param context: neutron api request context - :param id: UUID representing network profile - :returns: true if network profile exist else False - """ - try: - get_network_profile(context.session, id, context.tenant_id) - return True - except c_exc.NetworkProfileNotFound(profile=id): - return False - - def _get_segment_range(self, data): - return (int(seg) for seg in data.split("-")[:2]) - - def _validate_network_profile_args(self, context, p): - """ - Validate completeness of Nexus1000V network profile arguments. - - :param context: neutron api request context - :param p: network profile object - """ - self._validate_network_profile(p) - segment_type = p['segment_type'].lower() - if segment_type != c_const.NETWORK_TYPE_TRUNK: - self._validate_segment_range_uniqueness(context, p) - - def _validate_segment_range(self, network_profile): - """ - Validate segment range values. - - :param network_profile: network profile object - """ - if not re.match(r"(\d+)\-(\d+)", network_profile["segment_range"]): - msg = _("Invalid segment range. example range: 500-550") - raise n_exc.InvalidInput(error_message=msg) - - def _validate_multicast_ip_range(self, network_profile): - """ - Validate multicast ip range values. - - :param network_profile: network profile object - """ - try: - min_ip, max_ip = (network_profile - ['multicast_ip_range'].split('-', 1)) - except ValueError: - msg = _("Invalid multicast ip address range. " - "example range: 224.1.1.1-224.1.1.10") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - for ip in [min_ip, max_ip]: - try: - if not netaddr.IPAddress(ip).is_multicast(): - msg = _("%s is not a valid multicast ip address") % ip - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - if netaddr.IPAddress(ip) <= netaddr.IPAddress('224.0.0.255'): - msg = _("%s is reserved multicast ip address") % ip - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - except netaddr.AddrFormatError: - msg = _("%s is not a valid ip address") % ip - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - if netaddr.IPAddress(min_ip) > netaddr.IPAddress(max_ip): - msg = (_("Invalid multicast IP range '%(min_ip)s-%(max_ip)s':" - " Range should be from low address to high address") % - {'min_ip': min_ip, 'max_ip': max_ip}) - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - - def _validate_network_profile(self, net_p): - """ - Validate completeness of a network profile arguments. - - :param net_p: network profile object - """ - if net_p["segment_type"] == "": - msg = _("Arguments segment_type missing" - " for network profile") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - segment_type = net_p["segment_type"].lower() - if segment_type not in [c_const.NETWORK_TYPE_VLAN, - c_const.NETWORK_TYPE_OVERLAY, - c_const.NETWORK_TYPE_TRUNK, - c_const.NETWORK_TYPE_MULTI_SEGMENT]: - msg = _("segment_type should either be vlan, overlay, " - "multi-segment or trunk") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - if segment_type == c_const.NETWORK_TYPE_VLAN: - if "physical_network" not in net_p: - msg = _("Argument physical_network missing " - "for network profile") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - if segment_type == c_const.NETWORK_TYPE_TRUNK: - if net_p["segment_range"]: - msg = _("segment_range not required for trunk") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - if segment_type in [c_const.NETWORK_TYPE_TRUNK, - c_const.NETWORK_TYPE_OVERLAY]: - if not attributes.is_attr_set(net_p.get("sub_type")): - msg = _("Argument sub_type missing " - "for network profile") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - if segment_type in [c_const.NETWORK_TYPE_VLAN, - c_const.NETWORK_TYPE_OVERLAY]: - if "segment_range" not in net_p: - msg = _("Argument segment_range missing " - "for network profile") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - self._validate_segment_range(net_p) - if segment_type == c_const.NETWORK_TYPE_OVERLAY: - if net_p['sub_type'] != c_const.NETWORK_SUBTYPE_NATIVE_VXLAN: - net_p['multicast_ip_range'] = '0.0.0.0' - else: - multicast_ip_range = net_p.get("multicast_ip_range") - if not attributes.is_attr_set(multicast_ip_range): - msg = _("Argument multicast_ip_range missing" - " for VXLAN multicast network profile") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - self._validate_multicast_ip_range(net_p) - else: - net_p['multicast_ip_range'] = '0.0.0.0' - - def _validate_segment_range_uniqueness(self, context, net_p, id=None): - """ - Validate that segment range doesn't overlap. - - :param context: neutron api request context - :param net_p: network profile dictionary - :param id: UUID representing the network profile being updated - """ - segment_type = net_p["segment_type"].lower() - seg_min, seg_max = self._get_segment_range(net_p['segment_range']) - if segment_type == c_const.NETWORK_TYPE_VLAN: - if not ((seg_min <= seg_max) and - ((seg_min in range(p_const.MIN_VLAN_TAG, - c_const.N1KV_VLAN_RESERVED_MIN) and - seg_max in range(p_const.MIN_VLAN_TAG, - c_const.N1KV_VLAN_RESERVED_MIN)) or - (seg_min in range(c_const.N1KV_VLAN_RESERVED_MAX + 1, - p_const.MAX_VLAN_TAG) and - seg_max in range(c_const.N1KV_VLAN_RESERVED_MAX + 1, - p_const.MAX_VLAN_TAG)))): - msg = (_("Segment range is invalid, select from " - "%(min)s-%(nmin)s, %(nmax)s-%(max)s") % - {"min": p_const.MIN_VLAN_TAG, - "nmin": c_const.N1KV_VLAN_RESERVED_MIN - 1, - "nmax": c_const.N1KV_VLAN_RESERVED_MAX + 1, - "max": p_const.MAX_VLAN_TAG - 1}) - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - profiles = _get_network_profiles( - db_session=context.session, - physical_network=net_p["physical_network"] - ) - elif segment_type in [c_const.NETWORK_TYPE_OVERLAY, - c_const.NETWORK_TYPE_MULTI_SEGMENT, - c_const.NETWORK_TYPE_TRUNK]: - if (seg_min > seg_max or - seg_min < c_const.N1KV_VXLAN_MIN or - seg_max > c_const.N1KV_VXLAN_MAX): - msg = (_("segment range is invalid. Valid range is : " - "%(min)s-%(max)s") % - {"min": c_const.N1KV_VXLAN_MIN, - "max": c_const.N1KV_VXLAN_MAX}) - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - profiles = _get_network_profiles(db_session=context.session) - if profiles: - for profile in profiles: - if id and profile.id == id: - continue - name = profile.name - segment_range = profile.segment_range - if net_p["name"] == name: - msg = (_("NetworkProfile name %s already exists") % - net_p["name"]) - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - if (c_const.NETWORK_TYPE_MULTI_SEGMENT in - [profile.segment_type, net_p["segment_type"]] or - c_const.NETWORK_TYPE_TRUNK in - [profile.segment_type, net_p["segment_type"]]): - continue - seg_min, seg_max = self._get_segment_range( - net_p["segment_range"]) - profile_seg_min, profile_seg_max = self._get_segment_range( - segment_range) - if ((profile_seg_min <= seg_min <= profile_seg_max) or - (profile_seg_min <= seg_max <= profile_seg_max) or - ((seg_min <= profile_seg_min) and - (seg_max >= profile_seg_max))): - msg = _("Segment range overlaps with another profile") - LOG.error(msg) - raise n_exc.InvalidInput(error_message=msg) - - def _get_network_profile_by_name(self, db_session, name): - """ - Retrieve network profile based on name. - - :param db_session: database session - :param name: string representing the name for the network profile - :returns: network profile object - """ - with db_session.begin(subtransactions=True): - try: - return (db_session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=name).one()) - except exc.NoResultFound: - raise c_exc.NetworkProfileNotFound(profile=name) - - -class PolicyProfile_db_mixin(object): - - """Policy Profile Mixin.""" - - def _get_policy_collection_for_tenant(self, db_session, model, tenant_id): - profile_ids = (db_session.query(n1kv_models_v2. - ProfileBinding.profile_id) - .filter_by(tenant_id=tenant_id). - filter_by(profile_type=c_const.POLICY).all()) - if not profile_ids: - return [] - profiles = db_session.query(model).filter(model.id.in_( - pid[0] for pid in profile_ids)) - return [self._make_policy_profile_dict(p) for p in profiles] - - def _make_policy_profile_dict(self, policy_profile, fields=None): - res = {"id": policy_profile["id"], "name": policy_profile["name"]} - return self._fields(res, fields) - - def _make_profile_bindings_dict(self, profile_binding, fields=None): - res = {"profile_id": profile_binding["profile_id"], - "tenant_id": profile_binding["tenant_id"]} - return self._fields(res, fields) - - def _policy_profile_exists(self, id): - db_session = db.get_session() - return (db_session.query(n1kv_models_v2.PolicyProfile). - filter_by(id=id).first()) - - def get_policy_profile(self, context, id, fields=None): - """ - Retrieve a policy profile for the given UUID. - - :param context: neutron api request context - :param id: UUID representing policy profile to fetch - :params fields: a list of strings that are valid keys in a policy - profile dictionary. Only these fields will be returned - :returns: policy profile dictionary - """ - profile = get_policy_profile(context.session, id) - return self._make_policy_profile_dict(profile, fields) - - def get_policy_profiles(self, context, filters=None, fields=None): - """ - Retrieve a list of policy profiles. - - Retrieve all policy profiles if tenant is admin. For a non-admin - tenant, retrieve all policy profiles belonging to this tenant only. - :param context: neutron api request context - :param filters: a dictionary with keys that are valid keys for a - policy profile object. Values in this dictiontary are - an iterable containing values that will be used for an - exact match comparison for that value. Each result - returned by this function will have matched one of the - values for each key in filters - :params fields: a list of strings that are valid keys in a policy - profile dictionary. Only these fields will be returned - :returns: list of all policy profiles - """ - if context.is_admin or not c_conf.CISCO_N1K.restrict_policy_profiles: - return self._get_collection(context, n1kv_models_v2.PolicyProfile, - self._make_policy_profile_dict, - filters=filters, fields=fields) - else: - return self._get_policy_collection_for_tenant(context.session, - n1kv_models_v2. - PolicyProfile, - context.tenant_id) - - def get_policy_profile_bindings(self, context, filters=None, fields=None): - """ - Retrieve a list of profile bindings for policy profiles. - - :param context: neutron api request context - :param filters: a dictionary with keys that are valid keys for a - profile bindings object. Values in this dictiontary are - an iterable containing values that will be used for an - exact match comparison for that value. Each result - returned by this function will have matched one of the - values for each key in filters - :params fields: a list of strings that are valid keys in a profile - bindings dictionary. Only these fields will be returned - :returns: list of profile bindings - """ - if context.is_admin: - profile_bindings = _get_profile_bindings( - context.session, - profile_type=c_const.POLICY) - return [self._make_profile_bindings_dict(pb) - for pb in profile_bindings] - - def update_policy_profile(self, context, id, policy_profile): - """ - Update a policy profile. - - Add/remove policy profile to tenant-id binding for the corresponding - option and if user is admin. - :param context: neutron api request context - :param id: UUID representing policy profile to update - :param policy_profile: policy profile dictionary - :returns: updated policy profile dictionary - """ - p = policy_profile["policy_profile"] - if context.is_admin and "add_tenant" in p: - self.add_policy_profile_tenant(context.session, - id, - p["add_tenant"]) - return self._make_policy_profile_dict(get_policy_profile( - context.session, id)) - if context.is_admin and "remove_tenant" in p: - delete_profile_binding(context.session, p["remove_tenant"], id) - return self._make_policy_profile_dict(get_policy_profile( - context.session, id)) - return self._make_policy_profile_dict( - update_policy_profile(context.session, id, p)) - - def add_policy_profile_tenant(self, - db_session, - policy_profile_id, - tenant_id): - """ - Add a tenant to a policy profile binding. - - :param db_session: database session - :param policy_profile_id: UUID representing policy profile - :param tenant_id: UUID representing the tenant - :returns: profile binding object - """ - return create_profile_binding(db_session, - tenant_id, - policy_profile_id, - c_const.POLICY) - - def remove_policy_profile_tenant(self, policy_profile_id, tenant_id): - """ - Remove a tenant to a policy profile binding. - - :param policy_profile_id: UUID representing policy profile - :param tenant_id: UUID representing the tenant - """ - delete_profile_binding(None, tenant_id, policy_profile_id) - - def _delete_policy_profile(self, policy_profile_id): - """Delete policy profile and associated binding.""" - db_session = db.get_session() - with db_session.begin(subtransactions=True): - (db_session.query(n1kv_models_v2.PolicyProfile). - filter_by(id=policy_profile_id).delete()) - - def _get_policy_profile_by_name(self, name): - """ - Retrieve policy profile based on name. - - :param name: string representing the name for the policy profile - :returns: policy profile object - """ - db_session = db.get_session() - with db_session.begin(subtransactions=True): - try: - return (db_session.query(n1kv_models_v2.PolicyProfile). - filter_by(name=name).one()) - except exc.NoResultFound: - raise c_exc.PolicyProfileNameNotFound(profile_name=name) - - def _remove_all_fake_policy_profiles(self): - """ - Remove all policy profiles associated with fake tenant id. - - This will find all Profile ID where tenant is not set yet - set A - and profiles where tenant was already set - set B - and remove what is in both and no tenant id set - """ - db_session = db.get_session() - with db_session.begin(subtransactions=True): - a_set_q = (db_session.query(n1kv_models_v2.ProfileBinding). - filter_by(tenant_id=c_const.TENANT_ID_NOT_SET, - profile_type=c_const.POLICY)) - a_set = set(i.profile_id for i in a_set_q) - b_set_q = (db_session.query(n1kv_models_v2.ProfileBinding). - filter(sql.and_(n1kv_models_v2.ProfileBinding. - tenant_id != c_const.TENANT_ID_NOT_SET, - n1kv_models_v2.ProfileBinding. - profile_type == c_const.POLICY))) - b_set = set(i.profile_id for i in b_set_q) - if a_set & b_set: - (db_session.query(n1kv_models_v2.ProfileBinding). - filter(sql.and_(n1kv_models_v2.ProfileBinding.profile_id. - in_(a_set & b_set), - n1kv_models_v2.ProfileBinding.tenant_id == - c_const.TENANT_ID_NOT_SET)). - delete(synchronize_session="fetch")) - - def _add_policy_profile(self, - policy_profile_name, - policy_profile_id, - tenant_id=None): - """ - Add Policy profile and tenant binding. - - :param policy_profile_name: string representing the name for the - policy profile - :param policy_profile_id: UUID representing the policy profile - :param tenant_id: UUID representing the tenant - """ - policy_profile = {"id": policy_profile_id, "name": policy_profile_name} - tenant_id = tenant_id or c_const.TENANT_ID_NOT_SET - if not self._policy_profile_exists(policy_profile_id): - create_policy_profile(policy_profile) - create_profile_binding(None, - tenant_id, - policy_profile["id"], - c_const.POLICY) diff --git a/neutron/plugins/cisco/db/n1kv_models_v2.py b/neutron/plugins/cisco/db/n1kv_models_v2.py deleted file mode 100644 index bb7c446a1..000000000 --- a/neutron/plugins/cisco/db/n1kv_models_v2.py +++ /dev/null @@ -1,185 +0,0 @@ -# Copyright 2013 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. - -from oslo_log import log as logging -import sqlalchemy as sa -from sqlalchemy import sql - -from neutron.db import model_base -from neutron.db import models_v2 -from neutron.plugins.cisco.common import cisco_constants - - -LOG = logging.getLogger(__name__) - - -class N1kvVlanAllocation(model_base.BASEV2): - - """Represents allocation state of vlan_id on physical network.""" - __tablename__ = 'cisco_n1kv_vlan_allocations' - - physical_network = sa.Column(sa.String(64), - nullable=False, - primary_key=True) - vlan_id = sa.Column(sa.Integer, nullable=False, primary_key=True, - autoincrement=False) - allocated = sa.Column(sa.Boolean, nullable=False, default=False, - server_default=sql.false()) - network_profile_id = sa.Column(sa.String(36), - sa.ForeignKey('cisco_network_profiles.id', - ondelete="CASCADE"), - nullable=False) - - -class N1kvVxlanAllocation(model_base.BASEV2): - - """Represents allocation state of vxlan_id.""" - __tablename__ = 'cisco_n1kv_vxlan_allocations' - - vxlan_id = sa.Column(sa.Integer, nullable=False, primary_key=True, - autoincrement=False) - allocated = sa.Column(sa.Boolean, nullable=False, default=False, - server_default=sql.false()) - network_profile_id = sa.Column(sa.String(36), - sa.ForeignKey('cisco_network_profiles.id', - ondelete="CASCADE"), - nullable=False) - - -class N1kvPortBinding(model_base.BASEV2): - - """Represents binding of ports to policy profile.""" - __tablename__ = 'cisco_n1kv_port_bindings' - - port_id = sa.Column(sa.String(36), - sa.ForeignKey('ports.id', ondelete="CASCADE"), - primary_key=True) - profile_id = sa.Column(sa.String(36), - sa.ForeignKey('cisco_policy_profiles.id')) - - -class N1kvNetworkBinding(model_base.BASEV2): - - """Represents binding of virtual network to physical realization.""" - __tablename__ = 'cisco_n1kv_network_bindings' - - network_id = sa.Column(sa.String(36), - sa.ForeignKey('networks.id', ondelete="CASCADE"), - primary_key=True) - network_type = sa.Column(sa.String(32), nullable=False) - physical_network = sa.Column(sa.String(64)) - segmentation_id = sa.Column(sa.Integer) - multicast_ip = sa.Column(sa.String(32)) - profile_id = sa.Column(sa.String(36), - sa.ForeignKey('cisco_network_profiles.id')) - - -class N1kVmNetwork(model_base.BASEV2): - - """Represents VM Network information.""" - __tablename__ = 'cisco_n1kv_vmnetworks' - - name = sa.Column(sa.String(80), primary_key=True) - profile_id = sa.Column(sa.String(36), - sa.ForeignKey('cisco_policy_profiles.id')) - network_id = sa.Column(sa.String(36)) - port_count = sa.Column(sa.Integer) - - -class NetworkProfile(model_base.BASEV2, models_v2.HasId): - - """ - Nexus1000V Network Profiles - - segment_type - VLAN, OVERLAY, TRUNK, MULTI_SEGMENT - sub_type - TRUNK_VLAN, TRUNK_VXLAN, native_vxlan, enhanced_vxlan - segment_range - '-' - multicast_ip_index - - multicast_ip_range - '-' - physical_network - Name for the physical network - """ - __tablename__ = 'cisco_network_profiles' - - name = sa.Column(sa.String(255)) - segment_type = sa.Column(sa.Enum(cisco_constants.NETWORK_TYPE_VLAN, - cisco_constants.NETWORK_TYPE_OVERLAY, - cisco_constants.NETWORK_TYPE_TRUNK, - cisco_constants. - NETWORK_TYPE_MULTI_SEGMENT, - name='segment_type'), - nullable=False) - sub_type = sa.Column(sa.String(255)) - segment_range = sa.Column(sa.String(255)) - multicast_ip_index = sa.Column(sa.Integer, default=0, - server_default='0') - multicast_ip_range = sa.Column(sa.String(255)) - physical_network = sa.Column(sa.String(255)) - - -class PolicyProfile(model_base.BASEV2): - - """ - Nexus1000V Network Profiles - - Both 'id' and 'name' are coming from Nexus1000V switch - """ - __tablename__ = 'cisco_policy_profiles' - - id = sa.Column(sa.String(36), primary_key=True) - name = sa.Column(sa.String(255)) - - -class ProfileBinding(model_base.BASEV2): - - """ - Represents a binding of Network Profile - or Policy Profile to tenant_id - """ - __tablename__ = 'cisco_n1kv_profile_bindings' - - profile_type = sa.Column(sa.Enum(cisco_constants.NETWORK, - cisco_constants.POLICY, - name='profile_type')) - tenant_id = sa.Column(sa.String(36), - primary_key=True, - default=cisco_constants.TENANT_ID_NOT_SET, - server_default=cisco_constants.TENANT_ID_NOT_SET) - profile_id = sa.Column(sa.String(36), primary_key=True) - - -class N1kvTrunkSegmentBinding(model_base.BASEV2): - - """Represents binding of segments in trunk networks.""" - __tablename__ = 'cisco_n1kv_trunk_segments' - - trunk_segment_id = sa.Column(sa.String(36), - sa.ForeignKey('networks.id', - ondelete="CASCADE"), - primary_key=True) - segment_id = sa.Column(sa.String(36), nullable=False, primary_key=True) - dot1qtag = sa.Column(sa.String(36), nullable=False, primary_key=True) - - -class N1kvMultiSegmentNetworkBinding(model_base.BASEV2): - - """Represents binding of segments in multi-segment networks.""" - __tablename__ = 'cisco_n1kv_multi_segments' - - multi_segment_id = sa.Column(sa.String(36), - sa.ForeignKey('networks.id', - ondelete="CASCADE"), - primary_key=True) - segment1_id = sa.Column(sa.String(36), nullable=False, primary_key=True) - segment2_id = sa.Column(sa.String(36), nullable=False, primary_key=True) - encap_profile_name = sa.Column(sa.String(36)) diff --git a/neutron/plugins/cisco/db/network_db_v2.py b/neutron/plugins/cisco/db/network_db_v2.py deleted file mode 100644 index 15aeabf4c..000000000 --- a/neutron/plugins/cisco/db/network_db_v2.py +++ /dev/null @@ -1,280 +0,0 @@ -# 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. - -from oslo_log import log as logging -from oslo_utils import uuidutils -from sqlalchemy.orm import exc - -from neutron.db import api as db -from neutron.plugins.cisco.common import cisco_constants as const -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.db import network_models_v2 - - -LOG = logging.getLogger(__name__) - - -def get_all_qoss(tenant_id): - """Lists all the qos to tenant associations.""" - LOG.debug("get_all_qoss() called") - session = db.get_session() - return (session.query(network_models_v2.QoS). - filter_by(tenant_id=tenant_id).all()) - - -def get_qos(tenant_id, qos_id): - """Lists the qos given a tenant_id and qos_id.""" - LOG.debug("get_qos() called") - session = db.get_session() - try: - return (session.query(network_models_v2.QoS). - filter_by(tenant_id=tenant_id). - filter_by(qos_id=qos_id).one()) - except exc.NoResultFound: - raise c_exc.QosNotFound(qos_id=qos_id, - tenant_id=tenant_id) - - -def add_qos(tenant_id, qos_name, qos_desc): - """Adds a qos to tenant association.""" - LOG.debug("add_qos() called") - session = db.get_session() - try: - qos = (session.query(network_models_v2.QoS). - filter_by(tenant_id=tenant_id). - filter_by(qos_name=qos_name).one()) - raise c_exc.QosNameAlreadyExists(qos_name=qos_name, - tenant_id=tenant_id) - except exc.NoResultFound: - qos = network_models_v2.QoS(qos_id=uuidutils.generate_uuid(), - tenant_id=tenant_id, - qos_name=qos_name, - qos_desc=qos_desc) - session.add(qos) - session.flush() - return qos - - -def remove_qos(tenant_id, qos_id): - """Removes a qos to tenant association.""" - session = db.get_session() - try: - qos = (session.query(network_models_v2.QoS). - filter_by(tenant_id=tenant_id). - filter_by(qos_id=qos_id).one()) - session.delete(qos) - session.flush() - return qos - except exc.NoResultFound: - pass - - -def update_qos(tenant_id, qos_id, new_qos_name=None): - """Updates a qos to tenant association.""" - session = db.get_session() - try: - qos = (session.query(network_models_v2.QoS). - filter_by(tenant_id=tenant_id). - filter_by(qos_id=qos_id).one()) - if new_qos_name: - qos["qos_name"] = new_qos_name - session.merge(qos) - session.flush() - return qos - except exc.NoResultFound: - raise c_exc.QosNotFound(qos_id=qos_id, - tenant_id=tenant_id) - - -def get_all_credentials(): - """Lists all the creds for a tenant.""" - session = db.get_session() - return (session.query(network_models_v2.Credential).all()) - - -def get_credential(credential_id): - """Lists the creds for given a cred_id.""" - session = db.get_session() - try: - return (session.query(network_models_v2.Credential). - filter_by(credential_id=credential_id).one()) - except exc.NoResultFound: - raise c_exc.CredentialNotFound(credential_id=credential_id) - - -def get_credential_name(credential_name): - """Lists the creds for given a cred_name.""" - session = db.get_session() - try: - return (session.query(network_models_v2.Credential). - filter_by(credential_name=credential_name).one()) - except exc.NoResultFound: - raise c_exc.CredentialNameNotFound(credential_name=credential_name) - - -def add_credential(credential_name, user_name, password, type): - """Create a credential.""" - session = db.get_session() - try: - cred = (session.query(network_models_v2.Credential). - filter_by(credential_name=credential_name).one()) - raise c_exc.CredentialAlreadyExists(credential_name=credential_name) - except exc.NoResultFound: - cred = network_models_v2.Credential( - credential_id=uuidutils.generate_uuid(), - credential_name=credential_name, - user_name=user_name, - password=password, - type=type) - session.add(cred) - session.flush() - return cred - - -def remove_credential(credential_id): - """Removes a credential.""" - session = db.get_session() - try: - cred = (session.query(network_models_v2.Credential). - filter_by(credential_id=credential_id).one()) - session.delete(cred) - session.flush() - return cred - except exc.NoResultFound: - pass - - -def update_credential(credential_id, - new_user_name=None, new_password=None): - """Updates a credential for a tenant.""" - session = db.get_session() - try: - cred = (session.query(network_models_v2.Credential). - filter_by(credential_id=credential_id).one()) - if new_user_name: - cred["user_name"] = new_user_name - if new_password: - cred["password"] = new_password - session.merge(cred) - session.flush() - return cred - except exc.NoResultFound: - raise c_exc.CredentialNotFound(credential_id=credential_id) - - -def get_all_n1kv_credentials(): - session = db.get_session() - return (session.query(network_models_v2.Credential). - filter_by(type='n1kv')) - - -def delete_all_n1kv_credentials(): - session = db.get_session() - session.query(network_models_v2.Credential).filter_by(type='n1kv').delete() - - -def add_provider_network(network_id, network_type, segmentation_id): - """Add a network to the provider network table.""" - session = db.get_session() - if session.query(network_models_v2.ProviderNetwork).filter_by( - network_id=network_id).first(): - raise c_exc.ProviderNetworkExists(network_id) - pnet = network_models_v2.ProviderNetwork(network_id=network_id, - network_type=network_type, - segmentation_id=segmentation_id) - session.add(pnet) - session.flush() - - -def remove_provider_network(network_id): - """Remove network_id from the provider network table. - - :param network_id: Any network id. If it is not in the table, do nothing. - :return: network_id if it was in the table and successfully removed. - """ - session = db.get_session() - pnet = (session.query(network_models_v2.ProviderNetwork). - filter_by(network_id=network_id).first()) - if pnet: - session.delete(pnet) - session.flush() - return network_id - - -def is_provider_network(network_id): - """Return True if network_id is in the provider network table.""" - session = db.get_session() - if session.query(network_models_v2.ProviderNetwork).filter_by( - network_id=network_id).first(): - return True - - -def is_provider_vlan(vlan_id): - """Check for a for a vlan provider network with the specified vland_id. - - Returns True if the provider network table contains a vlan network - with the specified vlan_id. - """ - session = db.get_session() - if (session.query(network_models_v2.ProviderNetwork). - filter_by(network_type=const.NETWORK_TYPE_VLAN, - segmentation_id=vlan_id).first()): - return True - - -class Credential_db_mixin(object): - - """Mixin class for Cisco Credentials as a resource.""" - - def _make_credential_dict(self, credential, fields=None): - res = {'credential_id': credential['credential_id'], - 'credential_name': credential['credential_name'], - 'user_name': credential['user_name'], - 'password': credential['password'], - 'type': credential['type']} - return self._fields(res, fields) - - def create_credential(self, context, credential): - """Create a credential.""" - c = credential['credential'] - cred = add_credential(c['credential_name'], - c['user_name'], - c['password'], - c['type']) - return self._make_credential_dict(cred) - - def get_credentials(self, context, filters=None, fields=None): - """Retrieve a list of credentials.""" - return self._get_collection(context, - network_models_v2.Credential, - self._make_credential_dict, - filters=filters, - fields=fields) - - def get_credential(self, context, id, fields=None): - """Retireve the requested credential based on its id.""" - credential = get_credential(id) - return self._make_credential_dict(credential, fields) - - def update_credential(self, context, id, credential): - """Update a credential based on its id.""" - c = credential['credential'] - cred = update_credential(id, - c['user_name'], - c['password']) - return self._make_credential_dict(cred) - - def delete_credential(self, context, id): - """Delete a credential based on its id.""" - return remove_credential(id) diff --git a/neutron/plugins/cisco/db/network_models_v2.py b/neutron/plugins/cisco/db/network_models_v2.py deleted file mode 100644 index 460fcaf3f..000000000 --- a/neutron/plugins/cisco/db/network_models_v2.py +++ /dev/null @@ -1,52 +0,0 @@ -# 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. - -import sqlalchemy as sa - -from neutron.db import model_base - - -class QoS(model_base.BASEV2): - """Represents QoS policies for a tenant.""" - - __tablename__ = 'cisco_qos_policies' - - qos_id = sa.Column(sa.String(255)) - tenant_id = sa.Column(sa.String(255), primary_key=True) - qos_name = sa.Column(sa.String(255), primary_key=True) - qos_desc = sa.Column(sa.String(255)) - - -class Credential(model_base.BASEV2): - """Represents credentials for a tenant to control Cisco switches.""" - - __tablename__ = 'cisco_credentials' - - credential_id = sa.Column(sa.String(255)) - credential_name = sa.Column(sa.String(255), primary_key=True) - user_name = sa.Column(sa.String(255)) - password = sa.Column(sa.String(255)) - type = sa.Column(sa.String(255)) - - -class ProviderNetwork(model_base.BASEV2): - """Represents networks that were created as provider networks.""" - - __tablename__ = 'cisco_provider_networks' - - network_id = sa.Column(sa.String(36), - sa.ForeignKey('networks.id', ondelete="CASCADE"), - primary_key=True) - network_type = sa.Column(sa.String(255), nullable=False) - segmentation_id = sa.Column(sa.Integer, nullable=False) diff --git a/neutron/plugins/cisco/extensions/__init__.py b/neutron/plugins/cisco/extensions/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/plugins/cisco/extensions/_credential_view.py b/neutron/plugins/cisco/extensions/_credential_view.py deleted file mode 100644 index 5ab280991..000000000 --- a/neutron/plugins/cisco/extensions/_credential_view.py +++ /dev/null @@ -1,47 +0,0 @@ -# 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. - - -def get_view_builder(req): - base_url = req.application_url - return ViewBuilder(base_url) - - -class ViewBuilder(object): - """ViewBuilder for Credential, derived from neutron.views.networks.""" - - def __init__(self, base_url): - """Initialize builder. - - :param base_url: url of the root wsgi application - """ - self.base_url = base_url - - def build(self, credential_data, is_detail=False): - """Generic method used to generate a credential entity.""" - if is_detail: - credential = self._build_detail(credential_data) - else: - credential = self._build_simple(credential_data) - return credential - - def _build_simple(self, credential_data): - """Return a simple description of credential.""" - return dict(credential=dict(id=credential_data['credential_id'])) - - def _build_detail(self, credential_data): - """Return a detailed description of credential.""" - return dict(credential=dict(id=credential_data['credential_id'], - name=credential_data['user_name'], - password=credential_data['password'])) diff --git a/neutron/plugins/cisco/extensions/_qos_view.py b/neutron/plugins/cisco/extensions/_qos_view.py deleted file mode 100644 index 187af1950..000000000 --- a/neutron/plugins/cisco/extensions/_qos_view.py +++ /dev/null @@ -1,47 +0,0 @@ -# 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. - - -def get_view_builder(req): - base_url = req.application_url - return ViewBuilder(base_url) - - -class ViewBuilder(object): - """ViewBuilder for QoS, derived from neutron.views.networks.""" - - def __init__(self, base_url): - """Initialize builder. - - :param base_url: url of the root wsgi application - """ - self.base_url = base_url - - def build(self, qos_data, is_detail=False): - """Generic method used to generate a QoS entity.""" - if is_detail: - qos = self._build_detail(qos_data) - else: - qos = self._build_simple(qos_data) - return qos - - def _build_simple(self, qos_data): - """Return a simple description of qos.""" - return dict(qos=dict(id=qos_data['qos_id'])) - - def _build_detail(self, qos_data): - """Return a detailed description of qos.""" - return dict(qos=dict(id=qos_data['qos_id'], - name=qos_data['qos_name'], - description=qos_data['qos_desc'])) diff --git a/neutron/plugins/cisco/extensions/credential.py b/neutron/plugins/cisco/extensions/credential.py deleted file mode 100644 index f4d1f7f8f..000000000 --- a/neutron/plugins/cisco/extensions/credential.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2013 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import base -from neutron import manager - - -# Attribute Map -RESOURCE_ATTRIBUTE_MAP = { - 'credentials': { - 'credential_id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:regex': attributes.UUID_PATTERN}, - 'is_visible': True}, - 'credential_name': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'is_visible': False, 'default': ''}, - 'type': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - 'user_name': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - 'password': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - }, -} - - -class Credential(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - """Returns Extended Resource Name.""" - return "Cisco Credential" - - @classmethod - def get_alias(cls): - """Returns Extended Resource Alias.""" - return "credential" - - @classmethod - def get_description(cls): - """Returns Extended Resource Description.""" - return "Credential include username and password" - - @classmethod - def get_updated(cls): - """Returns Extended Resource Update Time.""" - return "2011-07-25T13:25:27-06:00" - - @classmethod - def get_resources(cls): - """Returns Extended Resources.""" - resource_name = "credential" - collection_name = resource_name + "s" - plugin = manager.NeutronManager.get_plugin() - params = RESOURCE_ATTRIBUTE_MAP.get(collection_name, dict()) - controller = base.create_resource(collection_name, - resource_name, - plugin, params) - return [extensions.ResourceExtension(collection_name, - controller)] diff --git a/neutron/plugins/cisco/extensions/n1kv.py b/neutron/plugins/cisco/extensions/n1kv.py deleted file mode 100644 index e754e0a25..000000000 --- a/neutron/plugins/cisco/extensions/n1kv.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright 2013 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes - - -PROFILE_ID = 'n1kv:profile_id' -MULTICAST_IP = 'n1kv:multicast_ip' -SEGMENT_ADD = 'n1kv:segment_add' -SEGMENT_DEL = 'n1kv:segment_del' -MEMBER_SEGMENTS = 'n1kv:member_segments' - -EXTENDED_ATTRIBUTES_2_0 = { - 'networks': { - PROFILE_ID: {'allow_post': True, 'allow_put': False, - 'validate': {'type:regex': attributes.UUID_PATTERN}, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'is_visible': True}, - MULTICAST_IP: {'allow_post': True, 'allow_put': True, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'is_visible': True}, - SEGMENT_ADD: {'allow_post': True, 'allow_put': True, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'is_visible': True}, - SEGMENT_DEL: {'allow_post': True, 'allow_put': True, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'is_visible': True}, - MEMBER_SEGMENTS: {'allow_post': True, 'allow_put': True, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'is_visible': True}, - }, - 'ports': { - PROFILE_ID: {'allow_post': True, 'allow_put': False, - 'validate': {'type:regex': attributes.UUID_PATTERN}, - 'default': attributes.ATTR_NOT_SPECIFIED, - 'is_visible': True} - } -} - - -class N1kv(extensions.ExtensionDescriptor): - - """Extension class supporting N1kv profiles. - - This class is used by neutron's extension framework to make - metadata about the n1kv profile extension available to - clients. No new resources are defined by this extension. Instead, - the existing network resource's request and response messages are - extended with attributes in the n1kv profile namespace. - - To create a network based on n1kv profile using the CLI with admin rights: - - (shell) net-create --tenant_id \ - --n1kv:profile_id - (shell) port-create --tenant_id \ - --n1kv:profile_id - - - With admin rights, network dictionaries returned from CLI commands - will also include n1kv profile attributes. - """ - - @classmethod - def get_name(cls): - return "n1kv" - - @classmethod - def get_alias(cls): - return "n1kv" - - @classmethod - def get_description(cls): - return "Expose network profile" - - @classmethod - def get_updated(cls): - return "2012-11-15T10:00:00-00:00" - - def get_extended_resources(self, version): - if version == "2.0": - return EXTENDED_ATTRIBUTES_2_0 - else: - return {} diff --git a/neutron/plugins/cisco/extensions/network_profile.py b/neutron/plugins/cisco/extensions/network_profile.py deleted file mode 100644 index 6a16cc2f0..000000000 --- a/neutron/plugins/cisco/extensions/network_profile.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright 2013 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import base -from neutron import manager - - -# Attribute Map -RESOURCE_ATTRIBUTE_MAP = { - 'network_profiles': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:regex': attributes.UUID_PATTERN}, - 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - 'segment_type': {'allow_post': True, 'allow_put': False, - 'is_visible': True, 'default': ''}, - 'sub_type': {'allow_post': True, 'allow_put': False, - 'is_visible': True, - 'default': attributes.ATTR_NOT_SPECIFIED}, - 'segment_range': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': ''}, - 'multicast_ip_range': {'allow_post': True, 'allow_put': True, - 'is_visible': True, - 'default': attributes.ATTR_NOT_SPECIFIED}, - 'multicast_ip_index': {'allow_post': False, 'allow_put': False, - 'is_visible': False, 'default': '0'}, - 'physical_network': {'allow_post': True, 'allow_put': False, - 'is_visible': True, 'default': ''}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'is_visible': False, 'default': ''}, - 'add_tenants': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': None, - 'convert_to': attributes.convert_none_to_empty_list}, - 'remove_tenants': { - 'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': None, - 'convert_to': attributes.convert_none_to_empty_list, - }, - }, - 'network_profile_bindings': { - 'profile_id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:regex': attributes.UUID_PATTERN}, - 'is_visible': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'is_visible': True}, - }, -} - - -class Network_profile(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "Cisco N1kv Network Profiles" - - @classmethod - def get_alias(cls): - return 'network_profile' - - @classmethod - def get_description(cls): - return ("Profile includes the type of profile for N1kv") - - @classmethod - def get_updated(cls): - return "2012-07-20T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Extended Resources.""" - exts = [] - plugin = manager.NeutronManager.get_plugin() - for resource_name in ['network_profile', 'network_profile_binding']: - collection_name = resource_name + "s" - controller = base.create_resource( - collection_name, - resource_name, - plugin, - RESOURCE_ATTRIBUTE_MAP.get(collection_name)) - ex = extensions.ResourceExtension(collection_name, - controller) - exts.append(ex) - return exts diff --git a/neutron/plugins/cisco/extensions/policy_profile.py b/neutron/plugins/cisco/extensions/policy_profile.py deleted file mode 100644 index 04515c20c..000000000 --- a/neutron/plugins/cisco/extensions/policy_profile.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2013 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. - -from neutron.api import extensions -from neutron.api.v2 import attributes -from neutron.api.v2 import base -from neutron import manager - -# Attribute Map -RESOURCE_ATTRIBUTE_MAP = { - 'policy_profiles': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:regex': attributes.UUID_PATTERN}, - 'is_visible': True}, - 'name': {'allow_post': False, 'allow_put': False, - 'is_visible': True, 'default': ''}, - 'add_tenant': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': None}, - 'remove_tenant': {'allow_post': True, 'allow_put': True, - 'is_visible': True, 'default': None}, - }, - 'policy_profile_bindings': { - 'profile_id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:regex': attributes.UUID_PATTERN}, - 'is_visible': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'is_visible': True}, - }, -} - - -class Policy_profile(extensions.ExtensionDescriptor): - - @classmethod - def get_name(cls): - return "Cisco Nexus1000V Policy Profiles" - - @classmethod - def get_alias(cls): - return 'policy_profile' - - @classmethod - def get_description(cls): - return "Profile includes the type of profile for N1kv" - - @classmethod - def get_updated(cls): - return "2012-07-20T10:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Extended Resources.""" - exts = [] - plugin = manager.NeutronManager.get_plugin() - for resource_name in ['policy_profile', 'policy_profile_binding']: - collection_name = resource_name + "s" - controller = base.create_resource( - collection_name, - resource_name, - plugin, - RESOURCE_ATTRIBUTE_MAP.get(collection_name)) - ex = extensions.ResourceExtension(collection_name, - controller) - exts.append(ex) - return exts diff --git a/neutron/plugins/cisco/extensions/qos.py b/neutron/plugins/cisco/extensions/qos.py deleted file mode 100644 index b9428f23d..000000000 --- a/neutron/plugins/cisco/extensions/qos.py +++ /dev/null @@ -1,146 +0,0 @@ -# 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. - -from webob import exc - -from neutron.api import api_common as common -from neutron.api import extensions -from neutron import manager -from neutron.plugins.cisco.common import cisco_exceptions as exception -from neutron.plugins.cisco.common import cisco_faults as faults -from neutron.plugins.cisco.extensions import _qos_view as qos_view -from neutron import wsgi - - -class Qos(extensions.ExtensionDescriptor): - """Qos extension file.""" - - @classmethod - def get_name(cls): - """Returns Ext Resource Name.""" - return "Cisco qos" - - @classmethod - def get_alias(cls): - """Returns Ext Resource Alias.""" - return "Cisco qos" - - @classmethod - def get_description(cls): - """Returns Ext Resource Description.""" - return "qos includes qos_name and qos_desc" - - @classmethod - def get_updated(cls): - """Returns Ext Resource update.""" - return "2011-07-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 = QosController(manager.NeutronManager.get_plugin()) - return [extensions.ResourceExtension('qoss', controller, - parent=parent_resource)] - - -class QosController(common.NeutronController, wsgi.Controller): - """qos API controller based on NeutronController.""" - - _qos_ops_param_list = [ - {'param-name': 'qos_name', 'required': True}, - {'param-name': 'qos_desc', 'required': True}, - ] - - _serialization_metadata = { - "application/xml": { - "attributes": { - "qos": ["id", "name"], - }, - }, - } - - def __init__(self, plugin): - self._resource_name = 'qos' - self._plugin = plugin - - def index(self, request, tenant_id): - """Returns a list of qos ids.""" - return self._items(request, tenant_id, is_detail=False) - - def _items(self, request, tenant_id, is_detail): - """Returns a list of qoss.""" - qoss = self._plugin.get_all_qoss(tenant_id) - builder = qos_view.get_view_builder(request) - result = [builder.build(qos, is_detail)['qos'] for qos in qoss] - return dict(qoss=result) - - # pylint: disable=no-member - def show(self, request, tenant_id, id): - """Returns qos details for the given qos id.""" - try: - qos = self._plugin.get_qos_details(tenant_id, id) - builder = qos_view.get_view_builder(request) - #build response with details - result = builder.build(qos, True) - return dict(qoss=result) - except exception.QosNotFound as exp: - return faults.Fault(faults.QosNotFound(exp)) - - def create(self, request, tenant_id): - """Creates a new qos for a given tenant.""" - #look for qos name in request - try: - body = self._deserialize(request.body, request.get_content_type()) - req_body = self._prepare_request_body(body, - self._qos_ops_param_list) - req_params = req_body[self._resource_name] - except exc.HTTPError as exp: - return faults.Fault(exp) - qos = self._plugin.create_qos(tenant_id, - req_params['qos_name'], - req_params['qos_desc']) - builder = qos_view.get_view_builder(request) - result = builder.build(qos) - return dict(qoss=result) - - def update(self, request, tenant_id, id): - """Updates the name for the qos with the given id.""" - try: - body = self._deserialize(request.body, request.get_content_type()) - req_body = self._prepare_request_body(body, - self._qos_ops_param_list) - req_params = req_body[self._resource_name] - except exc.HTTPError as exp: - return faults.Fault(exp) - try: - qos = self._plugin.rename_qos(tenant_id, id, - req_params['qos_name']) - - builder = qos_view.get_view_builder(request) - result = builder.build(qos, True) - return dict(qoss=result) - except exception.QosNotFound as exp: - return faults.Fault(faults.QosNotFound(exp)) - - def delete(self, request, tenant_id, id): - """Destroys the qos with the given id.""" - try: - self._plugin.delete_qos(tenant_id, id) - return exc.HTTPOk() - except exception.QosNotFound as exp: - return faults.Fault(faults.QosNotFound(exp)) diff --git a/neutron/plugins/cisco/l2device_plugin_base.py b/neutron/plugins/cisco/l2device_plugin_base.py deleted file mode 100644 index 660e5f8d0..000000000 --- a/neutron/plugins/cisco/l2device_plugin_base.py +++ /dev/null @@ -1,171 +0,0 @@ -# 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. - -import abc -import inspect -import six - - -@six.add_metaclass(abc.ABCMeta) -class L2DevicePluginBase(object): - """Base class for a device-specific plugin. - - An example of a device-specific plugin is a Nexus switch plugin. - The network model relies on device-category-specific plugins to perform - the configuration on each device. - """ - - @abc.abstractmethod - def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id, - **kwargs): - """Create network. - - :returns: - :raises: - """ - pass - - @abc.abstractmethod - def delete_network(self, tenant_id, net_id, **kwargs): - """Delete network. - - :returns: - :raises: - """ - pass - - @abc.abstractmethod - def update_network(self, tenant_id, net_id, name, **kwargs): - """Update network. - - :returns: - :raises: - """ - pass - - @abc.abstractmethod - def create_port(self, tenant_id, net_id, port_state, port_id, **kwargs): - """Create port. - - :returns: - :raises: - """ - pass - - @abc.abstractmethod - def delete_port(self, tenant_id, net_id, port_id, **kwargs): - """Delete port. - - :returns: - :raises: - """ - pass - - @abc.abstractmethod - def update_port(self, tenant_id, net_id, port_id, **kwargs): - """Update port. - - :returns: - :raises: - """ - pass - - @abc.abstractmethod - def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id, - **kwargs): - """Plug interface. - - :returns: - :raises: - """ - pass - - @abc.abstractmethod - def unplug_interface(self, tenant_id, net_id, port_id, **kwargs): - """Unplug interface. - - :returns: - :raises: - """ - pass - - def create_subnet(self, tenant_id, net_id, ip_version, - subnet_cidr, **kwargs): - """Create subnet. - - :returns: - :raises: - """ - pass - - def get_subnets(self, tenant_id, net_id, **kwargs): - """Get subnets. - - :returns: - :raises: - """ - pass - - def get_subnet(self, tenant_id, net_id, subnet_id, **kwargs): - """Get subnet. - - :returns: - :raises: - """ - pass - - def update_subnet(self, tenant_id, net_id, subnet_id, **kwargs): - """Update subnet. - - :returns: - :raises: - """ - pass - - def delete_subnet(self, tenant_id, net_id, subnet_id, **kwargs): - """Delete subnet. - - :returns: - :raises: - """ - pass - - @classmethod - def __subclasshook__(cls, klass): - """Check plugin class. - - The __subclasshook__ method is a class method - that will be called every time 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 L2DevicePluginBase: - 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.__code__.co_argcount - expected_arg_count = \ - abstract_fn_obj.__code__.co_argcount - method_ok = arg_count == expected_arg_count - if method_ok: - continue - return NotImplemented - return True - return NotImplemented diff --git a/neutron/plugins/cisco/models/__init__.py b/neutron/plugins/cisco/models/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/plugins/cisco/models/virt_phy_sw_v2.py b/neutron/plugins/cisco/models/virt_phy_sw_v2.py deleted file mode 100644 index 13fecd6ae..000000000 --- a/neutron/plugins/cisco/models/virt_phy_sw_v2.py +++ /dev/null @@ -1,320 +0,0 @@ -# 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. - -import inspect - -from oslo_log import log as logging -from oslo_utils import excutils -from oslo_utils import importutils - -from neutron.api.v2 import attributes -from neutron.extensions import portbindings -from neutron.extensions import providernet as provider -from neutron.i18n import _LE, _LI -from neutron import neutron_plugin_base_v2 -from neutron.plugins.cisco.common import cisco_constants as const -from neutron.plugins.cisco.common import cisco_credentials_v2 as cred -from neutron.plugins.cisco.common import config as conf -from neutron.plugins.cisco.db import network_db_v2 as cdb - - -LOG = logging.getLogger(__name__) - - -class VirtualPhysicalSwitchModelV2(neutron_plugin_base_v2.NeutronPluginBaseV2): - """Virtual Physical Switch Model. - - This implementation works with n1kv sub-plugin for the - following topology: - One or more servers to a n1kv switch. - """ - __native_bulk_support = True - supported_extension_aliases = ["provider", "binding"] - _methods_to_delegate = ['create_network_bulk', - 'get_network', 'get_networks', - 'create_port_bulk', - 'get_port', 'get_ports', - 'create_subnet', 'create_subnet_bulk', - 'delete_subnet', 'update_subnet', - 'get_subnet', 'get_subnets', - 'create_or_update_agent', 'report_state'] - - def __init__(self): - """Initialize the segmentation manager. - - Checks which device plugins are configured, and load the inventories - those device plugins for which the inventory is configured. - """ - conf.CiscoConfigOptions() - - self._plugins = {} - self._plugins['vswitch_plugin'] = importutils.import_object( - 'neutron.plugins.cisco.n1kv.n1kv_neutron_plugin.' - 'N1kvNeutronPluginV2') - - if ((const.VSWITCH_PLUGIN in self._plugins) and - hasattr(self._plugins[const.VSWITCH_PLUGIN], - "supported_extension_aliases")): - self.supported_extension_aliases.extend( - self._plugins[const.VSWITCH_PLUGIN]. - supported_extension_aliases) - - # Initialize credential store after database initialization - cred.Store.initialize() - LOG.debug("%(module)s.%(name)s init done", - {'module': __name__, - 'name': self.__class__.__name__}) - - def __getattribute__(self, name): - """Delegate calls to sub-plugin. - - This delegates the calls to the methods implemented by the - sub-plugin. Note: Currently, bulking is handled by the caller - (PluginV2), and this model class expects to receive only non-bulking - calls. If, however, a bulking call is made, this will method will - delegate the call to the sub-plugin. - """ - super_getattribute = super(VirtualPhysicalSwitchModelV2, - self).__getattribute__ - methods = super_getattribute('_methods_to_delegate') - - if name in methods: - plugin = super_getattribute('_plugins')[const.VSWITCH_PLUGIN] - return getattr(plugin, name) - - try: - return super_getattribute(name) - except AttributeError: - plugin = super_getattribute('_plugins')[const.VSWITCH_PLUGIN] - return getattr(plugin, name) - - def _func_name(self, offset=0): - """Get the name of the calling function.""" - frame_record = inspect.stack()[1 + offset] - func_name = frame_record[3] - return func_name - - def _invoke_plugin_per_device(self, plugin_key, function_name, - args, **kwargs): - """Invoke plugin per device. - - Invokes a device plugin's relevant functions (based on the - plugin implementation) for completing this operation. - """ - if plugin_key not in self._plugins: - LOG.info(_LI("No %s Plugin loaded"), plugin_key) - LOG.info(_LI("%(plugin_key)s: %(function_name)s with args " - "%(args)s ignored"), - {'plugin_key': plugin_key, - 'function_name': function_name, - 'args': args}) - else: - func = getattr(self._plugins[plugin_key], function_name) - return func(*args, **kwargs) - - def _get_provider_vlan_id(self, network): - if (all(attributes.is_attr_set(network.get(attr)) - for attr in (provider.NETWORK_TYPE, - provider.PHYSICAL_NETWORK, - provider.SEGMENTATION_ID)) - and - network[provider.NETWORK_TYPE] == const.NETWORK_TYPE_VLAN): - return network[provider.SEGMENTATION_ID] - - def create_network(self, context, network): - """Create network. - - Perform this operation in the context of the configured device - plugins. - """ - LOG.debug("create_network() called") - provider_vlan_id = self._get_provider_vlan_id(network[const.NETWORK]) - args = [context, network] - switch_output = self._invoke_plugin_per_device(const.VSWITCH_PLUGIN, - self._func_name(), - args) - # The vswitch plugin did all the verification. If it's a provider - # vlan network, save it for the sub-plugin to use later. - if provider_vlan_id: - network_id = switch_output[const.NET_ID] - cdb.add_provider_network(network_id, - const.NETWORK_TYPE_VLAN, - provider_vlan_id) - LOG.debug("Provider network added to DB: %(network_id)s, " - "%(vlan_id)s", - {'network_id': network_id, 'vlan_id': provider_vlan_id}) - return switch_output - - def update_network(self, context, id, network): - """Update network. - - Perform this operation in the context of the configured device - plugins. - """ - LOG.debug("update_network() called") - - # We can only support updating of provider attributes if all the - # configured sub-plugins support it. Currently we have no method - # in place for checking whether a sub-plugin supports it, - # so assume not. - provider._raise_if_updates_provider_attributes(network['network']) - - args = [context, id, network] - return self._invoke_plugin_per_device(const.VSWITCH_PLUGIN, - self._func_name(), - args) - - def delete_network(self, context, id): - """Delete network. - - Perform this operation in the context of the configured device - plugins. - """ - args = [context, id] - switch_output = self._invoke_plugin_per_device(const.VSWITCH_PLUGIN, - self._func_name(), - args) - if cdb.remove_provider_network(id): - LOG.debug("Provider network removed from DB: %s", id) - return switch_output - - def get_network(self, context, id, fields=None): - """Get network. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover - - def get_networks(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, page_reverse=False): - """Get networks. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover - - def _check_valid_port_device_owner(self, port): - """Check the port for valid device_owner. - - Don't call the sub-plugin for router and dhcp - port owners. - """ - return port['device_owner'].startswith('compute') - - def _get_port_host_id_from_bindings(self, port): - """Get host_id from portbindings.""" - host_id = None - - if (portbindings.HOST_ID in port and - attributes.is_attr_set(port[portbindings.HOST_ID])): - host_id = port[portbindings.HOST_ID] - - return host_id - - def create_port(self, context, port): - """Create port. - - Perform this operation in the context of the configured device - plugins. - """ - LOG.debug("create_port() called") - args = [context, port] - return self._invoke_plugin_per_device(const.VSWITCH_PLUGIN, - self._func_name(), - args) - - def get_port(self, context, id, fields=None): - """Get port. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover - - def get_ports(self, context, filters=None, fields=None): - """Get ports. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover - - def update_port(self, context, id, port): - """Update port. - - Perform this operation in the context of the configured device - plugins. - """ - LOG.debug("update_port() called") - args = [context, id, port] - return self._invoke_plugin_per_device(const.VSWITCH_PLUGIN, - self._func_name(), - args) - - def delete_port(self, context, id, l3_port_check=True): - """Delete port. - - Perform this operation in the context of the configured device - plugins. - """ - LOG.debug("delete_port() called") - port = self.get_port(context, id) - - try: - args = [context, id] - switch_output = self._invoke_plugin_per_device( - const.VSWITCH_PLUGIN, self._func_name(), - args, l3_port_check=l3_port_check) - except Exception as e: - with excutils.save_and_reraise_exception(): - LOG.error(_LE("Unable to delete port '%(pname)s' on switch. " - "Exception: %(exp)s"), {'pname': port['name'], - 'exp': e}) - - return switch_output - - def create_subnet(self, context, subnet): - """Create subnet. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover - - def update_subnet(self, context, id, subnet): - """Update subnet. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover - - def get_subnet(self, context, id, fields=None): - """Get subnet. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover - - def delete_subnet(self, context, id, kwargs): - """Delete subnet. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover - - def get_subnets(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, page_reverse=False): - """Get subnets. This method is delegated to the vswitch plugin. - - This method is included here to satisfy abstract method requirements. - """ - pass # pragma no cover diff --git a/neutron/plugins/cisco/n1kv/__init__.py b/neutron/plugins/cisco/n1kv/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/plugins/cisco/n1kv/n1kv_client.py b/neutron/plugins/cisco/n1kv/n1kv_client.py deleted file mode 100644 index edbf5e7db..000000000 --- a/neutron/plugins/cisco/n1kv/n1kv_client.py +++ /dev/null @@ -1,558 +0,0 @@ -# Copyright 2013 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. - -import base64 - -import eventlet -import netaddr -from oslo_log import log as logging -from oslo_serialization import jsonutils -import requests -import six - -from neutron.common import exceptions as n_exc -from neutron.extensions import providernet -from neutron.plugins.cisco.common import cisco_constants as c_const -from neutron.plugins.cisco.common import cisco_credentials_v2 as c_cred -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.common import config as c_conf -from neutron.plugins.cisco.db import network_db_v2 -from neutron.plugins.cisco.extensions import n1kv - -LOG = logging.getLogger(__name__) - - -def safe_b64_encode(s): - if six.PY3: - method = base64.encodebytes - else: - method = base64.encodestring - - if isinstance(s, six.text_type): - s = s.encode('utf-8') - encoded_string = method(s).rstrip() - - if six.PY3: - return encoded_string.decode('utf-8') - else: - return encoded_string - - -class Client(object): - - """ - Client for the Cisco Nexus1000V Neutron Plugin. - - This client implements functions to communicate with - Cisco Nexus1000V VSM. - - For every Neutron objects, Cisco Nexus1000V Neutron Plugin - creates a corresponding object in the controller (Cisco - Nexus1000V VSM). - - CONCEPTS: - - Following are few concepts used in Nexus1000V VSM: - - port-profiles: - Policy profiles correspond to port profiles on Nexus1000V VSM. - Port profiles are the primary mechanism by which network policy is - defined and applied to switch interfaces in a Nexus 1000V system. - - network-segment: - Each network-segment represents a broadcast domain. - - network-segment-pool: - A network-segment-pool contains one or more network-segments. - - logical-network: - A logical-network contains one or more network-segment-pools. - - bridge-domain: - A bridge-domain is created when the network-segment is of type VXLAN. - Each VXLAN <--> VLAN combination can be thought of as a bridge domain. - - ip-pool: - Each ip-pool represents a subnet on the Nexus1000V VSM. - - vm-network: - vm-network refers to a network-segment and policy-profile. - It maintains a list of ports that uses the network-segment and - policy-profile this vm-network refers to. - - events: - Events correspond to commands that are logged on Nexus1000V VSM. - Events are used to poll for a certain resource on Nexus1000V VSM. - Event type of port_profile: Return all updates/create/deletes - of port profiles from the VSM. - Event type of port_profile_update: Return only updates regarding - policy-profiles. - Event type of port_profile_delete: Return only deleted policy profiles. - - - WORK FLOW: - - For every network profile a corresponding logical-network and - a network-segment-pool, under this logical-network, will be created. - - For every network created from a given network profile, a - network-segment will be added to the network-segment-pool corresponding - to that network profile. - - A port is created on a network and associated with a policy-profile. - Hence for every unique combination of a network and a policy-profile, a - unique vm-network will be created and a reference to the port will be - added. If the same combination of network and policy-profile is used by - another port, the references to that port will be added to the same - vm-network. - - - """ - - # Define paths for the URI where the client connects for HTTP requests. - port_profiles_path = "/virtual-port-profile" - network_segment_path = "/network-segment/%s" - network_segment_pool_path = "/network-segment-pool/%s" - ip_pool_path = "/ip-pool-template/%s" - ports_path = "/kvm/vm-network/%s/ports" - port_path = "/kvm/vm-network/%s/ports/%s" - vm_networks_path = "/kvm/vm-network" - vm_network_path = "/kvm/vm-network/%s" - bridge_domains_path = "/kvm/bridge-domain" - bridge_domain_path = "/kvm/bridge-domain/%s" - logical_network_path = "/logical-network/%s" - events_path = "/kvm/events" - clusters_path = "/cluster" - encap_profiles_path = "/encapsulation-profile" - encap_profile_path = "/encapsulation-profile/%s" - - pool = eventlet.GreenPool(c_conf.CISCO_N1K.http_pool_size) - - def __init__(self, **kwargs): - """Initialize a new client for the plugin.""" - self.format = 'json' - self.hosts = self._get_vsm_hosts() - self.action_prefix = 'http://%s/api/n1k' % self.hosts[0] - self.timeout = c_conf.CISCO_N1K.http_timeout - - def list_port_profiles(self): - """ - Fetch all policy profiles from the VSM. - - :returns: JSON string - """ - return self._get(self.port_profiles_path) - - def create_bridge_domain(self, network, overlay_subtype): - """ - Create a bridge domain on VSM. - - :param network: network dict - :param overlay_subtype: string representing subtype of overlay network - """ - body = {'name': network['id'] + c_const.BRIDGE_DOMAIN_SUFFIX, - 'segmentId': network[providernet.SEGMENTATION_ID], - 'subType': overlay_subtype, - 'tenantId': network['tenant_id']} - if overlay_subtype == c_const.NETWORK_SUBTYPE_NATIVE_VXLAN: - body['groupIp'] = network[n1kv.MULTICAST_IP] - return self._post(self.bridge_domains_path, - body=body) - - def delete_bridge_domain(self, name): - """ - Delete a bridge domain on VSM. - - :param name: name of the bridge domain to be deleted - """ - return self._delete(self.bridge_domain_path % name) - - def create_network_segment(self, network, network_profile): - """ - Create a network segment on the VSM. - - :param network: network dict - :param network_profile: network profile dict - """ - body = {'publishName': network['id'], - 'description': network['name'], - 'id': network['id'], - 'tenantId': network['tenant_id'], - 'networkSegmentPool': network_profile['id'], } - if network[providernet.NETWORK_TYPE] == c_const.NETWORK_TYPE_VLAN: - body['vlan'] = network[providernet.SEGMENTATION_ID] - elif network[providernet.NETWORK_TYPE] == c_const.NETWORK_TYPE_OVERLAY: - body['bridgeDomain'] = (network['id'] + - c_const.BRIDGE_DOMAIN_SUFFIX) - if network_profile['segment_type'] == c_const.NETWORK_TYPE_TRUNK: - body['mode'] = c_const.NETWORK_TYPE_TRUNK - body['segmentType'] = network_profile['sub_type'] - if network_profile['sub_type'] == c_const.NETWORK_TYPE_VLAN: - body['addSegments'] = network['add_segment_list'] - body['delSegments'] = network['del_segment_list'] - else: - body['encapProfile'] = (network['id'] + - c_const.ENCAPSULATION_PROFILE_SUFFIX) - else: - body['mode'] = 'access' - body['segmentType'] = network_profile['segment_type'] - return self._post(self.network_segment_path % network['id'], - body=body) - - def update_network_segment(self, network_segment_id, body): - """ - Update a network segment on the VSM. - - Network segment on VSM can be updated to associate it with an ip-pool - or update its description and segment id. - - :param network_segment_id: UUID representing the network segment - :param body: dict of arguments to be updated - """ - return self._post(self.network_segment_path % network_segment_id, - body=body) - - def delete_network_segment(self, network_segment_id): - """ - Delete a network segment on the VSM. - - :param network_segment_id: UUID representing the network segment - """ - return self._delete(self.network_segment_path % network_segment_id) - - def create_logical_network(self, network_profile, tenant_id): - """ - Create a logical network on the VSM. - - :param network_profile: network profile dict - :param tenant_id: UUID representing the tenant - """ - LOG.debug("Logical network") - body = {'description': network_profile['name'], - 'tenantId': tenant_id} - logical_network_name = (network_profile['id'] + - c_const.LOGICAL_NETWORK_SUFFIX) - return self._post(self.logical_network_path % logical_network_name, - body=body) - - def delete_logical_network(self, logical_network_name): - """ - Delete a logical network on VSM. - - :param logical_network_name: string representing name of the logical - network - """ - return self._delete( - self.logical_network_path % logical_network_name) - - def create_network_segment_pool(self, network_profile, tenant_id): - """ - Create a network segment pool on the VSM. - - :param network_profile: network profile dict - :param tenant_id: UUID representing the tenant - """ - LOG.debug("network_segment_pool") - logical_network_name = (network_profile['id'] + - c_const.LOGICAL_NETWORK_SUFFIX) - body = {'name': network_profile['name'], - 'description': network_profile['name'], - 'id': network_profile['id'], - 'logicalNetwork': logical_network_name, - 'tenantId': tenant_id} - if network_profile['segment_type'] == c_const.NETWORK_TYPE_OVERLAY: - body['subType'] = network_profile['sub_type'] - return self._post( - self.network_segment_pool_path % network_profile['id'], - body=body) - - def update_network_segment_pool(self, network_profile): - """ - Update a network segment pool on the VSM. - - :param network_profile: network profile dict - """ - body = {'name': network_profile['name'], - 'description': network_profile['name']} - return self._post(self.network_segment_pool_path % - network_profile['id'], body=body) - - def delete_network_segment_pool(self, network_segment_pool_id): - """ - Delete a network segment pool on the VSM. - - :param network_segment_pool_id: UUID representing the network - segment pool - """ - return self._delete(self.network_segment_pool_path % - network_segment_pool_id) - - def create_ip_pool(self, subnet): - """ - Create an ip-pool on the VSM. - - :param subnet: subnet dict - """ - if subnet['cidr']: - try: - ip = netaddr.IPNetwork(subnet['cidr']) - netmask = str(ip.netmask) - network_address = str(ip.network) - except (ValueError, netaddr.AddrFormatError): - msg = _("Invalid input for CIDR") - raise n_exc.InvalidInput(error_message=msg) - else: - netmask = network_address = "" - - if subnet['allocation_pools']: - address_range_start = subnet['allocation_pools'][0]['start'] - address_range_end = subnet['allocation_pools'][0]['end'] - else: - address_range_start = None - address_range_end = None - - body = {'addressRangeStart': address_range_start, - 'addressRangeEnd': address_range_end, - 'ipAddressSubnet': netmask, - 'description': subnet['name'], - 'gateway': subnet['gateway_ip'], - 'dhcp': subnet['enable_dhcp'], - 'dnsServersList': subnet['dns_nameservers'], - 'networkAddress': network_address, - 'netSegmentName': subnet['network_id'], - 'id': subnet['id'], - 'tenantId': subnet['tenant_id']} - return self._post(self.ip_pool_path % subnet['id'], - body=body) - - def update_ip_pool(self, subnet): - """ - Update an ip-pool on the VSM. - - :param subnet: subnet dictionary - """ - body = {'description': subnet['name'], - 'dhcp': subnet['enable_dhcp'], - 'dnsServersList': subnet['dns_nameservers']} - return self._post(self.ip_pool_path % subnet['id'], - body=body) - - def delete_ip_pool(self, subnet_id): - """ - Delete an ip-pool on the VSM. - - :param subnet_id: UUID representing the subnet - """ - return self._delete(self.ip_pool_path % subnet_id) - - def create_vm_network(self, - port, - vm_network_name, - policy_profile): - """ - Create a VM network on the VSM. - - :param port: port dict - :param vm_network_name: name of the VM network - :param policy_profile: policy profile dict - """ - body = {'name': vm_network_name, - 'networkSegmentId': port['network_id'], - 'networkSegment': port['network_id'], - 'portProfile': policy_profile['name'], - 'portProfileId': policy_profile['id'], - 'tenantId': port['tenant_id'], - 'portId': port['id'], - 'macAddress': port['mac_address'], - } - if port.get('fixed_ips'): - body['ipAddress'] = port['fixed_ips'][0]['ip_address'] - body['subnetId'] = port['fixed_ips'][0]['subnet_id'] - return self._post(self.vm_networks_path, - body=body) - - def delete_vm_network(self, vm_network_name): - """ - Delete a VM network on the VSM. - - :param vm_network_name: name of the VM network - """ - return self._delete(self.vm_network_path % vm_network_name) - - def create_n1kv_port(self, port, vm_network_name): - """ - Create a port on the VSM. - - :param port: port dict - :param vm_network_name: name of the VM network which imports this port - """ - body = {'id': port['id'], - 'macAddress': port['mac_address']} - if port.get('fixed_ips'): - body['ipAddress'] = port['fixed_ips'][0]['ip_address'] - body['subnetId'] = port['fixed_ips'][0]['subnet_id'] - return self._post(self.ports_path % vm_network_name, - body=body) - - def update_n1kv_port(self, vm_network_name, port_id, body): - """ - Update a port on the VSM. - - Update the mac address associated with the port - - :param vm_network_name: name of the VM network which imports this port - :param port_id: UUID of the port - :param body: dict of the arguments to be updated - """ - return self._post(self.port_path % (vm_network_name, port_id), - body=body) - - def delete_n1kv_port(self, vm_network_name, port_id): - """ - Delete a port on the VSM. - - :param vm_network_name: name of the VM network which imports this port - :param port_id: UUID of the port - """ - return self._delete(self.port_path % (vm_network_name, port_id)) - - def _do_request(self, method, action, body=None, - headers=None): - """ - Perform the HTTP request. - - The response is in either JSON format or plain text. A GET method will - invoke a JSON response while a PUT/POST/DELETE returns message from the - VSM in plain text format. - Exception is raised when VSM replies with an INTERNAL SERVER ERROR HTTP - status code (500) i.e. an error has occurred on the VSM or SERVICE - UNAVAILABLE (503) i.e. VSM is not reachable. - - :param method: type of the HTTP request. POST, GET, PUT or DELETE - :param action: path to which the client makes request - :param body: dict for arguments which are sent as part of the request - :param headers: header for the HTTP request - :returns: JSON or plain text in HTTP response - """ - action = self.action_prefix + action - if not headers and self.hosts: - headers = self._get_auth_header(self.hosts[0]) - headers['Content-Type'] = self._set_content_type('json') - headers['Accept'] = self._set_content_type('json') - if body: - body = jsonutils.dumps(body, indent=2) - LOG.debug("req: %s", body) - try: - resp = self.pool.spawn(requests.request, - method, - url=action, - data=body, - headers=headers, - timeout=self.timeout).wait() - except Exception as e: - raise c_exc.VSMConnectionFailed(reason=e) - LOG.debug("status_code %s", resp.status_code) - if resp.status_code == requests.codes.OK: - if 'application/json' in resp.headers['content-type']: - try: - return resp.json() - except ValueError: - return {} - elif 'text/plain' in resp.headers['content-type']: - LOG.debug("VSM: %s", resp.text) - else: - raise c_exc.VSMError(reason=resp.text) - - def _set_content_type(self, format=None): - """ - Set the mime-type to either 'xml' or 'json'. - - :param format: format to be set. - :return: mime-type string - """ - if not format: - format = self.format - return "application/%s" % format - - def _delete(self, action, body=None, headers=None): - return self._do_request("DELETE", action, body=body, - headers=headers) - - def _get(self, action, body=None, headers=None): - return self._do_request("GET", action, body=body, - headers=headers) - - def _post(self, action, body=None, headers=None): - return self._do_request("POST", action, body=body, - headers=headers) - - def _put(self, action, body=None, headers=None): - return self._do_request("PUT", action, body=body, - headers=headers) - - def _get_vsm_hosts(self): - """ - Retrieve a list of VSM ip addresses. - - :return: list of host ip addresses - """ - return [cr[c_const.CREDENTIAL_NAME] for cr in - network_db_v2.get_all_n1kv_credentials()] - - def _get_auth_header(self, host_ip): - """ - Retrieve header with auth info for the VSM. - - :param host_ip: IP address of the VSM - :return: authorization header dict - """ - username = c_cred.Store.get_username(host_ip) - password = c_cred.Store.get_password(host_ip) - auth = safe_b64_encode("%s:%s" % (username, password)) - header = {"Authorization": "Basic %s" % auth} - return header - - def get_clusters(self): - """Fetches a list of all vxlan gateway clusters.""" - return self._get(self.clusters_path) - - def create_encapsulation_profile(self, encap): - """ - Create an encapsulation profile on VSM. - - :param encap: encapsulation dict - """ - body = {'name': encap['name'], - 'addMappings': encap['add_segment_list'], - 'delMappings': encap['del_segment_list']} - return self._post(self.encap_profiles_path, - body=body) - - def update_encapsulation_profile(self, context, profile_name, body): - """ - Adds a vlan to bridge-domain mapping to an encapsulation profile. - - :param profile_name: Name of the encapsulation profile - :param body: mapping dictionary - """ - return self._post(self.encap_profile_path - % profile_name, body=body) - - def delete_encapsulation_profile(self, name): - """ - Delete an encapsulation profile on VSM. - - :param name: name of the encapsulation profile to be deleted - """ - return self._delete(self.encap_profile_path % name) diff --git a/neutron/plugins/cisco/n1kv/n1kv_neutron_plugin.py b/neutron/plugins/cisco/n1kv/n1kv_neutron_plugin.py deleted file mode 100644 index 31953df53..000000000 --- a/neutron/plugins/cisco/n1kv/n1kv_neutron_plugin.py +++ /dev/null @@ -1,1429 +0,0 @@ -# Copyright 2013 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. - -import eventlet -from oslo_config import cfg as o_conf -from oslo_log import log as logging -from oslo_utils import excutils -from oslo_utils import importutils -from oslo_utils import uuidutils - -from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api -from neutron.api.rpc.handlers import dhcp_rpc -from neutron.api.rpc.handlers import metadata_rpc -from neutron.api.v2 import attributes -from neutron.common import constants -from neutron.common import exceptions as n_exc -from neutron.common import rpc as n_rpc -from neutron.common import topics -from neutron.db import agents_db -from neutron.db import agentschedulers_db -from neutron.db import db_base_plugin_v2 -from neutron.db import external_net_db -from neutron.db import portbindings_db -from neutron.db.quota import driver -from neutron.extensions import portbindings -from neutron.extensions import providernet -from neutron.i18n import _LW -from neutron import manager -from neutron.plugins.cisco.common import cisco_constants as c_const -from neutron.plugins.cisco.common import cisco_credentials_v2 as c_cred -from neutron.plugins.cisco.common import cisco_exceptions -from neutron.plugins.cisco.common import config as c_conf -from neutron.plugins.cisco.db import n1kv_db_v2 -from neutron.plugins.cisco.db import network_db_v2 -from neutron.plugins.cisco.extensions import n1kv -from neutron.plugins.cisco.n1kv import n1kv_client -from neutron.plugins.common import constants as svc_constants -from neutron.plugins.common import utils - - -LOG = logging.getLogger(__name__) - - -class N1kvNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2, - external_net_db.External_net_db_mixin, - portbindings_db.PortBindingMixin, - n1kv_db_v2.NetworkProfile_db_mixin, - n1kv_db_v2.PolicyProfile_db_mixin, - network_db_v2.Credential_db_mixin, - agentschedulers_db.DhcpAgentSchedulerDbMixin, - driver.DbQuotaDriver): - - """ - Implement the Neutron abstractions using Cisco Nexus1000V. - - Refer README file for the architecture, new features, and - workflow - - """ - - # This attribute specifies whether the plugin supports or not - # bulk operations. - __native_bulk_support = False - supported_extension_aliases = ["provider", "agent", - "n1kv", "network_profile", - "policy_profile", "external-net", - "binding", "credential", "quotas", - "dhcp_agent_scheduler"] - - def __init__(self, configfile=None): - """ - Initialize Nexus1000V Neutron plugin. - - 1. Initialize VIF type to OVS - 2. clear N1kv credential - 3. Initialize Nexus1000v and Credential DB - 4. Establish communication with Cisco Nexus1000V - """ - super(N1kvNeutronPluginV2, self).__init__() - self.base_binding_dict = { - portbindings.VIF_TYPE: portbindings.VIF_TYPE_OVS, - portbindings.VIF_DETAILS: { - # TODO(rkukura): Replace with new VIF security details - portbindings.CAP_PORT_FILTER: - 'security-group' in self.supported_extension_aliases}} - network_db_v2.delete_all_n1kv_credentials() - c_cred.Store.initialize() - self._setup_vsm() - self._setup_rpc() - self.network_scheduler = importutils.import_object( - o_conf.CONF.network_scheduler_driver - ) - self.start_periodic_dhcp_agent_status_check() - - def _setup_rpc(self): - # RPC support - self.service_topics = {svc_constants.CORE: topics.PLUGIN} - self.conn = n_rpc.create_connection(new=True) - self.endpoints = [dhcp_rpc.DhcpRpcCallback(), - agents_db.AgentExtRpcCallback(), - metadata_rpc.MetadataRpcCallback()] - for svc_topic in self.service_topics.values(): - self.conn.create_consumer(svc_topic, self.endpoints, fanout=False) - self.dhcp_agent_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI() - # Consume from all consumers in threads - self.conn.consume_in_threads() - - def _setup_vsm(self): - """ - Setup Cisco Nexus 1000V related parameters and pull policy profiles. - - Retrieve all the policy profiles from the VSM when the plugin - is instantiated for the first time and then continue to poll for - policy profile updates. - """ - LOG.debug('_setup_vsm') - self.agent_vsm = True - # Poll VSM for create/delete of policy profile. - eventlet.spawn(self._poll_policy_profiles) - - def _poll_policy_profiles(self): - """Start a green thread to pull policy profiles from VSM.""" - while True: - self._populate_policy_profiles() - eventlet.sleep(c_conf.CISCO_N1K.poll_duration) - - def _populate_policy_profiles(self): - """ - Populate all the policy profiles from VSM. - - The tenant id is not available when the policy profiles are polled - from the VSM. Hence we associate the policy profiles with fake - tenant-ids. - """ - LOG.debug('_populate_policy_profiles') - try: - n1kvclient = n1kv_client.Client() - policy_profiles = n1kvclient.list_port_profiles() - vsm_profiles = {} - plugin_profiles_set = set() - # Fetch policy profiles from VSM - for profile_name in policy_profiles: - profile_id = (policy_profiles - [profile_name][c_const.PROPERTIES][c_const.ID]) - vsm_profiles[profile_id] = profile_name - # Fetch policy profiles previously populated - for profile in n1kv_db_v2.get_policy_profiles(): - plugin_profiles_set.add(profile.id) - vsm_profiles_set = set(vsm_profiles) - # Update database if the profile sets differ. - if vsm_profiles_set ^ plugin_profiles_set: - # Add profiles in database if new profiles were created in VSM - for pid in vsm_profiles_set - plugin_profiles_set: - self._add_policy_profile(vsm_profiles[pid], pid) - - # Delete profiles from database if profiles were deleted in VSM - for pid in plugin_profiles_set - vsm_profiles_set: - self._delete_policy_profile(pid) - self._remove_all_fake_policy_profiles() - except (cisco_exceptions.VSMError, - cisco_exceptions.VSMConnectionFailed): - LOG.warning(_LW('No policy profile populated from VSM')) - - def _extend_network_dict_provider(self, context, network): - """Add extended network parameters.""" - binding = n1kv_db_v2.get_network_binding(context.session, - network['id']) - network[providernet.NETWORK_TYPE] = binding.network_type - if binding.network_type == c_const.NETWORK_TYPE_OVERLAY: - network[providernet.PHYSICAL_NETWORK] = None - network[providernet.SEGMENTATION_ID] = binding.segmentation_id - network[n1kv.MULTICAST_IP] = binding.multicast_ip - elif binding.network_type == c_const.NETWORK_TYPE_VLAN: - network[providernet.PHYSICAL_NETWORK] = binding.physical_network - network[providernet.SEGMENTATION_ID] = binding.segmentation_id - elif binding.network_type == c_const.NETWORK_TYPE_TRUNK: - network[providernet.PHYSICAL_NETWORK] = binding.physical_network - network[providernet.SEGMENTATION_ID] = None - network[n1kv.MULTICAST_IP] = None - elif binding.network_type == c_const.NETWORK_TYPE_MULTI_SEGMENT: - network[providernet.PHYSICAL_NETWORK] = None - network[providernet.SEGMENTATION_ID] = None - network[n1kv.MULTICAST_IP] = None - - def _process_provider_create(self, context, attrs): - network_type = attrs.get(providernet.NETWORK_TYPE) - physical_network = attrs.get(providernet.PHYSICAL_NETWORK) - segmentation_id = attrs.get(providernet.SEGMENTATION_ID) - - network_type_set = attributes.is_attr_set(network_type) - physical_network_set = attributes.is_attr_set(physical_network) - segmentation_id_set = attributes.is_attr_set(segmentation_id) - - if not (network_type_set or physical_network_set or - segmentation_id_set): - return (None, None, None) - - if not network_type_set: - msg = _("provider:network_type required") - raise n_exc.InvalidInput(error_message=msg) - elif network_type == c_const.NETWORK_TYPE_VLAN: - if not segmentation_id_set: - msg = _("provider:segmentation_id required") - raise n_exc.InvalidInput(error_message=msg) - if segmentation_id < 1 or segmentation_id > 4094: - msg = _("provider:segmentation_id out of range " - "(1 through 4094)") - raise n_exc.InvalidInput(error_message=msg) - elif network_type == c_const.NETWORK_TYPE_OVERLAY: - if physical_network_set: - msg = _("provider:physical_network specified for Overlay " - "network") - raise n_exc.InvalidInput(error_message=msg) - else: - physical_network = None - if not segmentation_id_set: - msg = _("provider:segmentation_id required") - raise n_exc.InvalidInput(error_message=msg) - if segmentation_id < 5000: - msg = _("provider:segmentation_id out of range " - "(5000+)") - raise n_exc.InvalidInput(error_message=msg) - else: - msg = _("provider:network_type %s not supported"), network_type - raise n_exc.InvalidInput(error_message=msg) - - if network_type == c_const.NETWORK_TYPE_VLAN: - if physical_network_set: - network_profiles = n1kv_db_v2.get_network_profiles() - for network_profile in network_profiles: - if physical_network == network_profile[ - 'physical_network']: - break - else: - msg = (_("Unknown provider:physical_network %s"), - physical_network) - raise n_exc.InvalidInput(error_message=msg) - else: - msg = _("provider:physical_network required") - raise n_exc.InvalidInput(error_message=msg) - - return (network_type, physical_network, segmentation_id) - - def _check_provider_update(self, context, attrs): - """Handle Provider network updates.""" - network_type = attrs.get(providernet.NETWORK_TYPE) - physical_network = attrs.get(providernet.PHYSICAL_NETWORK) - segmentation_id = attrs.get(providernet.SEGMENTATION_ID) - - network_type_set = attributes.is_attr_set(network_type) - physical_network_set = attributes.is_attr_set(physical_network) - segmentation_id_set = attributes.is_attr_set(segmentation_id) - - if not (network_type_set or physical_network_set or - segmentation_id_set): - return - - # TBD : Need to handle provider network updates - msg = _("Plugin does not support updating provider attributes") - raise n_exc.InvalidInput(error_message=msg) - - def _get_cluster(self, segment1, segment2, clusters): - """ - Returns a cluster to apply the segment mapping - - :param segment1: UUID of segment to be mapped - :param segment2: UUID of segment to be mapped - :param clusters: List of clusters - """ - for cluster in sorted(clusters, key=lambda k: k['size']): - for mapping in cluster[c_const.MAPPINGS]: - for segment in mapping[c_const.SEGMENTS]: - if segment1 in segment or segment2 in segment: - break - else: - cluster['size'] += 2 - return cluster['encapProfileName'] - break - return - - def _extend_mapping_dict(self, context, mapping_dict, segment): - """ - Extend a mapping dictionary with dot1q tag and bridge-domain name. - - :param context: neutron api request context - :param mapping_dict: dictionary to populate values - :param segment: id of the segment being populated - """ - net = self.get_network(context, segment) - if net[providernet.NETWORK_TYPE] == c_const.NETWORK_TYPE_VLAN: - mapping_dict['dot1q'] = str(net[providernet.SEGMENTATION_ID]) - else: - mapping_dict['bridgeDomain'] = (net['name'] + - c_const.BRIDGE_DOMAIN_SUFFIX) - - def _send_add_multi_segment_request(self, context, net_id, segment_pairs): - """ - Send Add multi-segment network request to VSM. - - :param context: neutron api request context - :param net_id: UUID of the multi-segment network - :param segment_pairs: List of segments in UUID pairs - that need to be bridged - """ - - if not segment_pairs: - return - - session = context.session - n1kvclient = n1kv_client.Client() - clusters = n1kvclient.get_clusters() - online_clusters = [] - encap_dict = {} - for cluster in clusters['body'][c_const.SET]: - cluster = cluster[c_const.PROPERTIES] - if cluster[c_const.STATE] == c_const.ONLINE: - cluster['size'] = 0 - for mapping in cluster[c_const.MAPPINGS]: - cluster['size'] += ( - len(mapping[c_const.SEGMENTS])) - online_clusters.append(cluster) - for (segment1, segment2) in segment_pairs: - encap_profile = self._get_cluster(segment1, segment2, - online_clusters) - if encap_profile is not None: - if encap_profile in encap_dict: - profile_dict = encap_dict[encap_profile] - else: - profile_dict = {'name': encap_profile, - 'addMappings': [], - 'delMappings': []} - encap_dict[encap_profile] = profile_dict - mapping_dict = {} - self._extend_mapping_dict(context, - mapping_dict, segment1) - self._extend_mapping_dict(context, - mapping_dict, segment2) - profile_dict['addMappings'].append(mapping_dict) - n1kv_db_v2.add_multi_segment_encap_profile_name(session, - net_id, - (segment1, - segment2), - encap_profile) - else: - raise cisco_exceptions.NoClusterFound() - - for profile in encap_dict: - n1kvclient.update_encapsulation_profile(context, profile, - encap_dict[profile]) - - def _send_del_multi_segment_request(self, context, net_id, segment_pairs): - """ - Send Delete multi-segment network request to VSM. - - :param context: neutron api request context - :param net_id: UUID of the multi-segment network - :param segment_pairs: List of segments in UUID pairs - whose bridging needs to be removed - """ - if not segment_pairs: - return - session = context.session - encap_dict = {} - n1kvclient = n1kv_client.Client() - for (segment1, segment2) in segment_pairs: - binding = ( - n1kv_db_v2.get_multi_segment_network_binding(session, net_id, - (segment1, - segment2))) - encap_profile = binding['encap_profile_name'] - if encap_profile in encap_dict: - profile_dict = encap_dict[encap_profile] - else: - profile_dict = {'name': encap_profile, - 'addMappings': [], - 'delMappings': []} - encap_dict[encap_profile] = profile_dict - mapping_dict = {} - self._extend_mapping_dict(context, - mapping_dict, segment1) - self._extend_mapping_dict(context, - mapping_dict, segment2) - profile_dict['delMappings'].append(mapping_dict) - - for profile in encap_dict: - n1kvclient.update_encapsulation_profile(context, profile, - encap_dict[profile]) - - def _get_encap_segments(self, context, segment_pairs): - """ - Get the list of segments in encapsulation profile format. - - :param context: neutron api request context - :param segment_pairs: List of segments that need to be bridged - """ - member_list = [] - for pair in segment_pairs: - (segment, dot1qtag) = pair - member_dict = {} - net = self.get_network(context, segment) - member_dict['bridgeDomain'] = (net['name'] + - c_const.BRIDGE_DOMAIN_SUFFIX) - member_dict['dot1q'] = dot1qtag - member_list.append(member_dict) - return member_list - - def _populate_member_segments(self, context, network, segment_pairs, oper): - """ - Populate trunk network dict with member segments. - - :param context: neutron api request context - :param network: Dictionary containing the trunk network information - :param segment_pairs: List of segments in UUID pairs - that needs to be trunked - :param oper: Operation to be performed - """ - LOG.debug('_populate_member_segments %s', segment_pairs) - trunk_list = [] - for (segment, dot1qtag) in segment_pairs: - net = self.get_network(context, segment) - member_dict = {'segment': net['name'], - 'dot1qtag': dot1qtag} - trunk_list.append(member_dict) - if oper == n1kv.SEGMENT_ADD: - network['add_segment_list'] = trunk_list - elif oper == n1kv.SEGMENT_DEL: - network['del_segment_list'] = trunk_list - - def _parse_multi_segments(self, context, attrs, param): - """ - Parse the multi-segment network attributes. - - :param context: neutron api request context - :param attrs: Attributes of the network - :param param: Additional parameter indicating an add - or del operation - :returns: List of segment UUIDs in set pairs - """ - pair_list = [] - valid_seg_types = [c_const.NETWORK_TYPE_VLAN, - c_const.NETWORK_TYPE_OVERLAY] - segments = attrs.get(param) - if not attributes.is_attr_set(segments): - return pair_list - for pair in segments.split(','): - segment1, sep, segment2 = pair.partition(':') - if (uuidutils.is_uuid_like(segment1) and - uuidutils.is_uuid_like(segment2)): - binding1 = n1kv_db_v2.get_network_binding(context.session, - segment1) - binding2 = n1kv_db_v2.get_network_binding(context.session, - segment2) - if (binding1.network_type not in valid_seg_types or - binding2.network_type not in valid_seg_types or - binding1.network_type == binding2.network_type): - msg = _("Invalid pairing supplied") - raise n_exc.InvalidInput(error_message=msg) - else: - pair_list.append((segment1, segment2)) - else: - LOG.debug('Invalid UUID supplied in %s', pair) - msg = _("Invalid UUID supplied") - raise n_exc.InvalidInput(error_message=msg) - return pair_list - - def _parse_trunk_segments(self, context, attrs, param, physical_network, - sub_type): - """ - Parse the trunk network attributes. - - :param context: neutron api request context - :param attrs: Attributes of the network - :param param: Additional parameter indicating an add - or del operation - :param physical_network: Physical network of the trunk segment - :param sub_type: Sub-type of the trunk segment - :returns: List of segment UUIDs and dot1qtag (for vxlan) in set pairs - """ - pair_list = [] - segments = attrs.get(param) - if not attributes.is_attr_set(segments): - return pair_list - for pair in segments.split(','): - segment, sep, dot1qtag = pair.partition(':') - if sub_type == c_const.NETWORK_TYPE_VLAN: - dot1qtag = '' - if uuidutils.is_uuid_like(segment): - binding = n1kv_db_v2.get_network_binding(context.session, - segment) - if binding.network_type == c_const.NETWORK_TYPE_TRUNK: - msg = _("Cannot add a trunk segment '%s' as a member of " - "another trunk segment") % segment - raise n_exc.InvalidInput(error_message=msg) - elif binding.network_type == c_const.NETWORK_TYPE_VLAN: - if sub_type == c_const.NETWORK_TYPE_OVERLAY: - msg = _("Cannot add vlan segment '%s' as a member of " - "a vxlan trunk segment") % segment - raise n_exc.InvalidInput(error_message=msg) - if not physical_network: - physical_network = binding.physical_network - elif physical_network != binding.physical_network: - msg = _("Network UUID '%s' belongs to a different " - "physical network") % segment - raise n_exc.InvalidInput(error_message=msg) - elif binding.network_type == c_const.NETWORK_TYPE_OVERLAY: - if sub_type == c_const.NETWORK_TYPE_VLAN: - msg = _("Cannot add vxlan segment '%s' as a member of " - "a vlan trunk segment") % segment - raise n_exc.InvalidInput(error_message=msg) - try: - if not utils.is_valid_vlan_tag(int(dot1qtag)): - msg = _("Vlan tag '%s' is out of range") % dot1qtag - raise n_exc.InvalidInput(error_message=msg) - except ValueError: - msg = _("Vlan tag '%s' is not an integer " - "value") % dot1qtag - raise n_exc.InvalidInput(error_message=msg) - pair_list.append((segment, dot1qtag)) - else: - LOG.debug('%s is not a valid uuid', segment) - msg = _("'%s' is not a valid UUID") % segment - raise n_exc.InvalidInput(error_message=msg) - return pair_list - - def _extend_network_dict_member_segments(self, context, network): - """Add the extended parameter member segments to the network.""" - members = [] - binding = n1kv_db_v2.get_network_binding(context.session, - network['id']) - if binding.network_type == c_const.NETWORK_TYPE_TRUNK: - members = n1kv_db_v2.get_trunk_members(context.session, - network['id']) - elif binding.network_type == c_const.NETWORK_TYPE_MULTI_SEGMENT: - members = n1kv_db_v2.get_multi_segment_members(context.session, - network['id']) - network[n1kv.MEMBER_SEGMENTS] = members - - def _extend_network_dict_profile(self, context, network): - """Add the extended parameter network profile to the network.""" - binding = n1kv_db_v2.get_network_binding(context.session, - network['id']) - network[n1kv.PROFILE_ID] = binding.profile_id - - def _extend_port_dict_profile(self, context, port): - """Add the extended parameter port profile to the port.""" - binding = n1kv_db_v2.get_port_binding(context.session, - port['id']) - port[n1kv.PROFILE_ID] = binding.profile_id - - def _process_network_profile(self, context, network): - """Validate network profile exists.""" - profile_id = network.get(n1kv.PROFILE_ID) - profile_id_set = attributes.is_attr_set(profile_id) - if not profile_id_set: - profile_name = c_conf.CISCO_N1K.default_network_profile - net_p = self._get_network_profile_by_name(context.session, - profile_name) - profile_id = net_p['id'] - network['n1kv:profile_id'] = profile_id - return profile_id - - def _process_policy_profile(self, context, attrs): - """Validates whether policy profile exists.""" - profile_id = attrs.get(n1kv.PROFILE_ID) - profile_id_set = attributes.is_attr_set(profile_id) - if not profile_id_set: - msg = _("n1kv:profile_id does not exist") - raise n_exc.InvalidInput(error_message=msg) - if not self._policy_profile_exists(profile_id): - msg = _("n1kv:profile_id does not exist") - raise n_exc.InvalidInput(error_message=msg) - - return profile_id - - def _send_create_logical_network_request(self, network_profile, tenant_id): - """ - Send create logical network request to VSM. - - :param network_profile: network profile dictionary - :param tenant_id: UUID representing the tenant - """ - LOG.debug('_send_create_logical_network') - n1kvclient = n1kv_client.Client() - n1kvclient.create_logical_network(network_profile, tenant_id) - - def _send_delete_logical_network_request(self, network_profile): - """ - Send delete logical network request to VSM. - - :param network_profile: network profile dictionary - """ - LOG.debug('_send_delete_logical_network') - n1kvclient = n1kv_client.Client() - logical_network_name = (network_profile['id'] + - c_const.LOGICAL_NETWORK_SUFFIX) - n1kvclient.delete_logical_network(logical_network_name) - - def _send_create_network_profile_request(self, context, profile): - """ - Send create network profile request to VSM. - - :param context: neutron api request context - :param profile: network profile dictionary - """ - LOG.debug('_send_create_network_profile_request: %s', profile['id']) - n1kvclient = n1kv_client.Client() - n1kvclient.create_network_segment_pool(profile, context.tenant_id) - - def _send_update_network_profile_request(self, profile): - """ - Send update network profile request to VSM. - - :param profile: network profile dictionary - """ - LOG.debug('_send_update_network_profile_request: %s', profile['id']) - n1kvclient = n1kv_client.Client() - n1kvclient.update_network_segment_pool(profile) - - def _send_delete_network_profile_request(self, profile): - """ - Send delete network profile request to VSM. - - :param profile: network profile dictionary - """ - LOG.debug('_send_delete_network_profile_request: %s', - profile['name']) - n1kvclient = n1kv_client.Client() - n1kvclient.delete_network_segment_pool(profile['id']) - - def _send_create_network_request(self, context, network, segment_pairs): - """ - Send create network request to VSM. - - Create a bridge domain for network of type Overlay. - :param context: neutron api request context - :param network: network dictionary - :param segment_pairs: List of segments in UUID pairs - that need to be bridged - """ - LOG.debug('_send_create_network_request: %s', network['id']) - profile = self.get_network_profile(context, - network[n1kv.PROFILE_ID]) - n1kvclient = n1kv_client.Client() - if network[providernet.NETWORK_TYPE] == c_const.NETWORK_TYPE_OVERLAY: - n1kvclient.create_bridge_domain(network, profile['sub_type']) - if network[providernet.NETWORK_TYPE] == c_const.NETWORK_TYPE_TRUNK: - self._populate_member_segments(context, network, segment_pairs, - n1kv.SEGMENT_ADD) - network['del_segment_list'] = [] - if profile['sub_type'] == c_const.NETWORK_TYPE_OVERLAY: - encap_dict = {'name': (network['name'] + - c_const.ENCAPSULATION_PROFILE_SUFFIX), - 'add_segment_list': ( - self._get_encap_segments(context, - segment_pairs)), - 'del_segment_list': []} - n1kvclient.create_encapsulation_profile(encap_dict) - n1kvclient.create_network_segment(network, profile) - - def _send_update_network_request(self, context, network, add_segments, - del_segments): - """ - Send update network request to VSM. - - :param context: neutron api request context - :param network: network dictionary - :param add_segments: List of segments bindings - that need to be deleted - :param del_segments: List of segments bindings - that need to be deleted - """ - LOG.debug('_send_update_network_request: %s', network['id']) - db_session = context.session - profile = n1kv_db_v2.get_network_profile( - db_session, network[n1kv.PROFILE_ID], context.tenant_id) - n1kvclient = n1kv_client.Client() - body = {'description': network['name'], - 'id': network['id'], - 'networkSegmentPool': profile['id'], - 'vlan': network[providernet.SEGMENTATION_ID], - 'mode': 'access', - 'segmentType': profile['segment_type'], - 'addSegments': [], - 'delSegments': []} - if network[providernet.NETWORK_TYPE] == c_const.NETWORK_TYPE_TRUNK: - self._populate_member_segments(context, network, add_segments, - n1kv.SEGMENT_ADD) - self._populate_member_segments(context, network, del_segments, - n1kv.SEGMENT_DEL) - body['mode'] = c_const.NETWORK_TYPE_TRUNK - body['segmentType'] = profile['sub_type'] - body['addSegments'] = network['add_segment_list'] - body['delSegments'] = network['del_segment_list'] - LOG.debug('add_segments=%s', body['addSegments']) - LOG.debug('del_segments=%s', body['delSegments']) - if profile['sub_type'] == c_const.NETWORK_TYPE_OVERLAY: - encap_profile = (network['id'] + - c_const.ENCAPSULATION_PROFILE_SUFFIX) - encap_dict = {'name': encap_profile, - 'addMappings': ( - self._get_encap_segments(context, - add_segments)), - 'delMappings': ( - self._get_encap_segments(context, - del_segments))} - n1kvclient.update_encapsulation_profile(context, encap_profile, - encap_dict) - n1kvclient.update_network_segment(network['id'], body) - - def _send_delete_network_request(self, context, network): - """ - Send delete network request to VSM. - - Delete bridge domain if network is of type Overlay. - Delete encapsulation profile if network is of type OVERLAY Trunk. - :param context: neutron api request context - :param network: network dictionary - """ - LOG.debug('_send_delete_network_request: %s', network['id']) - n1kvclient = n1kv_client.Client() - session = context.session - if network[providernet.NETWORK_TYPE] == c_const.NETWORK_TYPE_OVERLAY: - name = network['id'] + c_const.BRIDGE_DOMAIN_SUFFIX - n1kvclient.delete_bridge_domain(name) - elif network[providernet.NETWORK_TYPE] == c_const.NETWORK_TYPE_TRUNK: - profile = self.get_network_profile( - context, network[n1kv.PROFILE_ID]) - if profile['sub_type'] == c_const.NETWORK_TYPE_OVERLAY: - profile_name = (network['id'] + - c_const.ENCAPSULATION_PROFILE_SUFFIX) - n1kvclient.delete_encapsulation_profile(profile_name) - elif (network[providernet.NETWORK_TYPE] == - c_const.NETWORK_TYPE_MULTI_SEGMENT): - encap_dict = n1kv_db_v2.get_multi_segment_encap_dict(session, - network['id']) - for profile in encap_dict: - profile_dict = {'name': profile, - 'addSegments': [], - 'delSegments': []} - for segment_pair in encap_dict[profile]: - mapping_dict = {} - (segment1, segment2) = segment_pair - self._extend_mapping_dict(context, - mapping_dict, segment1) - self._extend_mapping_dict(context, - mapping_dict, segment2) - profile_dict['delSegments'].append(mapping_dict) - n1kvclient.update_encapsulation_profile(context, profile, - profile_dict) - n1kvclient.delete_network_segment(network['id']) - - def _send_create_subnet_request(self, context, subnet): - """ - Send create subnet request to VSM. - - :param context: neutron api request context - :param subnet: subnet dictionary - """ - LOG.debug('_send_create_subnet_request: %s', subnet['id']) - n1kvclient = n1kv_client.Client() - n1kvclient.create_ip_pool(subnet) - - def _send_update_subnet_request(self, subnet): - """ - Send update subnet request to VSM. - - :param subnet: subnet dictionary - """ - LOG.debug('_send_update_subnet_request: %s', subnet['name']) - n1kvclient = n1kv_client.Client() - n1kvclient.update_ip_pool(subnet) - - def _send_delete_subnet_request(self, context, subnet): - """ - Send delete subnet request to VSM. - - :param context: neutron api request context - :param subnet: subnet dictionary - """ - LOG.debug('_send_delete_subnet_request: %s', subnet['name']) - body = {'ipPool': subnet['id'], 'deleteSubnet': True} - n1kvclient = n1kv_client.Client() - n1kvclient.update_network_segment(subnet['network_id'], body=body) - n1kvclient.delete_ip_pool(subnet['id']) - - def _send_create_port_request(self, - context, - port, - port_count, - policy_profile, - vm_network_name): - """ - Send create port request to VSM. - - Create a VM network for a network and policy profile combination. - If the VM network already exists, bind this port to the existing - VM network on the VSM. - :param context: neutron api request context - :param port: port dictionary - :param port_count: integer representing the number of ports in one - VM Network - :param policy_profile: object of type policy profile - :param vm_network_name: string representing the name of the VM - network - """ - LOG.debug('_send_create_port_request: %s', port) - n1kvclient = n1kv_client.Client() - if port_count == 1: - n1kvclient.create_vm_network(port, - vm_network_name, - policy_profile) - else: - n1kvclient.create_n1kv_port(port, vm_network_name) - - def _send_update_port_request(self, port_id, mac_address, vm_network_name): - """ - Send update port request to VSM. - - :param port_id: UUID representing port to update - :param mac_address: string representing the mac address - :param vm_network_name: VM network name to which the port is bound - """ - LOG.debug('_send_update_port_request: %s', port_id) - body = {'portId': port_id, - 'macAddress': mac_address} - n1kvclient = n1kv_client.Client() - n1kvclient.update_n1kv_port(vm_network_name, port_id, body) - - def _send_delete_port_request(self, context, port, vm_network): - """ - Send delete port request to VSM. - - Delete the port on the VSM. - :param context: neutron api request context - :param port: port object which is to be deleted - :param vm_network: VM network object with which the port is associated - """ - LOG.debug('_send_delete_port_request: %s', port['id']) - n1kvclient = n1kv_client.Client() - n1kvclient.delete_n1kv_port(vm_network['name'], port['id']) - - def _get_segmentation_id(self, context, id): - """ - Retrieve segmentation ID for a given network. - - :param context: neutron api request context - :param id: UUID of the network - :returns: segmentation ID for the network - """ - session = context.session - binding = n1kv_db_v2.get_network_binding(session, id) - return binding.segmentation_id - - def create_network(self, context, network): - """ - Create network based on network profile. - - :param context: neutron api request context - :param network: network dictionary - :returns: network object - """ - (network_type, physical_network, - segmentation_id) = self._process_provider_create(context, - network['network']) - profile_id = self._process_network_profile(context, network['network']) - segment_pairs = None - LOG.debug('Create network: profile_id=%s', profile_id) - session = context.session - with session.begin(subtransactions=True): - if not network_type: - # tenant network - (physical_network, network_type, segmentation_id, - multicast_ip) = n1kv_db_v2.alloc_network(session, - profile_id, - context.tenant_id) - LOG.debug('Physical_network %(phy_net)s, ' - 'seg_type %(net_type)s, ' - 'seg_id %(seg_id)s, ' - 'multicast_ip %(multicast_ip)s', - {'phy_net': physical_network, - 'net_type': network_type, - 'seg_id': segmentation_id, - 'multicast_ip': multicast_ip}) - if network_type == c_const.NETWORK_TYPE_MULTI_SEGMENT: - segment_pairs = ( - self._parse_multi_segments(context, network['network'], - n1kv.SEGMENT_ADD)) - LOG.debug('Seg list %s ', segment_pairs) - elif network_type == c_const.NETWORK_TYPE_TRUNK: - network_profile = self.get_network_profile(context, - profile_id) - segment_pairs = ( - self._parse_trunk_segments(context, network['network'], - n1kv.SEGMENT_ADD, - physical_network, - network_profile['sub_type'] - )) - LOG.debug('Seg list %s ', segment_pairs) - else: - if not segmentation_id: - raise n_exc.TenantNetworksDisabled() - else: - # provider network - if network_type == c_const.NETWORK_TYPE_VLAN: - network_profile = self.get_network_profile(context, - profile_id) - seg_min, seg_max = self._get_segment_range( - network_profile['segment_range']) - if not seg_min <= segmentation_id <= seg_max: - raise cisco_exceptions.VlanIDOutsidePool() - n1kv_db_v2.reserve_specific_vlan(session, - physical_network, - segmentation_id) - multicast_ip = "0.0.0.0" - net = super(N1kvNeutronPluginV2, self).create_network(context, - network) - n1kv_db_v2.add_network_binding(session, - net['id'], - network_type, - physical_network, - segmentation_id, - multicast_ip, - profile_id, - segment_pairs) - self._process_l3_create(context, net, network['network']) - self._extend_network_dict_provider(context, net) - self._extend_network_dict_profile(context, net) - try: - if network_type == c_const.NETWORK_TYPE_MULTI_SEGMENT: - self._send_add_multi_segment_request(context, net['id'], - segment_pairs) - else: - self._send_create_network_request(context, net, segment_pairs) - except(cisco_exceptions.VSMError, - cisco_exceptions.VSMConnectionFailed): - with excutils.save_and_reraise_exception(): - self._delete_network_db(context, net['id']) - else: - LOG.debug("Created network: %s", net['id']) - return net - - def update_network(self, context, id, network): - """ - Update network parameters. - - :param context: neutron api request context - :param id: UUID representing the network to update - :returns: updated network object - """ - self._check_provider_update(context, network['network']) - add_segments = [] - del_segments = [] - - session = context.session - with session.begin(subtransactions=True): - net = super(N1kvNeutronPluginV2, self).update_network(context, id, - network) - self._process_l3_update(context, net, network['network']) - binding = n1kv_db_v2.get_network_binding(session, id) - if binding.network_type == c_const.NETWORK_TYPE_MULTI_SEGMENT: - add_segments = ( - self._parse_multi_segments(context, network['network'], - n1kv.SEGMENT_ADD)) - n1kv_db_v2.add_multi_segment_binding(session, - net['id'], add_segments) - del_segments = ( - self._parse_multi_segments(context, network['network'], - n1kv.SEGMENT_DEL)) - self._send_add_multi_segment_request(context, net['id'], - add_segments) - self._send_del_multi_segment_request(context, net['id'], - del_segments) - n1kv_db_v2.del_multi_segment_binding(session, - net['id'], del_segments) - elif binding.network_type == c_const.NETWORK_TYPE_TRUNK: - network_profile = self.get_network_profile(context, - binding.profile_id) - add_segments = ( - self._parse_trunk_segments(context, network['network'], - n1kv.SEGMENT_ADD, - binding.physical_network, - network_profile['sub_type'])) - n1kv_db_v2.add_trunk_segment_binding(session, - net['id'], add_segments) - del_segments = ( - self._parse_trunk_segments(context, network['network'], - n1kv.SEGMENT_DEL, - binding.physical_network, - network_profile['sub_type'])) - n1kv_db_v2.del_trunk_segment_binding(session, - net['id'], del_segments) - self._extend_network_dict_provider(context, net) - self._extend_network_dict_profile(context, net) - if binding.network_type != c_const.NETWORK_TYPE_MULTI_SEGMENT: - self._send_update_network_request(context, net, add_segments, - del_segments) - LOG.debug("Updated network: %s", net['id']) - return net - - def delete_network(self, context, id): - """ - Delete a network. - - :param context: neutron api request context - :param id: UUID representing the network to delete - """ - session = context.session - with session.begin(subtransactions=True): - network = self.get_network(context, id) - if network['subnets']: - msg = _("Cannot delete network '%s', " - "delete the associated subnet first") % network['name'] - raise n_exc.InvalidInput(error_message=msg) - if n1kv_db_v2.is_trunk_member(session, id): - msg = _("Cannot delete network '%s' " - "that is member of a trunk segment") % network['name'] - raise n_exc.InvalidInput(error_message=msg) - if n1kv_db_v2.is_multi_segment_member(session, id): - msg = _("Cannot delete network '%s' that is a member of a " - "multi-segment network") % network['name'] - raise n_exc.InvalidInput(error_message=msg) - self._delete_network_db(context, id) - # the network_binding record is deleted via cascade from - # the network record, so explicit removal is not necessary - self._send_delete_network_request(context, network) - LOG.debug("Deleted network: %s", id) - - def _delete_network_db(self, context, id): - session = context.session - with session.begin(subtransactions=True): - binding = n1kv_db_v2.get_network_binding(session, id) - if binding.network_type == c_const.NETWORK_TYPE_OVERLAY: - n1kv_db_v2.release_vxlan(session, binding.segmentation_id) - elif binding.network_type == c_const.NETWORK_TYPE_VLAN: - n1kv_db_v2.release_vlan(session, binding.physical_network, - binding.segmentation_id) - super(N1kvNeutronPluginV2, self).delete_network(context, id) - - def get_network(self, context, id, fields=None): - """ - Retrieve a Network. - - :param context: neutron api request context - :param id: UUID representing the network to fetch - :returns: requested network dictionary - """ - LOG.debug("Get network: %s", id) - net = super(N1kvNeutronPluginV2, self).get_network(context, id, None) - self._extend_network_dict_provider(context, net) - self._extend_network_dict_profile(context, net) - self._extend_network_dict_member_segments(context, net) - return self._fields(net, fields) - - def get_networks(self, context, filters=None, fields=None): - """ - Retrieve a list of networks. - - :param context: neutron api request context - :param filters: a dictionary with keys that are valid keys for a - network object. Values in this dictiontary are an - iterable containing values that will be used for an - exact match comparison for that value. Each result - returned by this function will have matched one of the - values for each key in filters - :params fields: a list of strings that are valid keys in a network - dictionary. Only these fields will be returned. - :returns: list of network dictionaries. - """ - LOG.debug("Get networks") - nets = super(N1kvNeutronPluginV2, self).get_networks(context, filters, - None) - for net in nets: - self._extend_network_dict_provider(context, net) - self._extend_network_dict_profile(context, net) - - return [self._fields(net, fields) for net in nets] - - def create_port(self, context, port): - """ - Create neutron port. - - Create a port. Use a default policy profile for ports created for dhcp - and router interface. Default policy profile name is configured in the - /etc/neutron/cisco_plugins.ini file. - - :param context: neutron api request context - :param port: port dictionary - :returns: port object - """ - p_profile = None - port_count = None - vm_network = None - vm_network_name = None - profile_id_set = False - - # Set the network policy profile id for auto generated L3/DHCP ports - if ('device_id' in port['port'] and port['port']['device_owner'] in - [constants.DEVICE_OWNER_DHCP, constants.DEVICE_OWNER_ROUTER_INTF, - constants.DEVICE_OWNER_ROUTER_GW, - constants.DEVICE_OWNER_FLOATINGIP]): - p_profile_name = c_conf.CISCO_N1K.network_node_policy_profile - p_profile = self._get_policy_profile_by_name(p_profile_name) - if p_profile: - port['port']['n1kv:profile_id'] = p_profile['id'] - - if n1kv.PROFILE_ID in port['port']: - profile_id = port['port'].get(n1kv.PROFILE_ID) - profile_id_set = attributes.is_attr_set(profile_id) - - # Set the default policy profile id for ports if no id is set - if not profile_id_set: - p_profile_name = c_conf.CISCO_N1K.default_policy_profile - p_profile = self._get_policy_profile_by_name(p_profile_name) - if p_profile: - port['port']['n1kv:profile_id'] = p_profile['id'] - profile_id_set = True - - profile_id = self._process_policy_profile(context, - port['port']) - LOG.debug('Create port: profile_id=%s', profile_id) - session = context.session - with session.begin(subtransactions=True): - pt = super(N1kvNeutronPluginV2, self).create_port(context, - port) - n1kv_db_v2.add_port_binding(session, pt['id'], profile_id) - self._extend_port_dict_profile(context, pt) - try: - vm_network = n1kv_db_v2.get_vm_network( - context.session, - profile_id, - pt['network_id']) - except cisco_exceptions.VMNetworkNotFound: - # Create a VM Network if no VM network exists. - vm_network_name = "%s%s_%s" % (c_const.VM_NETWORK_NAME_PREFIX, - profile_id, - pt['network_id']) - port_count = 1 - vm_network = n1kv_db_v2.add_vm_network(context.session, - vm_network_name, - profile_id, - pt['network_id'], - port_count) - else: - # Update port count of the VM network. - vm_network_name = vm_network['name'] - port_count = vm_network['port_count'] + 1 - n1kv_db_v2.update_vm_network_port_count(context.session, - vm_network_name, - port_count) - self._process_portbindings_create_and_update(context, - port['port'], - pt) - # Extract policy profile for VM network create in VSM. - if not p_profile: - p_profile = n1kv_db_v2.get_policy_profile(session, profile_id) - try: - self._send_create_port_request(context, - pt, - port_count, - p_profile, - vm_network_name) - except(cisco_exceptions.VSMError, - cisco_exceptions.VSMConnectionFailed): - with excutils.save_and_reraise_exception(): - self._delete_port_db(context, pt, vm_network) - else: - LOG.debug("Created port: %s", pt) - return pt - - def update_port(self, context, id, port): - """ - Update port parameters. - - :param context: neutron api request context - :param id: UUID representing the port to update - :returns: updated port object - """ - LOG.debug("Update port: %s", id) - with context.session.begin(subtransactions=True): - updated_port = super(N1kvNeutronPluginV2, - self).update_port(context, id, port) - self._process_portbindings_create_and_update(context, - port['port'], - updated_port) - self._extend_port_dict_profile(context, updated_port) - return updated_port - - @property - def l3plugin(self): - try: - return self._l3plugin - except AttributeError: - self._l3plugin = manager.NeutronManager.get_service_plugins().get( - svc_constants.L3_ROUTER_NAT) - return self._l3plugin - - def delete_port(self, context, id, l3_port_check=True): - """ - Delete a port. - - :param context: neutron api request context - :param id: UUID representing the port to delete - """ - # if needed, check to see if this is a port owned by - # and l3-router. If so, we should prevent deletion. - if self.l3plugin and l3_port_check: - self.l3plugin.prevent_l3_port_deletion(context, id) - with context.session.begin(subtransactions=True): - port = self.get_port(context, id) - vm_network = n1kv_db_v2.get_vm_network(context.session, - port[n1kv.PROFILE_ID], - port['network_id']) - if self.l3plugin: - self.l3plugin.disassociate_floatingips(context, id, - do_notify=False) - self._delete_port_db(context, port, vm_network) - - self._send_delete_port_request(context, port, vm_network) - - def _delete_port_db(self, context, port, vm_network): - with context.session.begin(subtransactions=True): - vm_network['port_count'] -= 1 - n1kv_db_v2.update_vm_network_port_count(context.session, - vm_network['name'], - vm_network['port_count']) - if vm_network['port_count'] == 0: - n1kv_db_v2.delete_vm_network(context.session, - port[n1kv.PROFILE_ID], - port['network_id']) - super(N1kvNeutronPluginV2, self).delete_port(context, port['id']) - - def get_port(self, context, id, fields=None): - """ - Retrieve a port. - :param context: neutron api request context - :param id: UUID representing the port to retrieve - :param fields: a list of strings that are valid keys in a port - dictionary. Only these fields will be returned. - :returns: port dictionary - """ - LOG.debug("Get port: %s", id) - port = super(N1kvNeutronPluginV2, self).get_port(context, id, None) - self._extend_port_dict_profile(context, port) - return self._fields(port, fields) - - def get_ports(self, context, filters=None, fields=None): - """ - Retrieve a list of ports. - - :param context: neutron api request context - :param filters: a dictionary with keys that are valid keys for a - port object. Values in this dictiontary are an - iterable containing values that will be used for an - exact match comparison for that value. Each result - returned by this function will have matched one of the - values for each key in filters - :params fields: a list of strings that are valid keys in a port - dictionary. Only these fields will be returned. - :returns: list of port dictionaries - """ - LOG.debug("Get ports") - ports = super(N1kvNeutronPluginV2, self).get_ports(context, filters, - None) - for port in ports: - self._extend_port_dict_profile(context, port) - - return [self._fields(port, fields) for port in ports] - - def create_subnet(self, context, subnet): - """ - Create subnet for a given network. - - :param context: neutron api request context - :param subnet: subnet dictionary - :returns: subnet object - """ - LOG.debug('Create subnet') - sub = super(N1kvNeutronPluginV2, self).create_subnet(context, subnet) - try: - self._send_create_subnet_request(context, sub) - except(cisco_exceptions.VSMError, - cisco_exceptions.VSMConnectionFailed): - with excutils.save_and_reraise_exception(): - super(N1kvNeutronPluginV2, - self).delete_subnet(context, sub['id']) - else: - LOG.debug("Created subnet: %s", sub['id']) - return sub - - def update_subnet(self, context, id, subnet): - """ - Update a subnet. - - :param context: neutron api request context - :param id: UUID representing subnet to update - :returns: updated subnet object - """ - LOG.debug('Update subnet') - sub = super(N1kvNeutronPluginV2, self).update_subnet(context, - id, - subnet) - self._send_update_subnet_request(sub) - return sub - - def delete_subnet(self, context, id): - """ - Delete a subnet. - - :param context: neutron api request context - :param id: UUID representing subnet to delete - :returns: deleted subnet object - """ - LOG.debug('Delete subnet: %s', id) - subnet = self.get_subnet(context, id) - self._send_delete_subnet_request(context, subnet) - return super(N1kvNeutronPluginV2, self).delete_subnet(context, id) - - def get_subnet(self, context, id, fields=None): - """ - Retrieve a subnet. - - :param context: neutron api request context - :param id: UUID representing subnet to retrieve - :params fields: a list of strings that are valid keys in a subnet - dictionary. Only these fields will be returned. - :returns: subnet object - """ - LOG.debug("Get subnet: %s", id) - subnet = super(N1kvNeutronPluginV2, self).get_subnet(context, id, - None) - return self._fields(subnet, fields) - - def get_subnets(self, context, filters=None, fields=None): - """ - Retrieve a list of subnets. - - :param context: neutron api request context - :param filters: a dictionary with keys that are valid keys for a - subnet object. Values in this dictiontary are an - iterable containing values that will be used for an - exact match comparison for that value. Each result - returned by this function will have matched one of the - values for each key in filters - :params fields: a list of strings that are valid keys in a subnet - dictionary. Only these fields will be returned. - :returns: list of dictionaries of subnets - """ - LOG.debug("Get subnets") - subnets = super(N1kvNeutronPluginV2, self).get_subnets(context, - filters, - None) - return [self._fields(subnet, fields) for subnet in subnets] - - def create_network_profile(self, context, network_profile): - """ - Create a network profile. - - Create a network profile, which represents a pool of networks - belonging to one type (VLAN or Overlay). On creation of network - profile, we retrieve the admin tenant-id which we use to replace - the previously stored fake tenant-id in tenant-profile bindings. - :param context: neutron api request context - :param network_profile: network profile dictionary - :returns: network profile object - """ - self._replace_fake_tenant_id_with_real(context) - with context.session.begin(subtransactions=True): - net_p = super(N1kvNeutronPluginV2, - self).create_network_profile(context, - network_profile) - try: - self._send_create_logical_network_request(net_p, - context.tenant_id) - except(cisco_exceptions.VSMError, - cisco_exceptions.VSMConnectionFailed): - with excutils.save_and_reraise_exception(): - super(N1kvNeutronPluginV2, - self).delete_network_profile(context, net_p['id']) - try: - self._send_create_network_profile_request(context, net_p) - except(cisco_exceptions.VSMError, - cisco_exceptions.VSMConnectionFailed): - with excutils.save_and_reraise_exception(): - super(N1kvNeutronPluginV2, - self).delete_network_profile(context, net_p['id']) - self._send_delete_logical_network_request(net_p) - return net_p - - def delete_network_profile(self, context, id): - """ - Delete a network profile. - - :param context: neutron api request context - :param id: UUID of the network profile to delete - :returns: deleted network profile object - """ - with context.session.begin(subtransactions=True): - net_p = super(N1kvNeutronPluginV2, - self).delete_network_profile(context, id) - self._send_delete_network_profile_request(net_p) - self._send_delete_logical_network_request(net_p) - - def update_network_profile(self, context, net_profile_id, network_profile): - """ - Update a network profile. - - :param context: neutron api request context - :param net_profile_id: UUID of the network profile to update - :param network_profile: dictionary containing network profile object - """ - session = context.session - with session.begin(subtransactions=True): - net_p = (super(N1kvNeutronPluginV2, self). - update_network_profile(context, - net_profile_id, - network_profile)) - self._send_update_network_profile_request(net_p) - return net_p diff --git a/neutron/plugins/cisco/network_plugin.py b/neutron/plugins/cisco/network_plugin.py deleted file mode 100644 index efeda9708..000000000 --- a/neutron/plugins/cisco/network_plugin.py +++ /dev/null @@ -1,171 +0,0 @@ -# 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. - -from oslo_log import log as logging -from oslo_utils import importutils -import webob.exc as wexc - -from neutron.api import extensions as neutron_extensions -from neutron.api.v2 import base -from neutron.db import db_base_plugin_v2 -from neutron.plugins.cisco.common import cisco_exceptions as cexc -from neutron.plugins.cisco.common import config -from neutron.plugins.cisco.db import network_db_v2 as cdb -from neutron.plugins.cisco import extensions - -LOG = logging.getLogger(__name__) - - -class PluginV2(db_base_plugin_v2.NeutronDbPluginV2): - """Meta-Plugin with v2 API support for multiple sub-plugins.""" - _supported_extension_aliases = ["credential", "Cisco qos"] - _methods_to_delegate = ['create_network', - 'delete_network', 'update_network', 'get_network', - 'get_networks', - 'create_port', 'delete_port', - 'update_port', 'get_port', 'get_ports', - 'create_subnet', - 'delete_subnet', 'update_subnet', - 'get_subnet', 'get_subnets', ] - - CISCO_FAULT_MAP = { - cexc.CredentialAlreadyExists: wexc.HTTPBadRequest, - cexc.CredentialNameNotFound: wexc.HTTPNotFound, - cexc.CredentialNotFound: wexc.HTTPNotFound, - cexc.NetworkSegmentIDNotFound: wexc.HTTPNotFound, - cexc.NetworkVlanBindingAlreadyExists: wexc.HTTPBadRequest, - cexc.NexusComputeHostNotConfigured: wexc.HTTPNotFound, - cexc.NexusConfigFailed: wexc.HTTPBadRequest, - cexc.NexusConnectFailed: wexc.HTTPServiceUnavailable, - cexc.NexusPortBindingNotFound: wexc.HTTPNotFound, - cexc.NoMoreNics: wexc.HTTPBadRequest, - cexc.PortIdForNexusSvi: wexc.HTTPBadRequest, - cexc.PortVnicBindingAlreadyExists: wexc.HTTPBadRequest, - cexc.PortVnicNotFound: wexc.HTTPNotFound, - cexc.QosNameAlreadyExists: wexc.HTTPBadRequest, - cexc.QosNotFound: wexc.HTTPNotFound, - cexc.SubnetNotSpecified: wexc.HTTPBadRequest, - cexc.VlanIDNotAvailable: wexc.HTTPNotFound, - cexc.VlanIDNotFound: wexc.HTTPNotFound, - } - - @property - def supported_extension_aliases(self): - if not hasattr(self, '_aliases'): - aliases = self._supported_extension_aliases[:] - if hasattr(self._model, "supported_extension_aliases"): - aliases.extend(self._model.supported_extension_aliases) - self._aliases = aliases - return self._aliases - - def __init__(self): - """Load the model class.""" - self._model_name = config.CISCO.model_class - self._model = importutils.import_object(self._model_name) - native_bulk_attr_name = ("_%s__native_bulk_support" - % self._model.__class__.__name__) - self.__native_bulk_support = getattr(self._model, - native_bulk_attr_name, False) - - neutron_extensions.append_api_extensions_path(extensions.__path__) - - # Extend the fault map - self._extend_fault_map() - - LOG.debug("Plugin initialization complete") - - def __getattribute__(self, name): - """Delegate core API calls to the model class. - - Core API calls are delegated directly to the configured model class. - Note: Bulking calls will be handled by this class, and turned into - non-bulking calls to be considered for delegation. - """ - methods = object.__getattribute__(self, "_methods_to_delegate") - if name in methods: - return getattr(object.__getattribute__(self, "_model"), - name) - else: - return object.__getattribute__(self, name) - - def __getattr__(self, name): - """Delegate calls to the extensions. - - This delegates the calls to the extensions explicitly implemented by - the model. - """ - if hasattr(self._model, name): - return getattr(self._model, name) - else: - # Must make sure we re-raise the error that led us here, since - # otherwise getattr() and even hasattr() doesn't work correctly. - raise AttributeError( - _("'%(model)s' object has no attribute '%(name)s'") % - {'model': self._model_name, 'name': name}) - - def _extend_fault_map(self): - """Extend the Neutron Fault Map for Cisco exceptions. - - Map exceptions which are specific to the Cisco Plugin - to standard HTTP exceptions. - - """ - base.FAULT_MAP.update(self.CISCO_FAULT_MAP) - - # - # Extension API implementation - # - def get_all_qoss(self, tenant_id): - """Get all QoS levels.""" - LOG.debug("get_all_qoss() called") - qoslist = cdb.get_all_qoss(tenant_id) - return qoslist - - def get_qos_details(self, tenant_id, qos_id): - """Get QoS Details.""" - LOG.debug("get_qos_details() called") - return cdb.get_qos(tenant_id, qos_id) - - def create_qos(self, tenant_id, qos_name, qos_desc): - """Create a QoS level.""" - LOG.debug("create_qos() called") - qos = cdb.add_qos(tenant_id, qos_name, str(qos_desc)) - return qos - - def delete_qos(self, tenant_id, qos_id): - """Delete a QoS level.""" - LOG.debug("delete_qos() called") - return cdb.remove_qos(tenant_id, qos_id) - - def rename_qos(self, tenant_id, qos_id, new_name): - """Rename QoS level.""" - LOG.debug("rename_qos() called") - return cdb.update_qos(tenant_id, qos_id, new_name) - - def get_all_credentials(self): - """Get all credentials.""" - LOG.debug("get_all_credentials() called") - credential_list = cdb.get_all_credentials() - return credential_list - - def get_credential_details(self, credential_id): - """Get a particular credential.""" - LOG.debug("get_credential_details() called") - return cdb.get_credential(credential_id) - - def rename_credential(self, credential_id, new_name, new_password): - """Rename the particular credential resource.""" - LOG.debug("rename_credential() called") - return cdb.update_credential(credential_id, new_name, - new_password=new_password) diff --git a/neutron/tests/unit/plugins/cisco/__init__.py b/neutron/tests/unit/plugins/cisco/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/plugins/cisco/n1kv/__init__.py b/neutron/tests/unit/plugins/cisco/n1kv/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/neutron/tests/unit/plugins/cisco/n1kv/fake_client.py b/neutron/tests/unit/plugins/cisco/n1kv/fake_client.py deleted file mode 100644 index 724e0f350..000000000 --- a/neutron/tests/unit/plugins/cisco/n1kv/fake_client.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright 2014 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. - -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.n1kv import n1kv_client - -_resource_metadata = {'port': ['id', 'macAddress', 'ipAddress', 'subnetId'], - 'vmnetwork': ['name', 'networkSegmentId', - 'networkSegment', 'portProfile', - 'portProfileId', 'tenantId', - 'portId', 'macAddress', - 'ipAddress', 'subnetId'], - 'subnet': ['addressRangeStart', 'addressRangeEnd', - 'ipAddressSubnet', 'description', 'gateway', - 'dhcp', 'dnsServersList', 'networkAddress', - 'netSegmentName', 'id', 'tenantId']} - - -class TestClient(n1kv_client.Client): - - def __init__(self, **kwargs): - self.broken = False - self.inject_params = False - self.total_profiles = 2 - super(TestClient, self).__init__() - - def _get_total_profiles(self): - return self.total_profiles - - def _do_request(self, method, action, body=None, headers=None): - if self.broken: - raise c_exc.VSMError(reason='VSM:Internal Server Error') - if self.inject_params and body: - body['invalidKey'] = 'catchMeIfYouCan' - if method == 'POST': - return _validate_resource(action, body) - elif method == 'GET': - if 'virtual-port-profile' in action: - return _policy_profile_generator( - self._get_total_profiles()) - else: - raise c_exc.VSMError(reason='VSM:Internal Server Error') - - -class TestClientInvalidRequest(TestClient): - - def __init__(self, **kwargs): - super(TestClientInvalidRequest, self).__init__() - self.inject_params = True - - -class TestClientInvalidResponse(TestClient): - - def __init__(self, **kwargs): - super(TestClientInvalidResponse, self).__init__() - self.broken = True - - -def _validate_resource(action, body=None): - if body: - body_set = set(body.keys()) - else: - return - if 'vm-network' in action and 'port' not in action: - vmnetwork_set = set(_resource_metadata['vmnetwork']) - if body_set - vmnetwork_set: - raise c_exc.VSMError(reason='Invalid Request') - elif 'port' in action: - port_set = set(_resource_metadata['port']) - if body_set - port_set: - raise c_exc.VSMError(reason='Invalid Request') - elif 'subnet' in action: - subnet_set = set(_resource_metadata['subnet']) - if body_set - subnet_set: - raise c_exc.VSMError(reason='Invalid Request') - else: - return - - -def _policy_profile_generator(total_profiles): - """ - Generate policy profile response and return a dictionary. - - :param total_profiles: integer representing total number of profiles to - return - """ - profiles = {} - for num in range(1, total_profiles + 1): - name = "pp-%s" % num - profile_id = "00000000-0000-0000-0000-00000000000%s" % num - profiles[name] = {"properties": {"name": name, "id": profile_id}} - return profiles - - -def _policy_profile_generator_xml(total_profiles): - """ - Generate policy profile response in XML format. - - :param total_profiles: integer representing total number of profiles to - return - """ - xml = [""" - """] - template = ( - '' - '' - '00000000-0000-0000-0000-00000000000%(num)s' - 'pp-%(num)s' - '' - '' - ) - xml.extend(template % {'num': n} for n in range(1, total_profiles + 1)) - xml.append("") - return ''.join(xml) diff --git a/neutron/tests/unit/plugins/cisco/n1kv/test_n1kv_db.py b/neutron/tests/unit/plugins/cisco/n1kv/test_n1kv_db.py deleted file mode 100644 index fbe322330..000000000 --- a/neutron/tests/unit/plugins/cisco/n1kv/test_n1kv_db.py +++ /dev/null @@ -1,881 +0,0 @@ -# Copyright 2013 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. - -from six import moves -from sqlalchemy.orm import exc as s_exc -from testtools import matchers - -from neutron.common import exceptions as n_exc -from neutron import context -from neutron.db import api as db -from neutron.db import common_db_mixin -from neutron.plugins.cisco.common import cisco_constants as c_const -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.db import n1kv_db_v2 -from neutron.plugins.cisco.db import n1kv_models_v2 -from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin -from neutron.tests.unit import testlib_api - - -PHYS_NET = 'physnet1' -PHYS_NET_2 = 'physnet2' -VLAN_MIN = 10 -VLAN_MAX = 19 -VXLAN_MIN = 5000 -VXLAN_MAX = 5009 -SEGMENT_RANGE = '200-220' -SEGMENT_RANGE_MIN_OVERLAP = '210-230' -SEGMENT_RANGE_MAX_OVERLAP = '190-209' -SEGMENT_RANGE_OVERLAP = '190-230' -TEST_NETWORK_ID = 'abcdefghijklmnopqrstuvwxyz' -TEST_NETWORK_ID2 = 'abcdefghijklmnopqrstuvwxy2' -TEST_NETWORK_ID3 = 'abcdefghijklmnopqrstuvwxy3' -TEST_NETWORK_PROFILE = {'name': 'test_profile', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'physnet1', - 'segment_range': '10-19'} -TEST_NETWORK_PROFILE_2 = {'name': 'test_profile_2', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'physnet1', - 'segment_range': SEGMENT_RANGE} -TEST_NETWORK_PROFILE_VXLAN = {'name': 'test_profile', - 'segment_type': c_const.NETWORK_TYPE_OVERLAY, - 'sub_type': c_const.NETWORK_SUBTYPE_NATIVE_VXLAN, - 'segment_range': '5000-5009', - 'multicast_ip_range': '239.0.0.70-239.0.0.80'} -TEST_POLICY_PROFILE = {'id': '4a417990-76fb-11e2-bcfd-0800200c9a66', - 'name': 'test_policy_profile'} -TEST_NETWORK_PROFILE_MULTI_SEGMENT = {'name': 'test_profile', - 'segment_type': - c_const.NETWORK_TYPE_MULTI_SEGMENT} -TEST_NETWORK_PROFILE_VLAN_TRUNK = {'name': 'test_profile', - 'segment_type': c_const.NETWORK_TYPE_TRUNK, - 'sub_type': c_const.NETWORK_TYPE_VLAN} -TEST_NETWORK_PROFILE_VXLAN_TRUNK = {'name': 'test_profile', - 'segment_type': c_const.NETWORK_TYPE_TRUNK, - 'sub_type': c_const.NETWORK_TYPE_OVERLAY} - - -def _create_test_network_profile_if_not_there(session, - profile=TEST_NETWORK_PROFILE): - try: - _profile = session.query(n1kv_models_v2.NetworkProfile).filter_by( - name=profile['name']).one() - except s_exc.NoResultFound: - _profile = n1kv_db_v2.create_network_profile(session, profile) - return _profile - - -def _create_test_policy_profile_if_not_there(session, - profile=TEST_POLICY_PROFILE): - try: - _profile = session.query(n1kv_models_v2.PolicyProfile).filter_by( - name=profile['name']).one() - except s_exc.NoResultFound: - _profile = n1kv_db_v2.create_policy_profile(profile) - return _profile - - -class VlanAllocationsTest(testlib_api.SqlTestCase): - - def setUp(self): - super(VlanAllocationsTest, self).setUp() - self.session = db.get_session() - self.net_p = _create_test_network_profile_if_not_there(self.session) - n1kv_db_v2.sync_vlan_allocations(self.session, self.net_p) - - def test_sync_vlan_allocations_outside_segment_range(self): - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET, - VLAN_MIN - 1) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET, - VLAN_MAX + 1) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET_2, - VLAN_MIN + 20) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET_2, - VLAN_MIN + 20) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET_2, - VLAN_MAX + 20) - - def test_sync_vlan_allocations_unallocated_vlans(self): - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - VLAN_MIN).allocated) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - VLAN_MIN + 1). - allocated) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - VLAN_MAX - 1). - allocated) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - VLAN_MAX).allocated) - - def test_vlan_pool(self): - vlan_ids = set() - for x in moves.range(VLAN_MIN, VLAN_MAX + 1): - (physical_network, seg_type, - vlan_id, m_ip) = n1kv_db_v2.reserve_vlan(self.session, self.net_p) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - self.assertRaises(n_exc.NoNetworkAvailable, - n1kv_db_v2.reserve_vlan, - self.session, - self.net_p) - - n1kv_db_v2.release_vlan(self.session, PHYS_NET, vlan_ids.pop()) - physical_network, seg_type, vlan_id, m_ip = (n1kv_db_v2.reserve_vlan( - self.session, self.net_p)) - self.assertEqual(physical_network, PHYS_NET) - self.assertThat(vlan_id, matchers.GreaterThan(VLAN_MIN - 1)) - self.assertThat(vlan_id, matchers.LessThan(VLAN_MAX + 1)) - vlan_ids.add(vlan_id) - - for vlan_id in vlan_ids: - n1kv_db_v2.release_vlan(self.session, PHYS_NET, vlan_id) - - def test_specific_vlan_inside_pool(self): - vlan_id = VLAN_MIN + 5 - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - vlan_id).allocated) - n1kv_db_v2.reserve_specific_vlan(self.session, PHYS_NET, vlan_id) - self.assertTrue(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - vlan_id).allocated) - - self.assertRaises(n_exc.VlanIdInUse, - n1kv_db_v2.reserve_specific_vlan, - self.session, - PHYS_NET, - vlan_id) - - n1kv_db_v2.release_vlan(self.session, PHYS_NET, vlan_id) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(self.session, - PHYS_NET, - vlan_id).allocated) - - def test_specific_vlan_outside_pool(self): - vlan_id = VLAN_MAX + 5 - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - self.session, - PHYS_NET, - vlan_id) - self.assertRaises(c_exc.VlanIDOutsidePool, - n1kv_db_v2.reserve_specific_vlan, - self.session, - PHYS_NET, - vlan_id) - - -class VxlanAllocationsTest(testlib_api.SqlTestCase, - n1kv_db_v2.NetworkProfile_db_mixin): - - def setUp(self): - super(VxlanAllocationsTest, self).setUp() - self.session = db.get_session() - self.net_p = _create_test_network_profile_if_not_there( - self.session, TEST_NETWORK_PROFILE_VXLAN) - n1kv_db_v2.sync_vxlan_allocations(self.session, self.net_p) - - def test_sync_vxlan_allocations_outside_segment_range(self): - self.assertRaises(c_exc.VxlanIDNotFound, - n1kv_db_v2.get_vxlan_allocation, - self.session, - VXLAN_MIN - 1) - self.assertRaises(c_exc.VxlanIDNotFound, - n1kv_db_v2.get_vxlan_allocation, - self.session, - VXLAN_MAX + 1) - - def test_sync_vxlan_allocations_unallocated_vxlans(self): - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - VXLAN_MIN).allocated) - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - VXLAN_MIN + 1). - allocated) - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - VXLAN_MAX - 1). - allocated) - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - VXLAN_MAX).allocated) - - def test_vxlan_pool(self): - vxlan_ids = set() - for x in moves.range(VXLAN_MIN, VXLAN_MAX + 1): - vxlan = n1kv_db_v2.reserve_vxlan(self.session, self.net_p) - vxlan_id = vxlan[2] - self.assertThat(vxlan_id, matchers.GreaterThan(VXLAN_MIN - 1)) - self.assertThat(vxlan_id, matchers.LessThan(VXLAN_MAX + 1)) - vxlan_ids.add(vxlan_id) - - self.assertRaises(n_exc.NoNetworkAvailable, - n1kv_db_v2.reserve_vxlan, - self.session, - self.net_p) - n1kv_db_v2.release_vxlan(self.session, vxlan_ids.pop()) - vxlan = n1kv_db_v2.reserve_vxlan(self.session, self.net_p) - vxlan_id = vxlan[2] - self.assertThat(vxlan_id, matchers.GreaterThan(VXLAN_MIN - 1)) - self.assertThat(vxlan_id, matchers.LessThan(VXLAN_MAX + 1)) - vxlan_ids.add(vxlan_id) - - for vxlan_id in vxlan_ids: - n1kv_db_v2.release_vxlan(self.session, vxlan_id) - n1kv_db_v2.delete_network_profile(self.session, self.net_p.id) - - def test_specific_vxlan_inside_pool(self): - vxlan_id = VXLAN_MIN + 5 - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - vxlan_id).allocated) - n1kv_db_v2.reserve_specific_vxlan(self.session, vxlan_id) - self.assertTrue(n1kv_db_v2.get_vxlan_allocation(self.session, - vxlan_id).allocated) - - self.assertRaises(c_exc.VxlanIDInUse, - n1kv_db_v2.reserve_specific_vxlan, - self.session, - vxlan_id) - - n1kv_db_v2.release_vxlan(self.session, vxlan_id) - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(self.session, - vxlan_id).allocated) - - def test_specific_vxlan_outside_pool(self): - vxlan_id = VXLAN_MAX + 5 - self.assertRaises(c_exc.VxlanIDNotFound, - n1kv_db_v2.get_vxlan_allocation, - self.session, - vxlan_id) - self.assertRaises(c_exc.VxlanIDOutsidePool, - n1kv_db_v2.reserve_specific_vxlan, - self.session, - vxlan_id) - - -class NetworkBindingsTest(test_plugin.NeutronDbPluginV2TestCase): - - def setUp(self): - super(NetworkBindingsTest, self).setUp() - self.session = db.get_session() - - def test_add_network_binding(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there(self.session) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, c_const.NETWORK_TYPE_VLAN, - PHYS_NET, 1234, '0.0.0.0', p.id, None) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, c_const.NETWORK_TYPE_VLAN) - self.assertEqual(binding.physical_network, PHYS_NET) - self.assertEqual(binding.segmentation_id, 1234) - - def test_create_multi_segment_network(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_MULTI_SEGMENT) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, - c_const.NETWORK_TYPE_MULTI_SEGMENT, - None, 0, '0.0.0.0', p.id, None) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, - c_const.NETWORK_TYPE_MULTI_SEGMENT) - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - - def test_add_multi_segment_binding(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_MULTI_SEGMENT) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, - c_const.NETWORK_TYPE_MULTI_SEGMENT, - None, 0, '0.0.0.0', p.id, - [(TEST_NETWORK_ID2, TEST_NETWORK_ID3)]) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, - c_const.NETWORK_TYPE_MULTI_SEGMENT) - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - ms_binding = (n1kv_db_v2.get_multi_segment_network_binding( - self.session, TEST_NETWORK_ID, - (TEST_NETWORK_ID2, TEST_NETWORK_ID3))) - self.assertIsNotNone(ms_binding) - self.assertEqual(ms_binding.multi_segment_id, TEST_NETWORK_ID) - self.assertEqual(ms_binding.segment1_id, TEST_NETWORK_ID2) - self.assertEqual(ms_binding.segment2_id, TEST_NETWORK_ID3) - ms_members = (n1kv_db_v2.get_multi_segment_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(ms_members, - [(TEST_NETWORK_ID2, TEST_NETWORK_ID3)]) - self.assertTrue(n1kv_db_v2.is_multi_segment_member( - self.session, TEST_NETWORK_ID2)) - self.assertTrue(n1kv_db_v2.is_multi_segment_member( - self.session, TEST_NETWORK_ID3)) - n1kv_db_v2.del_multi_segment_binding( - self.session, TEST_NETWORK_ID, - [(TEST_NETWORK_ID2, TEST_NETWORK_ID3)]) - ms_members = (n1kv_db_v2.get_multi_segment_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(ms_members, []) - - def test_create_vlan_trunk_network(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_VLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, c_const.NETWORK_TYPE_TRUNK, - None, 0, '0.0.0.0', p.id, None) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, c_const.NETWORK_TYPE_TRUNK) - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - - def test_create_vxlan_trunk_network(self): - with self.network() as network: - TEST_NETWORK_ID = network['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_VXLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, c_const.NETWORK_TYPE_TRUNK, - None, 0, '0.0.0.0', p.id, None) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, c_const.NETWORK_TYPE_TRUNK) - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - - def test_add_vlan_trunk_binding(self): - with self.network() as network1: - with self.network() as network2: - TEST_NETWORK_ID = network1['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - TEST_NETWORK_ID2 = network2['network']['id'] - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID2) - p_v = _create_test_network_profile_if_not_there(self.session) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID2, c_const.NETWORK_TYPE_VLAN, - PHYS_NET, 1234, '0.0.0.0', p_v.id, None) - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_VLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, c_const.NETWORK_TYPE_TRUNK, - None, 0, '0.0.0.0', p.id, [(TEST_NETWORK_ID2, 0)]) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, - c_const.NETWORK_TYPE_TRUNK) - self.assertEqual(binding.physical_network, PHYS_NET) - self.assertEqual(binding.segmentation_id, 0) - t_binding = (n1kv_db_v2.get_trunk_network_binding( - self.session, TEST_NETWORK_ID, - (TEST_NETWORK_ID2, 0))) - self.assertIsNotNone(t_binding) - self.assertEqual(t_binding.trunk_segment_id, TEST_NETWORK_ID) - self.assertEqual(t_binding.segment_id, TEST_NETWORK_ID2) - self.assertEqual(t_binding.dot1qtag, '0') - t_members = (n1kv_db_v2.get_trunk_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(t_members, - [(TEST_NETWORK_ID2, '0')]) - self.assertTrue(n1kv_db_v2.is_trunk_member( - self.session, TEST_NETWORK_ID2)) - n1kv_db_v2.del_trunk_segment_binding( - self.session, TEST_NETWORK_ID, - [(TEST_NETWORK_ID2, '0')]) - t_members = (n1kv_db_v2.get_multi_segment_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(t_members, []) - - def test_add_vxlan_trunk_binding(self): - with self.network() as network1: - with self.network() as network2: - TEST_NETWORK_ID = network1['network']['id'] - - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID) - TEST_NETWORK_ID2 = network2['network']['id'] - self.assertRaises(c_exc.NetworkBindingNotFound, - n1kv_db_v2.get_network_binding, - self.session, - TEST_NETWORK_ID2) - p_v = _create_test_network_profile_if_not_there( - self.session, TEST_NETWORK_PROFILE_VXLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID2, - c_const.NETWORK_TYPE_OVERLAY, - None, 5100, '224.10.10.10', p_v.id, None) - p = _create_test_network_profile_if_not_there( - self.session, - TEST_NETWORK_PROFILE_VXLAN_TRUNK) - n1kv_db_v2.add_network_binding( - self.session, TEST_NETWORK_ID, c_const.NETWORK_TYPE_TRUNK, - None, 0, '0.0.0.0', p.id, - [(TEST_NETWORK_ID2, 5)]) - binding = n1kv_db_v2.get_network_binding( - self.session, TEST_NETWORK_ID) - self.assertIsNotNone(binding) - self.assertEqual(binding.network_id, TEST_NETWORK_ID) - self.assertEqual(binding.network_type, - c_const.NETWORK_TYPE_TRUNK) - self.assertIsNone(binding.physical_network) - self.assertEqual(binding.segmentation_id, 0) - t_binding = (n1kv_db_v2.get_trunk_network_binding( - self.session, TEST_NETWORK_ID, - (TEST_NETWORK_ID2, '5'))) - self.assertIsNotNone(t_binding) - self.assertEqual(t_binding.trunk_segment_id, TEST_NETWORK_ID) - self.assertEqual(t_binding.segment_id, TEST_NETWORK_ID2) - self.assertEqual(t_binding.dot1qtag, '5') - t_members = (n1kv_db_v2.get_trunk_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(t_members, - [(TEST_NETWORK_ID2, '5')]) - self.assertTrue(n1kv_db_v2.is_trunk_member( - self.session, TEST_NETWORK_ID2)) - n1kv_db_v2.del_trunk_segment_binding( - self.session, TEST_NETWORK_ID, - [(TEST_NETWORK_ID2, '5')]) - t_members = (n1kv_db_v2.get_multi_segment_members( - self.session, TEST_NETWORK_ID)) - self.assertEqual(t_members, []) - - -class NetworkProfileTests(testlib_api.SqlTestCase, - n1kv_db_v2.NetworkProfile_db_mixin): - - def setUp(self): - super(NetworkProfileTests, self).setUp() - self.session = db.get_session() - - def test_create_network_profile(self): - _db_profile = n1kv_db_v2.create_network_profile(self.session, - TEST_NETWORK_PROFILE) - self.assertIsNotNone(_db_profile) - db_profile = (self.session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=TEST_NETWORK_PROFILE['name']).one()) - self.assertIsNotNone(db_profile) - self.assertEqual(_db_profile.id, db_profile.id) - self.assertEqual(_db_profile.name, db_profile.name) - self.assertEqual(_db_profile.segment_type, db_profile.segment_type) - self.assertEqual(_db_profile.segment_range, db_profile.segment_range) - self.assertEqual(_db_profile.multicast_ip_index, - db_profile.multicast_ip_index) - self.assertEqual(_db_profile.multicast_ip_range, - db_profile.multicast_ip_range) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_create_multi_segment_network_profile(self): - _db_profile = (n1kv_db_v2.create_network_profile( - self.session, TEST_NETWORK_PROFILE_MULTI_SEGMENT)) - self.assertIsNotNone(_db_profile) - db_profile = ( - self.session.query( - n1kv_models_v2.NetworkProfile).filter_by( - name=TEST_NETWORK_PROFILE_MULTI_SEGMENT['name']) - .one()) - self.assertIsNotNone(db_profile) - self.assertEqual(_db_profile.id, db_profile.id) - self.assertEqual(_db_profile.name, db_profile.name) - self.assertEqual(_db_profile.segment_type, db_profile.segment_type) - self.assertEqual(_db_profile.segment_range, db_profile.segment_range) - self.assertEqual(_db_profile.multicast_ip_index, - db_profile.multicast_ip_index) - self.assertEqual(_db_profile.multicast_ip_range, - db_profile.multicast_ip_range) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_create_vlan_trunk_network_profile(self): - _db_profile = (n1kv_db_v2.create_network_profile( - self.session, TEST_NETWORK_PROFILE_VLAN_TRUNK)) - self.assertIsNotNone(_db_profile) - db_profile = (self.session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=TEST_NETWORK_PROFILE_VLAN_TRUNK['name']). - one()) - self.assertIsNotNone(db_profile) - self.assertEqual(_db_profile.id, db_profile.id) - self.assertEqual(_db_profile.name, db_profile.name) - self.assertEqual(_db_profile.segment_type, db_profile.segment_type) - self.assertEqual(_db_profile.segment_range, db_profile.segment_range) - self.assertEqual(_db_profile.multicast_ip_index, - db_profile.multicast_ip_index) - self.assertEqual(_db_profile.multicast_ip_range, - db_profile.multicast_ip_range) - self.assertEqual(_db_profile.sub_type, db_profile.sub_type) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_create_vxlan_trunk_network_profile(self): - _db_profile = (n1kv_db_v2.create_network_profile( - self.session, TEST_NETWORK_PROFILE_VXLAN_TRUNK)) - self.assertIsNotNone(_db_profile) - db_profile = (self.session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=TEST_NETWORK_PROFILE_VXLAN_TRUNK['name']). - one()) - self.assertIsNotNone(db_profile) - self.assertEqual(_db_profile.id, db_profile.id) - self.assertEqual(_db_profile.name, db_profile.name) - self.assertEqual(_db_profile.segment_type, db_profile.segment_type) - self.assertEqual(_db_profile.segment_range, db_profile.segment_range) - self.assertEqual(_db_profile.multicast_ip_index, - db_profile.multicast_ip_index) - self.assertEqual(_db_profile.multicast_ip_range, - db_profile.multicast_ip_range) - self.assertEqual(_db_profile.sub_type, db_profile.sub_type) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_create_network_profile_overlap(self): - _db_profile = n1kv_db_v2.create_network_profile(self.session, - TEST_NETWORK_PROFILE_2) - ctx = context.get_admin_context() - TEST_NETWORK_PROFILE_2['name'] = 'net-profile-min-overlap' - TEST_NETWORK_PROFILE_2['segment_range'] = SEGMENT_RANGE_MIN_OVERLAP - test_net_profile = {'network_profile': TEST_NETWORK_PROFILE_2} - self.assertRaises(n_exc.InvalidInput, - self.create_network_profile, - ctx, - test_net_profile) - - TEST_NETWORK_PROFILE_2['name'] = 'net-profile-max-overlap' - TEST_NETWORK_PROFILE_2['segment_range'] = SEGMENT_RANGE_MAX_OVERLAP - test_net_profile = {'network_profile': TEST_NETWORK_PROFILE_2} - self.assertRaises(n_exc.InvalidInput, - self.create_network_profile, - ctx, - test_net_profile) - - TEST_NETWORK_PROFILE_2['name'] = 'net-profile-overlap' - TEST_NETWORK_PROFILE_2['segment_range'] = SEGMENT_RANGE_OVERLAP - test_net_profile = {'network_profile': TEST_NETWORK_PROFILE_2} - self.assertRaises(n_exc.InvalidInput, - self.create_network_profile, - ctx, - test_net_profile) - n1kv_db_v2.delete_network_profile(self.session, _db_profile.id) - - def test_delete_network_profile(self): - try: - profile = (self.session.query(n1kv_models_v2.NetworkProfile). - filter_by(name=TEST_NETWORK_PROFILE['name']).one()) - except s_exc.NoResultFound: - profile = n1kv_db_v2.create_network_profile(self.session, - TEST_NETWORK_PROFILE) - - n1kv_db_v2.delete_network_profile(self.session, profile.id) - try: - self.session.query(n1kv_models_v2.NetworkProfile).filter_by( - name=TEST_NETWORK_PROFILE['name']).one() - except s_exc.NoResultFound: - pass - else: - self.fail("Network Profile (%s) was not deleted" % - TEST_NETWORK_PROFILE['name']) - - def test_update_network_profile(self): - TEST_PROFILE_1 = {'name': 'test_profile_1'} - profile = _create_test_network_profile_if_not_there(self.session) - updated_profile = n1kv_db_v2.update_network_profile(self.session, - profile.id, - TEST_PROFILE_1) - self.assertEqual(updated_profile.name, TEST_PROFILE_1['name']) - n1kv_db_v2.delete_network_profile(self.session, profile.id) - - def test_get_network_profile(self): - profile = n1kv_db_v2.create_network_profile(self.session, - TEST_NETWORK_PROFILE) - got_profile = n1kv_db_v2.get_network_profile(self.session, profile.id) - self.assertEqual(profile.id, got_profile.id) - self.assertEqual(profile.name, got_profile.name) - n1kv_db_v2.delete_network_profile(self.session, profile.id) - - def test_get_network_profiles(self): - test_profiles = [{'name': 'test_profile1', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'phys1', - 'segment_range': '200-210'}, - {'name': 'test_profile2', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'phys1', - 'segment_range': '211-220'}, - {'name': 'test_profile3', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'phys1', - 'segment_range': '221-230'}, - {'name': 'test_profile4', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'phys1', - 'segment_range': '231-240'}, - {'name': 'test_profile5', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'phys1', - 'segment_range': '241-250'}, - {'name': 'test_profile6', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'phys1', - 'segment_range': '251-260'}, - {'name': 'test_profile7', - 'segment_type': c_const.NETWORK_TYPE_VLAN, - 'physical_network': 'phys1', - 'segment_range': '261-270'}] - [n1kv_db_v2.create_network_profile(self.session, p) - for p in test_profiles] - # TODO(abhraut): Fix this test to work with real tenant_td - profiles = n1kv_db_v2._get_network_profiles(db_session=self.session) - self.assertEqual(len(test_profiles), len(list(profiles))) - - -class PolicyProfileTests(testlib_api.SqlTestCase): - - def setUp(self): - super(PolicyProfileTests, self).setUp() - self.session = db.get_session() - - def test_create_policy_profile(self): - _db_profile = n1kv_db_v2.create_policy_profile(TEST_POLICY_PROFILE) - self.assertIsNotNone(_db_profile) - db_profile = (self.session.query(n1kv_models_v2.PolicyProfile). - filter_by(name=TEST_POLICY_PROFILE['name']).one)() - self.assertIsNotNone(db_profile) - self.assertTrue(_db_profile.id == db_profile.id) - self.assertTrue(_db_profile.name == db_profile.name) - - def test_delete_policy_profile(self): - profile = _create_test_policy_profile_if_not_there(self.session) - n1kv_db_v2.delete_policy_profile(profile.id) - try: - self.session.query(n1kv_models_v2.PolicyProfile).filter_by( - name=TEST_POLICY_PROFILE['name']).one() - except s_exc.NoResultFound: - pass - else: - self.fail("Policy Profile (%s) was not deleted" % - TEST_POLICY_PROFILE['name']) - - def test_update_policy_profile(self): - TEST_PROFILE_1 = {'name': 'test_profile_1'} - profile = _create_test_policy_profile_if_not_there(self.session) - updated_profile = n1kv_db_v2.update_policy_profile(self.session, - profile.id, - TEST_PROFILE_1) - self.assertEqual(updated_profile.name, TEST_PROFILE_1['name']) - - def test_get_policy_profile(self): - profile = _create_test_policy_profile_if_not_there(self.session) - got_profile = n1kv_db_v2.get_policy_profile(self.session, profile.id) - self.assertEqual(profile.id, got_profile.id) - self.assertEqual(profile.name, got_profile.name) - - -class ProfileBindingTests(testlib_api.SqlTestCase, - n1kv_db_v2.NetworkProfile_db_mixin, - common_db_mixin.CommonDbMixin): - - def setUp(self): - super(ProfileBindingTests, self).setUp() - self.session = db.get_session() - - def _create_test_binding_if_not_there(self, tenant_id, profile_id, - profile_type): - try: - _binding = (self.session.query(n1kv_models_v2.ProfileBinding). - filter_by(profile_type=profile_type, - tenant_id=tenant_id, - profile_id=profile_id).one()) - except s_exc.NoResultFound: - _binding = n1kv_db_v2.create_profile_binding(self.session, - tenant_id, - profile_id, - profile_type) - return _binding - - def test_create_profile_binding(self): - test_tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "dd7b9741-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "network" - n1kv_db_v2.create_profile_binding(self.session, - test_tenant_id, - test_profile_id, - test_profile_type) - try: - self.session.query(n1kv_models_v2.ProfileBinding).filter_by( - profile_type=test_profile_type, - tenant_id=test_tenant_id, - profile_id=test_profile_id).one() - except s_exc.MultipleResultsFound: - self.fail("Bindings must be unique") - except s_exc.NoResultFound: - self.fail("Could not create Profile Binding") - - def test_update_profile_binding(self): - test_tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "dd7b9741-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "network" - n1kv_db_v2.create_profile_binding(self.session, - test_tenant_id, - test_profile_id, - test_profile_type) - new_tenants = ['d434dd90-76ec-11e2-bcfd-0800200c9a67', - 'd434dd90-76ec-11e2-bcfd-0800200c9a68', - 'd434dd90-76ec-11e2-bcfd-0800200c9a69'] - n1kv_db_v2.update_profile_binding(self.session, - test_profile_id, - new_tenants, - test_profile_type) - - result = self.session.query(n1kv_models_v2.ProfileBinding).filter_by( - profile_type=test_profile_type, - profile_id=test_profile_id).all() - self.assertEqual(3, len(result)) - - def test_get_profile_binding(self): - test_tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "dd7b9741-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "network" - self._create_test_binding_if_not_there(test_tenant_id, - test_profile_id, - test_profile_type) - binding = n1kv_db_v2.get_profile_binding(self.session, - test_tenant_id, - test_profile_id) - self.assertEqual(binding.tenant_id, test_tenant_id) - self.assertEqual(binding.profile_id, test_profile_id) - self.assertEqual(binding.profile_type, test_profile_type) - - def test_get_profile_binding_not_found(self): - self.assertRaises( - c_exc.ProfileTenantBindingNotFound, - n1kv_db_v2.get_profile_binding, self.session, "123", "456") - - def test_delete_profile_binding(self): - test_tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "dd7b9741-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "network" - self._create_test_binding_if_not_there(test_tenant_id, - test_profile_id, - test_profile_type) - n1kv_db_v2.delete_profile_binding(self.session, - test_tenant_id, - test_profile_id) - q = (self.session.query(n1kv_models_v2.ProfileBinding).filter_by( - profile_type=test_profile_type, - tenant_id=test_tenant_id, - profile_id=test_profile_id)) - self.assertFalse(q.count()) - - def test_default_tenant_replace(self): - ctx = context.get_admin_context() - ctx.tenant_id = "d434dd90-76ec-11e2-bcfd-0800200c9a66" - test_profile_id = "AAAAAAAA-76ec-11e2-bcfd-0800200c9a66" - test_profile_type = "policy" - n1kv_db_v2.create_profile_binding(self.session, - c_const.TENANT_ID_NOT_SET, - test_profile_id, - test_profile_type) - network_profile = {"network_profile": TEST_NETWORK_PROFILE} - self.create_network_profile(ctx, network_profile) - binding = n1kv_db_v2.get_profile_binding(self.session, - ctx.tenant_id, - test_profile_id) - self.assertRaises( - c_exc.ProfileTenantBindingNotFound, - n1kv_db_v2.get_profile_binding, - self.session, - c_const.TENANT_ID_NOT_SET, - test_profile_id) - self.assertNotEqual(binding.tenant_id, - c_const.TENANT_ID_NOT_SET) diff --git a/neutron/tests/unit/plugins/cisco/n1kv/test_n1kv_plugin.py b/neutron/tests/unit/plugins/cisco/n1kv/test_n1kv_plugin.py deleted file mode 100644 index c7f9b7616..000000000 --- a/neutron/tests/unit/plugins/cisco/n1kv/test_n1kv_plugin.py +++ /dev/null @@ -1,1289 +0,0 @@ -# Copyright 2013 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. - -import mock -import webob.exc - -from neutron.api import extensions as neutron_extensions -from neutron.api.v2 import attributes -from neutron.common import utils -from neutron import context -import neutron.db.api as db -from neutron.extensions import portbindings -from neutron import manager -from neutron.plugins.cisco.common import cisco_constants as c_const -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.common import config as c_conf -from neutron.plugins.cisco.db import n1kv_db_v2 -from neutron.plugins.cisco.db import n1kv_models_v2 -from neutron.plugins.cisco.db import network_db_v2 as cdb -from neutron.plugins.cisco import extensions -from neutron.plugins.cisco.extensions import n1kv -from neutron.plugins.cisco.extensions import network_profile -from neutron.plugins.cisco.extensions import policy_profile -from neutron.plugins.cisco.n1kv import n1kv_client -from neutron.plugins.cisco.n1kv import n1kv_neutron_plugin -from neutron.tests import tools -from neutron.tests.unit import _test_extension_portbindings as test_bindings -from neutron.tests.unit.api.v2 import test_base -from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin -from neutron.tests.unit.extensions import test_l3 -from neutron.tests.unit.plugins.cisco.n1kv import fake_client -from neutron.tests.unit.scheduler import test_l3_agent_scheduler - - -PHYS_NET = 'some-phys-net' -VLAN_MIN = 100 -VLAN_MAX = 110 -TENANT_NOT_ADMIN = 'not_admin' -TENANT_TEST = 'test' - - -class FakeResponse(object): - - """ - This object is returned by mocked requests lib instead of normal response. - - Initialize it with the status code, header and buffer contents you wish to - return. - - """ - def __init__(self, status, response_text, headers): - self.buffer = response_text - self.status_code = status - self.headers = headers - - def json(self, *args, **kwargs): - return self.buffer - - -def _fake_setup_vsm(self): - """Fake establish Communication with Cisco Nexus1000V VSM.""" - self.agent_vsm = True - self._populate_policy_profiles() - - -class NetworkProfileTestExtensionManager(object): - - def get_resources(self): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - network_profile.RESOURCE_ATTRIBUTE_MAP) - return network_profile.Network_profile.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class PolicyProfileTestExtensionManager(object): - - def get_resources(self): - # Add the resources to the global attribute map - # This is done here as the setup process won't - # initialize the main API router which extends - # the global attribute map - attributes.RESOURCE_ATTRIBUTE_MAP.update( - policy_profile.RESOURCE_ATTRIBUTE_MAP) - return policy_profile.Policy_profile.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class N1kvPluginTestCase(test_plugin.NeutronDbPluginV2TestCase): - - _plugin_name = ('neutron.plugins.cisco.n1kv.' - 'n1kv_neutron_plugin.N1kvNeutronPluginV2') - - tenant_id = "some_tenant" - - DEFAULT_RESP_BODY = "" - DEFAULT_RESP_CODE = 200 - DEFAULT_CONTENT_TYPE = "" - fmt = "json" - - def _make_test_policy_profile(self, name='service_profile'): - """ - Create a policy profile record for testing purpose. - - :param name: string representing the name of the policy profile to - create. Default argument value chosen to correspond to the - default name specified in config.py file. - """ - uuid = test_base._uuid() - profile = {'id': uuid, - 'name': name} - return n1kv_db_v2.create_policy_profile(profile) - - def _make_test_profile(self, - name='default_network_profile', - segment_type=c_const.NETWORK_TYPE_VLAN, - segment_range='386-400'): - """ - Create a profile record for testing purposes. - - :param name: string representing the name of the network profile to - create. Default argument value chosen to correspond to the - default name specified in config.py file. - :param segment_type: string representing the type of network segment. - :param segment_range: string representing the segment range for network - profile. - """ - db_session = db.get_session() - profile = {'name': name, - 'segment_type': segment_type, - 'tenant_id': self.tenant_id, - 'segment_range': segment_range} - if segment_type == c_const.NETWORK_TYPE_OVERLAY: - profile['sub_type'] = 'unicast' - profile['multicast_ip_range'] = '0.0.0.0' - net_p = n1kv_db_v2.create_network_profile(db_session, profile) - n1kv_db_v2.sync_vxlan_allocations(db_session, net_p) - elif segment_type == c_const.NETWORK_TYPE_VLAN: - profile['physical_network'] = PHYS_NET - net_p = n1kv_db_v2.create_network_profile(db_session, profile) - n1kv_db_v2.sync_vlan_allocations(db_session, net_p) - n1kv_db_v2.create_profile_binding(db_session, self.tenant_id, - net_p['id'], c_const.NETWORK) - n1kv_db_v2.create_profile_binding(db_session, TENANT_NOT_ADMIN, - net_p['id'], c_const.NETWORK) - n1kv_db_v2.create_profile_binding(db_session, TENANT_TEST, - net_p['id'], c_const.NETWORK) - return net_p - - def setUp(self, ext_mgr=NetworkProfileTestExtensionManager()): - """ - Setup method for n1kv plugin tests. - - First step is to define an acceptable response from the VSM to - our requests. This needs to be done BEFORE the setUp() function - of the super-class is called. - - This default here works for many cases. If you need something - extra, please define your own setUp() function in your test class, - and set your DEFAULT_RESPONSE value also BEFORE calling the - setUp() of the super-function (this one here). If you have set - a value already, it will not be overwritten by this code. - - """ - if not self.DEFAULT_RESP_BODY: - self.DEFAULT_RESP_BODY = { - "icehouse-pp": {"properties": {"name": "icehouse-pp", - "id": "some-uuid-1"}}, - "havana_pp": {"properties": {"name": "havana_pp", - "id": "some-uuid-2"}}, - "dhcp_pp": {"properties": {"name": "dhcp_pp", - "id": "some-uuid-3"}}, - } - # Creating a mock HTTP connection object for requests lib. The N1KV - # client interacts with the VSM via HTTP. Since we don't have a VSM - # running in the unit tests, we need to 'fake' it by patching the HTTP - # library itself. We install a patch for a fake HTTP connection class. - # Using __name__ to avoid having to enter the full module path. - http_patcher = mock.patch(n1kv_client.requests.__name__ + ".request") - FakeHttpConnection = http_patcher.start() - # Now define the return values for a few functions that may be called - # on any instance of the fake HTTP connection class. - self.resp_headers = {"content-type": "application/json"} - FakeHttpConnection.return_value = (FakeResponse( - self.DEFAULT_RESP_CODE, - self.DEFAULT_RESP_BODY, - self.resp_headers)) - - # Patch some internal functions in a few other parts of the system. - # These help us move along, without having to mock up even more systems - # in the background. - - # Return a dummy VSM IP address - mock.patch(n1kv_client.__name__ + ".Client._get_vsm_hosts", - new=lambda self: "127.0.0.1").start() - - # Return dummy user profiles - mock.patch(cdb.__name__ + ".get_credential_name", - new=lambda self: {"user_name": "admin", - "password": "admin_password"}).start() - - n1kv_neutron_plugin.N1kvNeutronPluginV2._setup_vsm = _fake_setup_vsm - - neutron_extensions.append_api_extensions_path(extensions.__path__) - - self.useFixture(tools.AttributeMapMemento()) - # Update the RESOURCE_ATTRIBUTE_MAP with n1kv specific extended attrs. - attributes.RESOURCE_ATTRIBUTE_MAP["networks"].update( - n1kv.EXTENDED_ATTRIBUTES_2_0["networks"]) - attributes.RESOURCE_ATTRIBUTE_MAP["ports"].update( - n1kv.EXTENDED_ATTRIBUTES_2_0["ports"]) - super(N1kvPluginTestCase, self).setUp(self._plugin_name, - ext_mgr=ext_mgr) - # Create some of the database entries that we require. - self._make_test_profile() - self._make_test_policy_profile() - - -class TestN1kvNetworkProfiles(N1kvPluginTestCase): - def _prepare_net_profile_data(self, - segment_type, - sub_type=None, - segment_range=None, - mcast_ip_range=None): - netp = {'name': 'netp1', - 'segment_type': segment_type, - 'tenant_id': self.tenant_id} - if segment_type == c_const.NETWORK_TYPE_VLAN: - netp['segment_range'] = segment_range or '100-110' - netp['physical_network'] = PHYS_NET - elif segment_type == c_const.NETWORK_TYPE_OVERLAY: - netp['segment_range'] = segment_range or '10000-10010' - netp['sub_type'] = sub_type or 'enhanced' - netp['multicast_ip_range'] = (mcast_ip_range or - "224.1.1.1-224.1.1.10") - elif segment_type == c_const.NETWORK_TYPE_TRUNK: - netp['sub_type'] = c_const.NETWORK_TYPE_VLAN - data = {"network_profile": netp} - return data - - def test_create_network_profile_vlan(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_VLAN) - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - - def test_create_network_profile_overlay(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY) - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - - def test_create_network_profile_overlay_missing_subtype(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY) - data['network_profile'].pop('sub_type') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_network_profile_trunk(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_TRUNK) - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - - def test_create_network_profile_trunk_missing_subtype(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_TRUNK) - data['network_profile'].pop('sub_type') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_network_profile_overlay_unreasonable_seg_range(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY, - segment_range='10000-1000000001') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_network_profile_plugin(self): - net_p_dict = (self. - _prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY)) - net_p_req = self.new_create_request('network_profiles', net_p_dict) - net_p = self.deserialize(self.fmt, - net_p_req.get_response(self.ext_api)) - data = {'network_profile': {'name': 'netp2'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 200) - - def test_update_network_profile_physical_network_fail(self): - net_p = self._make_test_profile(name='netp1') - data = {'network_profile': {'physical_network': PHYS_NET}} - net_p_req = self.new_update_request('network_profiles', - data, - net_p['id']) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_network_profile_segment_type_fail(self): - net_p = self._make_test_profile(name='netp1') - data = {'network_profile': { - 'segment_type': c_const.NETWORK_TYPE_OVERLAY}} - net_p_req = self.new_update_request('network_profiles', - data, - net_p['id']) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_network_profile_sub_type_fail(self): - net_p_dict = (self. - _prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY)) - net_p_req = self.new_create_request('network_profiles', net_p_dict) - net_p = self.deserialize(self.fmt, - net_p_req.get_response(self.ext_api)) - data = {'network_profile': {'sub_type': c_const.NETWORK_TYPE_VLAN}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_update_network_profiles_with_networks_fail(self): - net_p = self._make_test_profile(name='netp1') - data = {'network_profile': {'segment_range': '200-210'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 200) - net_data = {'network': {'name': 'net1', - n1kv.PROFILE_ID: net_p['id'], - 'tenant_id': 'some_tenant'}} - network_req = self.new_create_request('networks', net_data) - network_res = network_req.get_response(self.api) - self.assertEqual(network_res.status_int, 201) - data = {'network_profile': {'segment_range': '300-310'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 409) - - def test_create_overlay_network_profile_invalid_multicast_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY, - sub_type=(c_const. - NETWORK_SUBTYPE_NATIVE_VXLAN), - mcast_ip_range='1.1.1.1') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_no_multicast_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY, - sub_type=(c_const. - NETWORK_SUBTYPE_NATIVE_VXLAN)) - data['network_profile']['multicast_ip_range'] = '' - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_wrong_split_multicast_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY, - sub_type=(c_const. - NETWORK_SUBTYPE_NATIVE_VXLAN), - mcast_ip_range= - '224.1.1.1.224.1.1.3') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_invalid_minip_multicast_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY, - sub_type=(c_const. - NETWORK_SUBTYPE_NATIVE_VXLAN), - mcast_ip_range= - '10.0.0.1-224.1.1.3') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_invalid_maxip_multicast_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY, - sub_type=(c_const. - NETWORK_SUBTYPE_NATIVE_VXLAN), - mcast_ip_range= - '224.1.1.1-20.0.0.1') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_create_overlay_network_profile_correct_multicast_pass(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY) - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - - def test_update_overlay_network_profile_correct_multicast_pass(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY) - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - net_p = self.deserialize(self.fmt, res) - data = {'network_profile': {'multicast_ip_range': - '224.0.1.0-224.0.1.100'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 200) - - def test_create_overlay_network_profile_reservedip_multicast_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY, - sub_type=(c_const. - NETWORK_SUBTYPE_NATIVE_VXLAN), - mcast_ip_range= - '224.0.0.100-224.0.1.100') - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_overlay_network_profile_reservedip_multicast_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_OVERLAY) - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - net_p = self.deserialize(self.fmt, res) - data = {'network_profile': {'multicast_ip_range': - '224.0.0.11-224.0.0.111'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_update_vlan_network_profile_multicast_fail(self): - net_p = self._make_test_profile(name='netp1') - data = {'network_profile': {'multicast_ip_range': - '224.0.1.0-224.0.1.100'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_update_trunk_network_profile_segment_range_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_TRUNK) - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - net_p = self.deserialize(self.fmt, res) - data = {'network_profile': {'segment_range': - '100-200'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_update_trunk_network_profile_multicast_fail(self): - data = self._prepare_net_profile_data(c_const.NETWORK_TYPE_TRUNK) - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(res.status_int, 201) - net_p = self.deserialize(self.fmt, res) - data = {'network_profile': {'multicast_ip_range': - '224.0.1.0-224.0.1.100'}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(update_res.status_int, 400) - - def test_create_network_profile_populate_vlan_segment_pool(self): - db_session = db.get_session() - net_p_dict = self._prepare_net_profile_data(c_const.NETWORK_TYPE_VLAN) - net_p_req = self.new_create_request('network_profiles', net_p_dict) - self.deserialize(self.fmt, - net_p_req.get_response(self.ext_api)) - for vlan in range(VLAN_MIN, VLAN_MAX + 1): - self.assertIsNotNone(n1kv_db_v2.get_vlan_allocation(db_session, - PHYS_NET, - vlan)) - self.assertFalse(n1kv_db_v2.get_vlan_allocation(db_session, - PHYS_NET, - vlan).allocated) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - db_session, - PHYS_NET, - VLAN_MIN - 1) - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - db_session, - PHYS_NET, - VLAN_MAX + 1) - - def test_delete_network_profile_with_network_fail(self): - net_p = self._make_test_profile(name='netp1') - net_data = {'network': {'name': 'net1', - n1kv.PROFILE_ID: net_p['id'], - 'tenant_id': 'some_tenant'}} - network_req = self.new_create_request('networks', net_data) - network_res = network_req.get_response(self.api) - self.assertEqual(network_res.status_int, 201) - self._delete('network_profiles', net_p['id'], - expected_code=409) - - def test_delete_network_profile_deallocate_vlan_segment_pool(self): - db_session = db.get_session() - net_p_dict = self._prepare_net_profile_data(c_const.NETWORK_TYPE_VLAN) - net_p_req = self.new_create_request('network_profiles', net_p_dict) - net_p = self.deserialize(self.fmt, - net_p_req.get_response(self.ext_api)) - self.assertIsNotNone(n1kv_db_v2.get_vlan_allocation(db_session, - PHYS_NET, - VLAN_MIN)) - self._delete('network_profiles', net_p['network_profile']['id']) - for vlan in range(VLAN_MIN, VLAN_MAX + 1): - self.assertRaises(c_exc.VlanIDNotFound, - n1kv_db_v2.get_vlan_allocation, - db_session, - PHYS_NET, - vlan) - - def test_create_network_profile_rollback_profile_binding(self): - """Test rollback of profile binding if network profile create fails.""" - db_session = db.get_session() - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClientInvalidResponse) - client_patch.start() - net_p_dict = self._prepare_net_profile_data(c_const.NETWORK_TYPE_VLAN) - self.new_create_request('network_profiles', net_p_dict) - bindings = (db_session.query(n1kv_models_v2.ProfileBinding).filter_by( - profile_type="network")) - self.assertEqual(3, bindings.count()) - - def test_create_network_profile_with_old_add_tenant_fail(self): - data = self._prepare_net_profile_data('vlan') - data['network_profile']['add_tenant'] = 'tenant1' - net_p_req = self.new_create_request('network_profiles', data) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(400, res.status_int) - - def test_create_network_profile_multi_tenants(self): - data = self._prepare_net_profile_data('vlan') - data['network_profile'][c_const.ADD_TENANTS] = ['tenant1', 'tenant2'] - del data['network_profile']['tenant_id'] - net_p_req = self.new_create_request('network_profiles', data) - net_p_req.environ['neutron.context'] = context.Context('', - self.tenant_id, - is_admin=True) - res = net_p_req.get_response(self.ext_api) - self.assertEqual(201, res.status_int) - net_p = self.deserialize(self.fmt, res) - db_session = db.get_session() - tenant_id = n1kv_db_v2.get_profile_binding(db_session, self.tenant_id, - net_p['network_profile']['id']) - tenant1 = n1kv_db_v2.get_profile_binding(db_session, 'tenant1', - net_p['network_profile']['id']) - tenant2 = n1kv_db_v2.get_profile_binding(db_session, 'tenant2', - net_p['network_profile']['id']) - self.assertIsNotNone(tenant_id) - self.assertIsNotNone(tenant1) - self.assertIsNotNone(tenant2) - return net_p - - def test_update_network_profile_multi_tenants(self): - net_p = self.test_create_network_profile_multi_tenants() - data = {'network_profile': {c_const.ADD_TENANTS: - ['tenant1', 'tenant3']}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_req.environ['neutron.context'] = context.Context('', - self.tenant_id, - is_admin=True) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(200, update_res.status_int) - db_session = db.get_session() - # current tenant_id should always present - tenant_id = n1kv_db_v2.get_profile_binding(db_session, self.tenant_id, - net_p['network_profile']['id']) - tenant1 = n1kv_db_v2.get_profile_binding(db_session, 'tenant1', - net_p['network_profile']['id']) - self.assertRaises(c_exc.ProfileTenantBindingNotFound, - n1kv_db_v2.get_profile_binding, - db_session, 'tenant4', - net_p['network_profile']['id']) - tenant3 = n1kv_db_v2.get_profile_binding(db_session, 'tenant3', - net_p['network_profile']['id']) - self.assertIsNotNone(tenant_id) - self.assertIsNotNone(tenant1) - self.assertIsNotNone(tenant3) - data = {'network_profile': {c_const.REMOVE_TENANTS: [self.tenant_id, - 'tenant1']}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_req.environ['neutron.context'] = context.Context('', - self.tenant_id, - is_admin=True) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(200, update_res.status_int) - # current tenant_id should always present - tenant_id = n1kv_db_v2.get_profile_binding(db_session, self.tenant_id, - net_p['network_profile']['id']) - self.assertIsNotNone(tenant_id) - self.assertRaises(c_exc.ProfileTenantBindingNotFound, - n1kv_db_v2.get_profile_binding, - db_session, 'tenant1', - net_p['network_profile']['id']) - self.assertRaises(c_exc.ProfileTenantBindingNotFound, - n1kv_db_v2.get_profile_binding, - db_session, 'tenant4', - net_p['network_profile']['id']) - tenant3 = n1kv_db_v2.get_profile_binding(db_session, 'tenant3', - net_p['network_profile']['id']) - self.assertIsNotNone(tenant3) - # Add new tenant4 to network profile and make sure existing tenants - # are not deleted. - data = {'network_profile': {c_const.ADD_TENANTS: - ['tenant4']}} - update_req = self.new_update_request('network_profiles', - data, - net_p['network_profile']['id']) - update_req.environ['neutron.context'] = context.Context('', - self.tenant_id, - is_admin=True) - update_res = update_req.get_response(self.ext_api) - self.assertEqual(200, update_res.status_int) - tenant4 = n1kv_db_v2.get_profile_binding(db_session, 'tenant4', - net_p['network_profile']['id']) - self.assertIsNotNone(tenant4) - - def test_get_network_profile_restricted(self): - c_conf.CONF.set_override('restrict_network_profiles', True, - 'CISCO_N1K') - ctx1 = context.Context(user_id='admin', - tenant_id='tenant1', - is_admin=True) - sess1 = db.get_session() - net_p = self._make_test_profile(name='netp1') - n1kv_db_v2.create_profile_binding(sess1, ctx1.tenant_id, - net_p['id'], c_const.NETWORK) - #network profile binding with creator tenant should always exist - profile = n1kv_db_v2.get_network_profile(sess1, net_p['id'], - ctx1.tenant_id) - self.assertIsNotNone(profile) - ctx2 = context.Context(user_id='non_admin', - tenant_id='tenant2', - is_admin=False) - sess2 = db.get_session() - self.assertRaises(c_exc.ProfileTenantBindingNotFound, - n1kv_db_v2.get_network_profile, - sess2, net_p['id'], ctx2.tenant_id) - - def test_get_network_profile_unrestricted(self): - c_conf.CONF.set_override('restrict_network_profiles', False, - 'CISCO_N1K') - ctx1 = context.Context(user_id='admin', - tenant_id='tenant1', - is_admin=True) - sess1 = db.get_session() - net_p = self._make_test_profile(name='netp1') - n1kv_db_v2.create_profile_binding(sess1, ctx1.tenant_id, - net_p['id'], c_const.NETWORK) - # network profile binding with creator tenant should always exist - profile = n1kv_db_v2.get_network_profile(sess1, net_p['id'], - ctx1.tenant_id) - self.assertIsNotNone(profile) - ctx2 = context.Context(user_id='non_admin', - tenant_id='tenant2', - is_admin=False) - sess2 = db.get_session() - profile = n1kv_db_v2.get_network_profile(sess2, net_p['id'], - ctx2.tenant_id) - #network profile will be returned even though the profile is - #not bound to tenant of sess2 - self.assertIsNotNone(profile) - - -class TestN1kvBasicGet(test_plugin.TestBasicGet, - N1kvPluginTestCase): - - pass - - -class TestN1kvHTTPResponse(test_plugin.TestV2HTTPResponse, - N1kvPluginTestCase): - - pass - - -class TestN1kvPorts(test_plugin.TestPortsV2, - N1kvPluginTestCase, - test_bindings.PortBindingsTestCase): - VIF_TYPE = portbindings.VIF_TYPE_OVS - HAS_PORT_FILTER = False - - _unsupported = ('test_delete_network_if_port_exists', - 'test_requested_subnet_id_v4_and_v6') - - def setUp(self): - if self._testMethodName in self._unsupported: - self.skipTest("Unsupported test case") - super(TestN1kvPorts, self).setUp() - - def test_create_port_with_default_n1kv_policy_profile_id(self): - """Test port create without passing policy profile id.""" - with self.port() as port: - db_session = db.get_session() - pp = n1kv_db_v2.get_policy_profile( - db_session, port['port'][n1kv.PROFILE_ID]) - self.assertEqual(pp['name'], 'service_profile') - - def test_create_port_with_n1kv_policy_profile_id(self): - """Test port create with policy profile id.""" - profile_obj = self._make_test_policy_profile(name='test_profile') - with self.network() as network: - data = {'port': {n1kv.PROFILE_ID: profile_obj.id, - 'tenant_id': self.tenant_id, - 'network_id': network['network']['id']}} - port_req = self.new_create_request('ports', data) - port = self.deserialize(self.fmt, - port_req.get_response(self.api)) - self.assertEqual(port['port'][n1kv.PROFILE_ID], - profile_obj.id) - self._delete('ports', port['port']['id']) - - def test_update_port_with_n1kv_policy_profile_id(self): - """Test port update failure while updating policy profile id.""" - with self.port() as port: - data = {'port': {n1kv.PROFILE_ID: 'some-profile-uuid'}} - port_req = self.new_update_request('ports', - data, - port['port']['id']) - res = port_req.get_response(self.api) - # Port update should fail to update policy profile id. - self.assertEqual(res.status_int, 400) - - def test_create_first_port_invalid_parameters_fail(self): - """Test parameters for first port create sent to the VSM.""" - profile_obj = self._make_test_policy_profile(name='test_profile') - with self.network() as network: - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClientInvalidRequest) - client_patch.start() - data = {'port': {n1kv.PROFILE_ID: profile_obj.id, - 'tenant_id': self.tenant_id, - 'network_id': network['network']['id'], - }} - port_req = self.new_create_request('ports', data) - res = port_req.get_response(self.api) - self.assertEqual(res.status_int, 500) - client_patch.stop() - - def test_create_next_port_invalid_parameters_fail(self): - """Test parameters for subsequent port create sent to the VSM.""" - with self.port() as port: - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClientInvalidRequest) - client_patch.start() - data = {'port': {n1kv.PROFILE_ID: port['port']['n1kv:profile_id'], - 'tenant_id': port['port']['tenant_id'], - 'network_id': port['port']['network_id']}} - port_req = self.new_create_request('ports', data) - res = port_req.get_response(self.api) - self.assertEqual(res.status_int, 500) - client_patch.stop() - - def test_create_first_port_rollback_vmnetwork(self): - """Test whether VMNetwork is cleaned up if port create fails on VSM.""" - db_session = db.get_session() - profile_obj = self._make_test_policy_profile(name='test_profile') - with self.network() as network: - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client. - TestClientInvalidResponse) - client_patch.start() - data = {'port': {n1kv.PROFILE_ID: profile_obj.id, - 'tenant_id': self.tenant_id, - 'network_id': network['network']['id'], - }} - self.new_create_request('ports', data) - self.assertRaises(c_exc.VMNetworkNotFound, - n1kv_db_v2.get_vm_network, - db_session, - profile_obj.id, - network['network']['id']) - # Explicit stop of failure response mock from controller required - # for network object clean up to succeed. - client_patch.stop() - - def test_create_next_port_rollback_vmnetwork_count(self): - """Test whether VMNetwork count if port create fails on VSM.""" - db_session = db.get_session() - with self.port() as port: - pt = port['port'] - old_vmn = n1kv_db_v2.get_vm_network(db_session, - pt['n1kv:profile_id'], - pt['network_id']) - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client. - TestClientInvalidResponse) - client_patch.start() - data = {'port': {n1kv.PROFILE_ID: pt['n1kv:profile_id'], - 'tenant_id': pt['tenant_id'], - 'network_id': pt['network_id']}} - self.new_create_request('ports', data) - new_vmn = n1kv_db_v2.get_vm_network(db_session, - pt['n1kv:profile_id'], - pt['network_id']) - self.assertEqual(old_vmn.port_count, new_vmn.port_count) - # Explicit stop of failure response mock from controller required - # for network object clean up to succeed. - client_patch.stop() - - def test_delete_last_port_vmnetwork_cleanup(self): - """Test whether VMNetwork is cleaned up from db on last port delete.""" - db_session = db.get_session() - with self.port() as port: - pt = port['port'] - self.assertIsNotNone(n1kv_db_v2. - get_vm_network(db_session, - pt['n1kv:profile_id'], - pt['network_id'])) - req = self.new_delete_request('ports', port['port']['id']) - req.get_response(self.api) - # Verify VMNetwork is cleaned up from the database on port delete. - self.assertRaises(c_exc.VMNetworkNotFound, - n1kv_db_v2.get_vm_network, - db_session, - pt['n1kv:profile_id'], - pt['network_id']) - - -class TestN1kvPolicyProfiles(N1kvPluginTestCase): - def setUp(self): - """ - Setup function for policy profile tests. - - We need to use the policy profile extension manager for these - test cases, so call the super class setup, but pass in the - policy profile extension manager. - """ - super(TestN1kvPolicyProfiles, self).setUp( - ext_mgr=PolicyProfileTestExtensionManager()) - - def test_populate_policy_profile(self): - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClient) - client_patch.start() - instance = n1kv_neutron_plugin.N1kvNeutronPluginV2() - instance._populate_policy_profiles() - db_session = db.get_session() - profile = n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000001') - self.assertEqual('pp-1', profile['name']) - client_patch.stop() - - def test_populate_policy_profile_delete(self): - # Patch the Client class with the TestClient class - with mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClient): - # Patch the _get_total_profiles() method to return a custom value - with mock.patch(fake_client.__name__ + - '.TestClient._get_total_profiles') as obj_inst: - # Return 3 policy profiles - obj_inst.return_value = 3 - plugin = manager.NeutronManager.get_plugin() - plugin._populate_policy_profiles() - db_session = db.get_session() - profile = n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000001') - # Verify that DB contains only 3 policy profiles - self.assertEqual('pp-1', profile['name']) - profile = n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000002') - self.assertEqual('pp-2', profile['name']) - profile = n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000003') - self.assertEqual('pp-3', profile['name']) - self.assertRaises(c_exc.PolicyProfileIdNotFound, - n1kv_db_v2.get_policy_profile, - db_session, - '00000000-0000-0000-0000-000000000004') - # Return 2 policy profiles - obj_inst.return_value = 2 - plugin._populate_policy_profiles() - # Verify that the third policy profile is deleted - self.assertRaises(c_exc.PolicyProfileIdNotFound, - n1kv_db_v2.get_policy_profile, - db_session, - '00000000-0000-0000-0000-000000000003') - - def _init_get_policy_profiles(self): - # Get the profiles - mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClient).start() - instance = n1kv_neutron_plugin.N1kvNeutronPluginV2() - instance._populate_policy_profiles() - db_session = db.get_session() - return [ - n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000001'), - n1kv_db_v2.get_policy_profile( - db_session, '00000000-0000-0000-0000-000000000002') - ] - - def _test_get_policy_profiles(self, expected_profiles, admin): - resource = 'policy_profiles' - if admin: - ctx = context.Context(user_id='admin', - tenant_id='tenant1', - is_admin=True) - else: - ctx = context.Context(user_id='non_admin', - tenant_id='tenant1', - is_admin=False) - res = self._list(resource, neutron_context=ctx) - self.assertEqual(len(expected_profiles), len(res[resource])) - profiles = sorted(res[resource], key=utils.safe_sort_key) - for i in range(len(profiles)): - self.assertEqual(expected_profiles[i].id, - profiles[i]['id']) - self.assertEqual(expected_profiles[i].name, - profiles[i]['name']) - - def test_get_profiles_unrestricted(self): - """ - Test unrestricted policy profile retrieval. - - Test getting policy profiles using the normal unrestricted - behavior. We set the flag and attempt to retrieve the port - profiles. It should work for both admin and non-admin. - """ - # Get the profiles - profiles = self._init_get_policy_profiles() - # Set the restriction flag - c_conf.CONF.set_override('restrict_policy_profiles', False, - 'CISCO_N1K') - # Request the list using non-admin and verify it returns - self._test_get_policy_profiles(expected_profiles=profiles, admin=False) - # Request the list using admin and verify it returns - self._test_get_policy_profiles(expected_profiles=profiles, admin=True) - - def test_get_profiles_restricted(self): - """ - Test restricted policy profile retrieval. - - Test getting policy profiles using the restricted behavior. - We set the flag and attempt to retrieve the port profiles. It - should work for admin and fail for non-admin. - """ - # Get the profiles - profiles = self._init_get_policy_profiles() - # Set the restriction flag - c_conf.CONF.set_override('restrict_policy_profiles', True, - 'CISCO_N1K') - # Request the list using non-admin and verify it returns no data - self._test_get_policy_profiles(expected_profiles=[], admin=False) - # Request the list using admin and verify it returns - self._test_get_policy_profiles(expected_profiles=profiles, admin=True) - - def test_get_policy_profiles_by_name(self): - with mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClient): - instance = n1kv_neutron_plugin.N1kvNeutronPluginV2() - profile = instance._get_policy_profile_by_name('pp-1') - self.assertEqual('pp-1', profile['name']) - self.assertEqual('00000000-0000-0000-0000-000000000001', - profile['id']) - self.assertRaises(c_exc.PolicyProfileNameNotFound, - instance._get_policy_profile_by_name, - "name") - - -class TestN1kvNetworks(test_plugin.TestNetworksV2, - N1kvPluginTestCase): - - def test_plugin(self): - self._make_network('json', - 'some_net', - True, - tenant_id=self.tenant_id, - set_context=True) - - req = self.new_list_request('networks', params="fields=tenant_id") - req.environ['neutron.context'] = context.Context('', self.tenant_id) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 200) - body = self.deserialize('json', res) - self.assertIn('tenant_id', body['networks'][0]) - - def _prepare_net_data(self, net_profile_id): - return {'network': {'name': 'net1', - n1kv.PROFILE_ID: net_profile_id, - 'tenant_id': self.tenant_id}} - - def test_create_network_with_default_n1kv_network_profile_id(self): - """Test network create without passing network profile id.""" - with self.network() as network: - db_session = db.get_session() - np = n1kv_db_v2.get_network_profile( - db_session, network['network'][n1kv.PROFILE_ID]) - self.assertEqual(np['name'], 'default_network_profile') - - def test_create_network_with_n1kv_network_profile_id(self): - """Test network create with network profile id.""" - profile_obj = self._make_test_profile(name='test_profile') - data = self._prepare_net_data(profile_obj.id) - network_req = self.new_create_request('networks', data) - network = self.deserialize(self.fmt, - network_req.get_response(self.api)) - self.assertEqual(network['network'][n1kv.PROFILE_ID], - profile_obj.id) - - def test_update_network_with_n1kv_network_profile_id(self): - """Test network update failure while updating network profile id.""" - with self.network() as network: - data = {'network': {n1kv.PROFILE_ID: 'some-profile-uuid'}} - network_req = self.new_update_request('networks', - data, - network['network']['id']) - res = network_req.get_response(self.api) - # Network update should fail to update network profile id. - self.assertEqual(res.status_int, 400) - - def test_create_network_rollback_deallocate_vlan_segment(self): - """Test vlan segment deallocation on network create failure.""" - profile_obj = self._make_test_profile(name='test_profile', - segment_range='20-23') - data = self._prepare_net_data(profile_obj.id) - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClientInvalidResponse) - client_patch.start() - self.new_create_request('networks', data) - db_session = db.get_session() - self.assertFalse(n1kv_db_v2.get_vlan_allocation(db_session, - PHYS_NET, - 20).allocated) - - def test_create_network_rollback_deallocate_overlay_segment(self): - """Test overlay segment deallocation on network create failure.""" - profile_obj = self._make_test_profile('test_np', - c_const.NETWORK_TYPE_OVERLAY, - '10000-10001') - data = self._prepare_net_data(profile_obj.id) - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClientInvalidResponse) - client_patch.start() - self.new_create_request('networks', data) - db_session = db.get_session() - self.assertFalse(n1kv_db_v2.get_vxlan_allocation(db_session, - 10000).allocated) - - def test_delete_network(self): - """Regular test case of network deletion. Should return successful.""" - res = self._create_network(self.fmt, name='net', admin_state_up=True) - network = self.deserialize(self.fmt, res) - req = self.new_delete_request('networks', network['network']['id']) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) - - def test_delete_network_with_subnet(self): - """Network deletion fails when a subnet is present on the network.""" - with self.subnet() as subnet: - net_id = subnet['subnet']['network_id'] - req = self.new_delete_request('networks', net_id) - res = req.get_response(self.api) - self.assertEqual(res.status_int, webob.exc.HTTPBadRequest.code) - - def test_update_network_set_not_shared_multi_tenants2_returns_409(self): - """ - Verifies that updating a network which cannot be shared, - returns a conflict error. - """ - with self.network(shared=True) as network: - res = self._create_port(self.fmt, network['network']['id'], - webob.exc.HTTPCreated.code, - tenant_id='somebody_else', - set_context=True) - data = {'network': {'shared': False}} - req = self.new_update_request('networks', data, - network['network']['id']) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPConflict.code) - port = self.deserialize(self.fmt, res) - self._delete('ports', port['port']['id']) - - def test_delete_network_if_port_exists(self): - """Verify that a network with a port attached cannot be removed.""" - res = self._create_network(self.fmt, name='net1', admin_state_up=True) - network = self.deserialize(self.fmt, res) - net_id = network['network']['id'] - res = self._create_port(self.fmt, net_id, - webob.exc.HTTPCreated.code) - req = self.new_delete_request('networks', net_id) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPConflict.code) - - -class TestN1kvSubnets(test_plugin.TestSubnetsV2, - N1kvPluginTestCase): - - _unsupported = ( - 'test_delete_network', - 'test_create_subnets_bulk_emulated', - 'test_create_subnets_bulk_emulated_plugin_failure') - - def setUp(self): - if self._testMethodName in self._unsupported: - self.skipTest("Unsupported test") - super(TestN1kvSubnets, self).setUp() - - def test_port_prevents_network_deletion(self): - self.skipTest("plugin does not return standard conflict code") - - def test_create_subnet_with_invalid_parameters(self): - """Test subnet creation with invalid parameters sent to the VSM""" - with self.network() as network: - client_patch = mock.patch(n1kv_client.__name__ + ".Client", - new=fake_client.TestClientInvalidRequest) - client_patch.start() - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': "10.0.0.0/24"}} - subnet_req = self.new_create_request('subnets', data) - subnet_resp = subnet_req.get_response(self.api) - # Subnet creation should fail due to invalid network name - self.assertEqual(subnet_resp.status_int, 400) - - def test_update_subnet_adding_additional_host_routes_and_dns(self): - host_routes = [{'destination': '172.16.0.0/24', - 'nexthop': '10.0.2.2'}] - with self.network() as network: - data = {'subnet': {'network_id': network['network']['id'], - 'cidr': '10.0.2.0/24', - 'ip_version': 4, - 'dns_nameservers': ['192.168.0.1'], - 'host_routes': host_routes, - 'tenant_id': network['network']['tenant_id']}} - req = self.new_create_request('subnets', data) - subnet = self.deserialize(self.fmt, req.get_response(self.api)) - - host_routes = [{'destination': '172.16.0.0/24', - 'nexthop': '10.0.2.2'}, - {'destination': '192.168.0.0/24', - 'nexthop': '10.0.2.3'}] - - dns_nameservers = ['192.168.0.1', '192.168.0.2'] - data = {'subnet': {'host_routes': host_routes, - 'dns_nameservers': dns_nameservers}} - req = self.new_update_request('subnets', data, - subnet['subnet']['id']) - subnet = self.deserialize(self.fmt, req.get_response(self.api)) - self.assertEqual( - sorted(subnet['subnet']['host_routes'], - key=utils.safe_sort_key), - sorted(host_routes, key=utils.safe_sort_key)) - self.assertEqual(sorted(subnet['subnet']['dns_nameservers']), - sorted(dns_nameservers)) - # In N1K we need to delete the subnet before the network - req = self.new_delete_request('subnets', subnet['subnet']['id']) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPNoContent.code) - - def test_subnet_with_allocation_range(self): - with self.network() as network: - net_id = network['network']['id'] - data = {'subnet': {'network_id': net_id, - 'cidr': '10.0.0.0/24', - 'ip_version': 4, - 'gateway_ip': '10.0.0.1', - 'tenant_id': network['network']['tenant_id'], - 'allocation_pools': [{'start': '10.0.0.100', - 'end': '10.0.0.120'}]}} - req = self.new_create_request('subnets', data) - subnet = self.deserialize(self.fmt, req.get_response(self.api)) - # Check fixed IP not in allocation range - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.10'}]} - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - port = self.deserialize(self.fmt, res) - # delete the port - self._delete('ports', port['port']['id']) - # Check when fixed IP is gateway - kwargs = {"fixed_ips": [{'subnet_id': subnet['subnet']['id'], - 'ip_address': '10.0.0.1'}]} - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - self.assertEqual(res.status_int, webob.exc.HTTPCreated.code) - port = self.deserialize(self.fmt, res) - # delete the port - self._delete('ports', port['port']['id']) - req = self.new_delete_request('subnets', subnet['subnet']['id']) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPNoContent.code) - - def test_requested_subnet_id_v4_and_v6(self): - with self.network() as network: - net_id = network['network']['id'] - res = self._create_subnet(self.fmt, tenant_id='tenant1', - net_id=net_id, cidr='10.0.0.0/24', - ip_version=4, - gateway_ip=attributes.ATTR_NOT_SPECIFIED) - subnet1 = self.deserialize(self.fmt, res) - res = self._create_subnet(self.fmt, tenant_id='tenant1', - net_id=net_id, - cidr='2607:f0d0:1002:51::/124', - ip_version=6, - gateway_ip=attributes.ATTR_NOT_SPECIFIED) - subnet2 = self.deserialize(self.fmt, res) - kwargs = {"fixed_ips": [{'subnet_id': subnet1['subnet']['id']}, - {'subnet_id': subnet2['subnet']['id']}]} - res = self._create_port(self.fmt, net_id=net_id, **kwargs) - port3 = self.deserialize(self.fmt, res) - ips = port3['port']['fixed_ips'] - self.assertEqual(len(ips), 2) - self.assertIn({'ip_address': '10.0.0.2', - 'subnet_id': subnet1['subnet']['id']}, ips) - self.assertIn({'ip_address': '2607:f0d0:1002:51::2', - 'subnet_id': subnet2['subnet']['id']}, ips) - res = self._create_port(self.fmt, net_id=net_id) - port4 = self.deserialize(self.fmt, res) - # Check that a v4 and a v6 address are allocated - ips = port4['port']['fixed_ips'] - self.assertEqual(len(ips), 2) - self.assertIn({'ip_address': '10.0.0.3', - 'subnet_id': subnet1['subnet']['id']}, ips) - self.assertIn({'ip_address': '2607:f0d0:1002:51::3', - 'subnet_id': subnet2['subnet']['id']}, ips) - self._delete('ports', port3['port']['id']) - self._delete('ports', port4['port']['id']) - req = self.new_delete_request('subnets', subnet1['subnet']['id']) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPNoContent.code) - req = self.new_delete_request('subnets', subnet2['subnet']['id']) - self.assertEqual(req.get_response(self.api).status_int, - webob.exc.HTTPNoContent.code) - - def test_schedule_network_with_subnet_create(self): - """Test invocation of explicit scheduling for networks.""" - with mock.patch.object(n1kv_neutron_plugin.N1kvNeutronPluginV2, - 'schedule_network') as mock_method: - # Test with network auto-scheduling disabled - c_conf.CONF.set_override('network_auto_schedule', False) - # Subnet creation should trigger scheduling for networks - with self.subnet(): - pass - self.assertEqual(1, mock_method.call_count) - - -class TestN1kvL3Test(test_l3.L3NatExtensionTestCase): - - pass - - -class TestN1kvL3SchedulersTest( - test_l3_agent_scheduler.L3SchedulerTestCaseMixin, - test_plugin.NeutronDbPluginV2TestCase): - - pass diff --git a/neutron/tests/unit/plugins/cisco/test_network_db.py b/neutron/tests/unit/plugins/cisco/test_network_db.py deleted file mode 100644 index a07c22e82..000000000 --- a/neutron/tests/unit/plugins/cisco/test_network_db.py +++ /dev/null @@ -1,309 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# 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 collections -import mock -import testtools - -from neutron.plugins.cisco.common import cisco_constants -from neutron.plugins.cisco.common import cisco_credentials_v2 -from neutron.plugins.cisco.common import cisco_exceptions as c_exc -from neutron.plugins.cisco.common import config as config -from neutron.plugins.cisco.db import network_db_v2 as cdb -from neutron.plugins.cisco import network_plugin -from neutron.tests.unit import testlib_api - - -class CiscoNetworkDbTest(testlib_api.SqlTestCase): - - """Base class for Cisco network database unit tests.""" - - def setUp(self): - super(CiscoNetworkDbTest, self).setUp() - - # The Cisco network plugin includes a thin layer of QoS and - # credential API methods which indirectly call Cisco QoS and - # credential database access methods. For better code coverage, - # this test suite will make calls to the QoS and credential database - # access methods indirectly through the network plugin. The network - # plugin's init function can be mocked out for this purpose. - def new_network_plugin_init(instance): - pass - with mock.patch.object(network_plugin.PluginV2, - '__init__', new=new_network_plugin_init): - self._network_plugin = network_plugin.PluginV2() - - -class CiscoNetworkQosDbTest(CiscoNetworkDbTest): - - """Unit tests for Cisco network QoS database model.""" - - QosObj = collections.namedtuple('QosObj', 'tenant qname desc') - - def _qos_test_obj(self, tnum, qnum, desc=None): - """Create a Qos test object from a pair of numbers.""" - if desc is None: - desc = 'test qos %s-%s' % (str(tnum), str(qnum)) - tenant = 'tenant_%s' % str(tnum) - qname = 'qos_%s' % str(qnum) - return self.QosObj(tenant, qname, desc) - - def _assert_equal(self, qos, qos_obj): - self.assertEqual(qos.tenant_id, qos_obj.tenant) - self.assertEqual(qos.qos_name, qos_obj.qname) - self.assertEqual(qos.qos_desc, qos_obj.desc) - - def test_qos_add_remove(self): - qos11 = self._qos_test_obj(1, 1) - qos = self._network_plugin.create_qos(qos11.tenant, qos11.qname, - qos11.desc) - self._assert_equal(qos, qos11) - qos_id = qos.qos_id - qos = self._network_plugin.delete_qos(qos11.tenant, qos_id) - self._assert_equal(qos, qos11) - qos = self._network_plugin.delete_qos(qos11.tenant, qos_id) - self.assertIsNone(qos) - - def test_qos_add_dup(self): - qos22 = self._qos_test_obj(2, 2) - qos = self._network_plugin.create_qos(qos22.tenant, qos22.qname, - qos22.desc) - self._assert_equal(qos, qos22) - qos_id = qos.qos_id - with testtools.ExpectedException(c_exc.QosNameAlreadyExists): - self._network_plugin.create_qos(qos22.tenant, qos22.qname, - "duplicate 22") - qos = self._network_plugin.delete_qos(qos22.tenant, qos_id) - self._assert_equal(qos, qos22) - qos = self._network_plugin.delete_qos(qos22.tenant, qos_id) - self.assertIsNone(qos) - - def test_qos_get(self): - qos11 = self._qos_test_obj(1, 1) - qos11_id = self._network_plugin.create_qos(qos11.tenant, qos11.qname, - qos11.desc).qos_id - qos21 = self._qos_test_obj(2, 1) - qos21_id = self._network_plugin.create_qos(qos21.tenant, qos21.qname, - qos21.desc).qos_id - qos22 = self._qos_test_obj(2, 2) - qos22_id = self._network_plugin.create_qos(qos22.tenant, qos22.qname, - qos22.desc).qos_id - - qos = self._network_plugin.get_qos_details(qos11.tenant, qos11_id) - self._assert_equal(qos, qos11) - qos = self._network_plugin.get_qos_details(qos21.tenant, qos21_id) - self._assert_equal(qos, qos21) - qos = self._network_plugin.get_qos_details(qos21.tenant, qos22_id) - self._assert_equal(qos, qos22) - - with testtools.ExpectedException(c_exc.QosNotFound): - self._network_plugin.get_qos_details(qos11.tenant, "dummyQosId") - with testtools.ExpectedException(c_exc.QosNotFound): - self._network_plugin.get_qos_details(qos11.tenant, qos21_id) - with testtools.ExpectedException(c_exc.QosNotFound): - self._network_plugin.get_qos_details(qos21.tenant, qos11_id) - - qos_all_t1 = self._network_plugin.get_all_qoss(qos11.tenant) - self.assertEqual(len(qos_all_t1), 1) - qos_all_t2 = self._network_plugin.get_all_qoss(qos21.tenant) - self.assertEqual(len(qos_all_t2), 2) - qos_all_t3 = self._network_plugin.get_all_qoss("tenant3") - self.assertEqual(len(qos_all_t3), 0) - - def test_qos_update(self): - qos11 = self._qos_test_obj(1, 1) - qos11_id = self._network_plugin.create_qos(qos11.tenant, qos11.qname, - qos11.desc).qos_id - self._network_plugin.rename_qos(qos11.tenant, qos11_id, - new_name=None) - new_qname = "new qos name" - new_qos = self._network_plugin.rename_qos(qos11.tenant, qos11_id, - new_qname) - expected_qobj = self.QosObj(qos11.tenant, new_qname, qos11.desc) - self._assert_equal(new_qos, expected_qobj) - new_qos = self._network_plugin.get_qos_details(qos11.tenant, qos11_id) - self._assert_equal(new_qos, expected_qobj) - with testtools.ExpectedException(c_exc.QosNotFound): - self._network_plugin.rename_qos(qos11.tenant, "dummyQosId", - new_name=None) - - -class CiscoNetworkCredentialDbTest(CiscoNetworkDbTest): - - """Unit tests for Cisco network credentials database model.""" - - CredObj = collections.namedtuple('CredObj', 'cname usr pwd ctype') - - def _cred_test_obj(self, tnum, cnum): - """Create a Credential test object from a pair of numbers.""" - cname = 'credential_%s_%s' % (str(tnum), str(cnum)) - usr = 'User_%s_%s' % (str(tnum), str(cnum)) - pwd = 'Password_%s_%s' % (str(tnum), str(cnum)) - ctype = 'ctype_%s' % str(tnum) - return self.CredObj(cname, usr, pwd, ctype) - - def _assert_equal(self, credential, cred_obj): - self.assertEqual(credential.type, cred_obj.ctype) - self.assertEqual(credential.credential_name, cred_obj.cname) - self.assertEqual(credential.user_name, cred_obj.usr) - self.assertEqual(credential.password, cred_obj.pwd) - - def test_credential_add_remove(self): - cred11 = self._cred_test_obj(1, 1) - cred = cdb.add_credential( - cred11.cname, cred11.usr, cred11.pwd, cred11.ctype) - self._assert_equal(cred, cred11) - cred_id = cred.credential_id - cred = cdb.remove_credential(cred_id) - self._assert_equal(cred, cred11) - cred = cdb.remove_credential(cred_id) - self.assertIsNone(cred) - - def test_credential_add_dup(self): - cred22 = self._cred_test_obj(2, 2) - cred = cdb.add_credential( - cred22.cname, cred22.usr, cred22.pwd, cred22.ctype) - self._assert_equal(cred, cred22) - cred_id = cred.credential_id - with testtools.ExpectedException(c_exc.CredentialAlreadyExists): - cdb.add_credential( - cred22.cname, cred22.usr, cred22.pwd, cred22.ctype) - cred = cdb.remove_credential(cred_id) - self._assert_equal(cred, cred22) - cred = cdb.remove_credential(cred_id) - self.assertIsNone(cred) - - def test_credential_get_id(self): - cred11 = self._cred_test_obj(1, 1) - cred11_id = cdb.add_credential( - cred11.cname, cred11.usr, cred11.pwd, cred11.ctype).credential_id - cred21 = self._cred_test_obj(2, 1) - cred21_id = cdb.add_credential( - cred21.cname, cred21.usr, cred21.pwd, cred21.ctype).credential_id - cred22 = self._cred_test_obj(2, 2) - cred22_id = cdb.add_credential( - cred22.cname, cred22.usr, cred22.pwd, cred22.ctype).credential_id - - cred = self._network_plugin.get_credential_details(cred11_id) - self._assert_equal(cred, cred11) - cred = self._network_plugin.get_credential_details(cred21_id) - self._assert_equal(cred, cred21) - cred = self._network_plugin.get_credential_details(cred22_id) - self._assert_equal(cred, cred22) - - with testtools.ExpectedException(c_exc.CredentialNotFound): - self._network_plugin.get_credential_details("dummyCredentialId") - - cred_all_t1 = self._network_plugin.get_all_credentials() - self.assertEqual(len(cred_all_t1), 3) - - def test_credential_get_name(self): - cred11 = self._cred_test_obj(1, 1) - cred11_id = cdb.add_credential( - cred11.cname, cred11.usr, cred11.pwd, cred11.ctype).credential_id - cred21 = self._cred_test_obj(2, 1) - cred21_id = cdb.add_credential( - cred21.cname, cred21.usr, cred21.pwd, cred21.ctype).credential_id - cred22 = self._cred_test_obj(2, 2) - cred22_id = cdb.add_credential( - cred22.cname, cred22.usr, cred22.pwd, cred22.ctype).credential_id - self.assertNotEqual(cred11_id, cred21_id) - self.assertNotEqual(cred11_id, cred22_id) - self.assertNotEqual(cred21_id, cred22_id) - - cred = cdb.get_credential_name(cred11.cname) - self._assert_equal(cred, cred11) - cred = cdb.get_credential_name(cred21.cname) - self._assert_equal(cred, cred21) - cred = cdb.get_credential_name(cred22.cname) - self._assert_equal(cred, cred22) - - with testtools.ExpectedException(c_exc.CredentialNameNotFound): - cdb.get_credential_name("dummyCredentialName") - - def test_credential_update(self): - cred11 = self._cred_test_obj(1, 1) - cred11_id = cdb.add_credential( - cred11.cname, cred11.usr, cred11.pwd, cred11.ctype).credential_id - self._network_plugin.rename_credential(cred11_id, new_name=None, - new_password=None) - new_usr = "new user name" - new_pwd = "new password" - new_credential = self._network_plugin.rename_credential( - cred11_id, new_usr, new_pwd) - expected_cred = self.CredObj( - cred11.cname, new_usr, new_pwd, cred11.ctype) - self._assert_equal(new_credential, expected_cred) - new_credential = self._network_plugin.get_credential_details( - cred11_id) - self._assert_equal(new_credential, expected_cred) - with testtools.ExpectedException(c_exc.CredentialNotFound): - self._network_plugin.rename_credential( - "dummyCredentialId", new_usr, new_pwd) - - def test_get_credential_not_found_exception(self): - self.assertRaises(c_exc.CredentialNotFound, - self._network_plugin.get_credential_details, - "dummyCredentialId") - - def test_credential_delete_all_n1kv(self): - cred_nexus_1 = self._cred_test_obj('nexus', 1) - cred_nexus_2 = self._cred_test_obj('nexus', 2) - cred_n1kv_1 = self.CredObj('n1kv-1', 'cisco', '123456', 'n1kv') - cred_n1kv_2 = self.CredObj('n1kv-2', 'cisco', '123456', 'n1kv') - cred_nexus_1_id = cdb.add_credential( - cred_nexus_1.cname, cred_nexus_1.usr, - cred_nexus_1.pwd, cred_nexus_1.ctype).credential_id - cred_nexus_2_id = cdb.add_credential( - cred_nexus_2.cname, cred_nexus_2.usr, - cred_nexus_2.pwd, cred_nexus_2.ctype).credential_id - cred_n1kv_1_id = cdb.add_credential( - cred_n1kv_1.cname, cred_n1kv_1.usr, - cred_n1kv_1.pwd, cred_n1kv_1.ctype).credential_id - cred_n1kv_2_id = cdb.add_credential( - cred_n1kv_2.cname, cred_n1kv_2.usr, - cred_n1kv_2.pwd, cred_n1kv_2.ctype).credential_id - cdb.delete_all_n1kv_credentials() - cred = cdb.get_credential(cred_nexus_1_id) - self.assertIsNotNone(cred) - cred = cdb.get_credential(cred_nexus_2_id) - self.assertIsNotNone(cred) - self.assertRaises(c_exc.CredentialNotFound, - cdb.get_credential, cred_n1kv_1_id) - self.assertRaises(c_exc.CredentialNotFound, - cdb.get_credential, cred_n1kv_2_id) - - -class CiscoCredentialStoreTest(testlib_api.SqlTestCase): - - """Cisco Credential Store unit tests.""" - - def test_cred_store_init_duplicate_creds_ignored(self): - """Check that with multi store instances, dup creds are ignored.""" - # Create a device dictionary containing credentials for 1 switch. - dev_dict = { - ('dev_id', '1.1.1.1', cisco_constants.USERNAME): 'user_1', - ('dev_id', '1.1.1.1', cisco_constants.PASSWORD): 'password_1', - ('dev_id', '1.1.1.1', 'host_a'): '1/1', - ('dev_id', '1.1.1.1', 'host_b'): '1/2', - ('dev_id', '1.1.1.1', 'host_c'): '1/3', - } - with mock.patch.object(config, 'get_device_dictionary', - return_value=dev_dict): - # Create and initialize 2 instances of credential store. - cisco_credentials_v2.Store().initialize() - cisco_credentials_v2.Store().initialize() - # There should be only 1 switch credential in the database. - self.assertEqual(len(cdb.get_all_credentials()), 1) diff --git a/setup.cfg b/setup.cfg index 5f3de4db1..6015ced5a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -52,7 +52,6 @@ data_files = etc/neutron/plugins/brocade/vyatta = etc/neutron/plugins/brocade/vyatta/vrouter.ini etc/neutron/plugins/cisco = etc/neutron/plugins/cisco/cisco_cfg_agent.ini - etc/neutron/plugins/cisco/cisco_plugins.ini etc/neutron/plugins/cisco/cisco_router_plugin.ini etc/neutron/plugins/cisco/cisco_vpn_agent.ini etc/neutron/plugins/embrane = etc/neutron/plugins/embrane/heleos_conf.ini @@ -105,7 +104,6 @@ console_scripts = neutron.core_plugins = bigswitch = neutron.plugins.bigswitch.plugin:NeutronRestProxyV2 brocade = neutron.plugins.brocade.NeutronPlugin:BrocadePluginV2 - cisco = neutron.plugins.cisco.network_plugin:PluginV2 embrane = neutron.plugins.embrane.plugins.embrane_ml2_plugin:EmbraneMl2Plugin midonet = neutron.plugins.midonet.plugin:MidonetPluginV2 ml2 = neutron.plugins.ml2.plugin:Ml2Plugin