+++ /dev/null
-[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:<IP address of VSM>]
-# username=<credential username>
-# password=<credential 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
-11926bcfe72d
34af2b5c5a59
+4af11ca47297
--- /dev/null
+# 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')
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
+++ /dev/null
-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
# 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
# ==================================
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'
+++ /dev/null
-# 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]
+++ /dev/null
-# 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.")
+++ /dev/null
-# 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.')
+++ /dev/null
-# 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:
-# {('<device ID>', '<device ipaddr>', '<keyword>'): '<value>', ...}
-#
-# 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
+++ /dev/null
-# 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)
+++ /dev/null
-# 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 - '<integer>-<integer>'
- multicast_ip_index - <integer>
- multicast_ip_range - '<ip>-<ip>'
- 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))
+++ /dev/null
-# 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)
+++ /dev/null
-# 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)
+++ /dev/null
-# 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']))
+++ /dev/null
-# 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']))
+++ /dev/null
-# 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)]
+++ /dev/null
-# 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 <tenant-id> <net-name> \
- --n1kv:profile_id <id>
- (shell) port-create --tenant_id <tenant-id> <net-name> \
- --n1kv:profile_id <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 {}
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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))
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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)
+++ /dev/null
-# 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
+++ /dev/null
-# 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)
+++ /dev/null
-# 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 = ["""<?xml version="1.0" encoding="utf-8"?>
- <set name="virtual_port_profile_set">"""]
- template = (
- '<instance name="%(num)d"'
- ' url="/api/n1k/virtual-port-profile/%(num)s">'
- '<properties>'
- '<id>00000000-0000-0000-0000-00000000000%(num)s</id>'
- '<name>pp-%(num)s</name>'
- '</properties>'
- '</instance>'
- )
- xml.extend(template % {'num': n} for n in range(1, total_profiles + 1))
- xml.append("</set>")
- return ''.join(xml)
+++ /dev/null
-# 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)
+++ /dev/null
-# 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
+++ /dev/null
-# 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)
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
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