From e5fe9d6e4302b9df3ebbfcaecf9f2f9d03dfd4f1 Mon Sep 17 00:00:00 2001 From: Abhishek Raut Date: Thu, 19 Nov 2015 17:46:57 -0800 Subject: [PATCH] [NSXv]: Add support for multiple transport zones Currently, there is no support in the NSX-V plugin to create a network on a specified transport zone. One transport zone is configured in the nsx.ini file and all networks are created on this transport zone. This commit adds the ability to specify a transport zone ID during network create operation using providernet APIs. Admin can now create a provider network of type VXLAN and specify the transport zone ID in the physical network attribute. Eg. CLI: neutron net-create vxlan-net --provider:network_type=vxlan --provider:physical_network=vdn-scope-1 If no transport zone ID is specified in physical_network attribute, the default value for transport zone ID will be picked up from nsx.ini This change also splits the HEADS file in database migrations into EXPAND and CONTRACT HEAD files. This reduces the chances of merge conflicts. A new migration script is generated to update binding type in NsxvTzNetworkBinding table to accept vxlan as a valid provider network type. Change-Id: I388c83c044f114755a5a3bcbca1381d64aaa14d5 --- .../versions/{HEADS => CONTRACT_HEAD} | 1 - .../alembic_migrations/versions/EXPAND_HEAD | 1 + ...af850eb3970_update_nsxv_tz_binding_type.py | 43 +++++++++++++++++++ vmware_nsx/db/nsxv_models.py | 2 +- vmware_nsx/plugins/nsx_v/plugin.py | 13 +++++- vmware_nsx/tests/unit/nsx_v/test_plugin.py | 15 +++++++ 6 files changed, 72 insertions(+), 3 deletions(-) rename vmware_nsx/db/migration/alembic_migrations/versions/{HEADS => CONTRACT_HEAD} (50%) create mode 100644 vmware_nsx/db/migration/alembic_migrations/versions/EXPAND_HEAD create mode 100644 vmware_nsx/db/migration/alembic_migrations/versions/mitaka/expand/2af850eb3970_update_nsxv_tz_binding_type.py diff --git a/vmware_nsx/db/migration/alembic_migrations/versions/HEADS b/vmware_nsx/db/migration/alembic_migrations/versions/CONTRACT_HEAD similarity index 50% rename from vmware_nsx/db/migration/alembic_migrations/versions/HEADS rename to vmware_nsx/db/migration/alembic_migrations/versions/CONTRACT_HEAD index c641378f6c..fe3e739804 100644 --- a/vmware_nsx/db/migration/alembic_migrations/versions/HEADS +++ b/vmware_nsx/db/migration/alembic_migrations/versions/CONTRACT_HEAD @@ -1,2 +1 @@ -312211a5725f 3c88bdea3054 diff --git a/vmware_nsx/db/migration/alembic_migrations/versions/EXPAND_HEAD b/vmware_nsx/db/migration/alembic_migrations/versions/EXPAND_HEAD new file mode 100644 index 0000000000..74adfb566d --- /dev/null +++ b/vmware_nsx/db/migration/alembic_migrations/versions/EXPAND_HEAD @@ -0,0 +1 @@ +2af850eb3970 diff --git a/vmware_nsx/db/migration/alembic_migrations/versions/mitaka/expand/2af850eb3970_update_nsxv_tz_binding_type.py b/vmware_nsx/db/migration/alembic_migrations/versions/mitaka/expand/2af850eb3970_update_nsxv_tz_binding_type.py new file mode 100644 index 0000000000..f9eee40136 --- /dev/null +++ b/vmware_nsx/db/migration/alembic_migrations/versions/mitaka/expand/2af850eb3970_update_nsxv_tz_binding_type.py @@ -0,0 +1,43 @@ +# Copyright 2015 VMware, 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. + +"""update nsxv tz binding type + +Revision ID: 2af850eb3970 +Revises: 312211a5725f +Create Date: 2015-11-24 13:44:08.664653 + +""" + +# revision identifiers, used by Alembic. +revision = '2af850eb3970' +down_revision = '312211a5725f' + +from alembic import op +import sqlalchemy as sa + + +tz_binding_type_enum = sa.Enum('flat', 'vlan', 'portgroup', + name='nsxv_tz_network_bindings_binding_type') +new_tz_binding_type_enum = sa.Enum( + 'flat', 'vlan', 'portgroup', 'vxlan', + name='nsxv_tz_network_bindings_binding_type') + + +def upgrade(): + op.alter_column( + 'nsxv_tz_network_bindings', + 'binding_type', + type_=new_tz_binding_type_enum, + existing_type=tz_binding_type_enum) diff --git a/vmware_nsx/db/nsxv_models.py b/vmware_nsx/db/nsxv_models.py index be3251237d..07e83ffced 100644 --- a/vmware_nsx/db/nsxv_models.py +++ b/vmware_nsx/db/nsxv_models.py @@ -177,7 +177,7 @@ class NsxvTzNetworkBinding(model_base.BASEV2): sa.ForeignKey('networks.id', ondelete="CASCADE"), primary_key=True) binding_type = sa.Column( - sa.Enum('flat', 'vlan', 'portgroup', + sa.Enum('flat', 'vlan', 'portgroup', 'vxlan', name='nsxv_tz_network_bindings_binding_type'), nullable=False, primary_key=True) phy_uuid = sa.Column(sa.String(36), primary_key=True, nullable=True) diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py index 88864ba0ae..37cda02e7e 100644 --- a/vmware_nsx/plugins/nsx_v/plugin.py +++ b/vmware_nsx/plugins/nsx_v/plugin.py @@ -572,6 +572,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, attr.is_attr_set(external) and not external) if backend_network: network_type = None + #NOTE(abhiraut): Consider refactoring code below to have more + # readable conditions. if provider_type is not None: segment = net_data[mpnet.SEGMENTS][0] network_type = segment.get(pnet.NETWORK_TYPE) @@ -581,7 +583,16 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, virtual_wire = {"name": net_data['id'], "tenantId": "virtual wire tenant"} config_spec = {"virtualWireCreateSpec": virtual_wire} - h, c = self.nsx_v.vcns.create_virtual_wire(self.vdn_scope_id, + vdn_scope_id = self.vdn_scope_id + if provider_type is not None: + segment = net_data[mpnet.SEGMENTS][0] + if attr.is_attr_set(segment.get(pnet.PHYSICAL_NETWORK)): + vdn_scope_id = segment.get(pnet.PHYSICAL_NETWORK) + if not (self.nsx_v.vcns. + validate_vdn_scope(vdn_scope_id)): + error = _("Configured vdn_scope_id not found") + raise nsx_exc.NsxPluginException(err_msg=error) + h, c = self.nsx_v.vcns.create_virtual_wire(vdn_scope_id, config_spec) net_moref = c elif network_type == c_utils.NsxVNetworkTypes.PORTGROUP: diff --git a/vmware_nsx/tests/unit/nsx_v/test_plugin.py b/vmware_nsx/tests/unit/nsx_v/test_plugin.py index b2760578e9..20bd5f5b12 100644 --- a/vmware_nsx/tests/unit/nsx_v/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v/test_plugin.py @@ -299,6 +299,21 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase): for k, v in expected_same_vlan: self.assertEqual(net1['network'][k], v) + def test_create_vxlan_with_tz_provider_network(self): + name = 'provider_net_vxlan' + expected = [('subnets', []), ('name', name), ('admin_state_up', True), + ('status', 'ACTIVE'), ('shared', False), + (pnet.NETWORK_TYPE, 'vxlan'), + (pnet.PHYSICAL_NETWORK, 'vdnscope-2')] + providernet_args = {pnet.NETWORK_TYPE: 'vxlan', + pnet.PHYSICAL_NETWORK: 'vdnscope-2'} + with self.network(name=name, + providernet_args=providernet_args, + arg_list=(pnet.NETWORK_TYPE, + pnet.PHYSICAL_NETWORK)) as net: + for k, v in expected: + self.assertEqual(net['network'][k], v) + class TestVnicIndex(NsxVPluginV2TestCase, test_vnic_index.VnicIndexDbTestCase):