diff --git a/vmware_nsx_tempest_plugin/lib/appliance_manager.py b/vmware_nsx_tempest_plugin/lib/appliance_manager.py index 7a39a0b..d3d1008 100644 --- a/vmware_nsx_tempest_plugin/lib/appliance_manager.py +++ b/vmware_nsx_tempest_plugin/lib/appliance_manager.py @@ -409,6 +409,21 @@ class ApplianceManager(manager.NetworkScenarioTest): "No IPv4 addresses found in: %s" % ports) return port_map + def add_router_interface( + self, + router_id, + subnet_id, + router_client=None): + if router_client is None: + router_client = self.routers_client + interface = router_client.add_router_interface(router_id, + subnet_id=subnet_id) + self.addCleanup( + test_utils.call_and_ignore_notfound_exc, + router_client.remove_router_interface, router_id, + subnet_id=subnet_id) + return interface + def remove_router_interface( self, router_id, diff --git a/vmware_nsx_tempest_plugin/tests/nsxv3/api/test_nsx_ipv6_external_network.py b/vmware_nsx_tempest_plugin/tests/nsxv3/api/test_nsx_ipv6_external_network.py index ede1467..c4e91b6 100644 --- a/vmware_nsx_tempest_plugin/tests/nsxv3/api/test_nsx_ipv6_external_network.py +++ b/vmware_nsx_tempest_plugin/tests/nsxv3/api/test_nsx_ipv6_external_network.py @@ -13,7 +13,6 @@ from tempest import config from tempest.lib import decorators -from tempest.lib import exceptions as lib_exc from vmware_nsx_tempest_plugin.lib import feature_manager CONF = config.CONF @@ -88,7 +87,7 @@ class IPv6ExternalNetworksTest(feature_manager.FeatureManager): def test_create_ipv6_external_gateway_snat(self): """ Test create IPv6 external network - Verify the router can not be configured with IPv6 gateway with SNAT + Verify the router can be configured with IPv6 gateway with SNAT """ name = "ipv6-ext-network" networks_client = self.cmgr_adm.networks_client @@ -108,9 +107,16 @@ class IPv6ExternalNetworksTest(feature_manager.FeatureManager): cidr="2000:20:20::/64", **allocation_pools) #Create a router and set gateway to an IPv6 external network - self.assertRaises(lib_exc.BadRequest, - self.create_topology_router, - router_name="ipv6-rtr", - routers_client=self.cmgr_adm.routers_client, - set_gateway=True, enable_snat=True, - ext_netid=ext_network['id']) + router = self.create_topology_router( + "ipv6-rtr", routers_client=self.cmgr_adm.routers_client, + set_gateway=True, enable_snat=True, + ext_netid=ext_network['id']) + show_body = self.show_topology_router(router['id'], + routers_client=self.cmgr_adm.routers_client) + self.assertEqual(show_body['router']['id'], router['id']) + self.assertEqual( + show_body['router']['external_gateway_info']['enable_snat'], + True) + self.assertEqual( + show_body['router']['external_gateway_info']['network_id'], + ext_network['id']) diff --git a/vmware_nsx_tempest_plugin/tests/nsxv3/scenario/test_ipv6_router.py b/vmware_nsx_tempest_plugin/tests/nsxv3/scenario/test_ipv6_router.py new file mode 100644 index 0000000..8d6c25a --- /dev/null +++ b/vmware_nsx_tempest_plugin/tests/nsxv3/scenario/test_ipv6_router.py @@ -0,0 +1,216 @@ +# 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 tempest import config +from tempest.lib.common.utils import data_utils +from tempest.lib import decorators +from tempest.lib import exceptions + +from vmware_nsx_tempest_plugin.lib import feature_manager +CONF = config.CONF + + +class IPv6RoutersTest(feature_manager.FeatureManager): + """Test the following operations for ports: + port create + port delete + port list + port show + port update + """ + + @classmethod + def skip_checks(cls): + super(IPv6RoutersTest, cls).skip_checks() + if not (CONF.network_feature_enabled.ipv6 and + CONF.network_feature_enabled.ipv6_subnet_attributes): + raise cls.skipException('IPv6 or its attributes not supported') + if not (CONF.network.project_networks_reachable or + CONF.network.public_network_id): + msg = ('Either project_networks_reachable must be "true", or ' + 'public_network_id must be defined.') + raise cls.skipException(msg) + + @classmethod + def setup_clients(cls): + super(IPv6RoutersTest, cls).setup_clients() + cls.cmgr_adm = cls.get_client_manager('admin') + + @classmethod + def resource_setup(cls): + super(IPv6RoutersTest, cls).resource_setup() + + def _create_ipv6_subnet(self, network, slaac=False): + subnet_client = self.cmgr_adm.subnets_client + subnet_name = network['name'] + 'sub' + address_cidr = CONF.network.project_network_v6_cidr + address_prefixlen = CONF.network.project_network_v6_mask_bits + if ((address_prefixlen >= 126)): + msg = ("Subnet %s isn't large enough for the test" % address_cidr) + raise exceptions.InvalidConfiguration(msg) + allocation_pools = {'allocation_pools': [{ + 'start': str(address_cidr).split('/')[0] + '2', + 'end':str(address_cidr).split('/')[0] + '70'}]} + if slaac: + subnet = self.create_topology_subnet(subnet_name, network, + subnets_client=subnet_client, + ip_version=6, ipv6_ra_mode='slaac', + ipv6_address_mode='slaac', + **allocation_pools) + else: + subnet = self.create_topology_subnet(subnet_name, network, + subnets_client=subnet_client, + ip_version=6, enable_dhcp=False, + **allocation_pools) + return subnet + + @decorators.attr(type=['nsxv3', 'positive']) + @decorators.idempotent_id('6526db57-c523-4879-b8ae-f50f0190f960') + def test_single_ipv6_downlink_interface_rtr(self): + """Test creating single ipv6 static subnet attached + to router downlink interface + """ + name = data_utils.rand_name("ipv6-net") + networks_client = self.cmgr_adm.networks_client + network = self.create_topology_network(name, + networks_client=networks_client) + subnet = self._create_ipv6_subnet(network) + rtr_name = data_utils.rand_name("ipv6-rtr") + router = self.create_topology_router( + rtr_name, routers_client=self.cmgr_adm.routers_client) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet['id']) + self.assertEqual(subnet['id'], interface['subnet_id']) + + @decorators.attr(type=['nsxv3', 'positive']) + @decorators.idempotent_id('6cbd1f61-8d63-4d81-a8ba-f0f0624d4585') + def test_ipv4_ipv6_downlink_interface_rtr(self): + """Test creating ipv4 and ipv6 static subnets attached + to router downlink interface + """ + name = data_utils.rand_name("ipv6-net") + networks_client = self.cmgr_adm.networks_client + network = self.create_topology_network(name, + networks_client=networks_client) + subnet_client = self.cmgr_adm.subnets_client + subnet_name = network['name'] + 'ipv4-sub' + subnet_ipv4 = self.create_topology_subnet(subnet_name, network, + subnets_client=subnet_client, + cidr='20.20.0.0/16') + subnet = self._create_ipv6_subnet(network) + rtr_name = data_utils.rand_name("ipv6-rtr") + router = self.create_topology_router( + rtr_name, routers_client=self.cmgr_adm.routers_client) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet_ipv4['id']) + self.assertEqual(subnet_ipv4['id'], interface['subnet_id']) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet['id']) + self.assertEqual(subnet['id'], interface['subnet_id']) + + @decorators.attr(type=['nsxv3', 'positive']) + @decorators.idempotent_id('6a228287-25d2-41b3-aa7d-f6e566b9c8a3') + def test_slaac_single_ipv6_downlink_interface_rtr(self): + """Test creating single ipv6 static subnet attached + to router downlink interface + """ + name = data_utils.rand_name("ipv6-net") + networks_client = self.cmgr_adm.networks_client + network = self.create_topology_network(name, + networks_client=networks_client) + subnet = self._create_ipv6_subnet(network, slaac=True) + rtr_name = data_utils.rand_name("ipv6-rtr") + router = self.create_topology_router( + rtr_name, routers_client=self.cmgr_adm.routers_client) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet['id']) + self.assertEqual(subnet['id'], interface['subnet_id']) + + @decorators.attr(type=['nsxv3', 'positive']) + @decorators.idempotent_id('8e7b1e28-e50e-458e-beb4-49ce5663c561') + def test_slaac_ipv4_ipv6_downlink_interface_rtr(self): + """Test creating ipv4 and ipv6 slaac subnets attached + to router downlink interface + """ + name = data_utils.rand_name("ipv6-net") + networks_client = self.cmgr_adm.networks_client + network = self.create_topology_network(name, + networks_client=networks_client) + subnet_client = self.cmgr_adm.subnets_client + subnet_name = network['name'] + 'ipv4-sub' + subnet_ipv4 = self.create_topology_subnet(subnet_name, network, + subnets_client=subnet_client, + cidr='20.20.0.0/16') + subnet = self._create_ipv6_subnet(network, slaac=True) + rtr_name = data_utils.rand_name("ipv6-rtr") + router = self.create_topology_router( + rtr_name, routers_client=self.cmgr_adm.routers_client) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet_ipv4['id']) + self.assertEqual(subnet_ipv4['id'], interface['subnet_id']) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet['id']) + self.assertEqual(subnet['id'], interface['subnet_id']) + + @decorators.attr(type=['nsxv3', 'positive']) + @decorators.idempotent_id('85235d0f-89b5-48a0-a3ee-d1bd21be6b94') + def test_slaac_multiple_ipv6_downlink_interface_rtr(self): + """Test creating multiple ipv6 slaac subnets attached + to router downlink interface + """ + name = data_utils.rand_name("ipv6-net") + networks_client = self.cmgr_adm.networks_client + network = self.create_topology_network(name, + networks_client=networks_client) + subnet = self._create_ipv6_subnet(network, slaac=True) + subnet_1 = self._create_ipv6_subnet(network, slaac=True) + rtr_name = data_utils.rand_name("ipv6-rtr") + router = self.create_topology_router( + rtr_name, routers_client=self.cmgr_adm.routers_client) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet['id']) + self.assertEqual(subnet['id'], interface['subnet_id']) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet_1['id']) + self.assertEqual(subnet_1['id'], interface['subnet_id']) + + @decorators.attr(type=['nsxv3', 'positive']) + @decorators.idempotent_id('3564b971-6033-43cc-a13a-93b467bca50d') + def test_multiple_ipv6_downlink_interface_rtr(self): + """Test creating multiple ipv6 slaac subnets attached + to router downlink interface + """ + name = data_utils.rand_name("ipv6-net") + networks_client = self.cmgr_adm.networks_client + network = self.create_topology_network(name, + networks_client=networks_client) + subnet = self._create_ipv6_subnet(network) + subnet_1 = self._create_ipv6_subnet(network) + rtr_name = data_utils.rand_name("ipv6-rtr") + router = self.create_topology_router( + rtr_name, routers_client=self.cmgr_adm.routers_client) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet['id']) + self.assertEqual(subnet['id'], interface['subnet_id']) + interface = self.add_router_interface( + router_client=self.cmgr_adm.routers_client, + router_id=router['id'], subnet_id=subnet_1['id']) + self.assertEqual(subnet_1['id'], interface['subnet_id'])