class UnicodeUserDataTest(NuageBaseTest): @classmethod def skip_checks(cls): super(UnicodeUserDataTest, cls).skip_checks() if six.PY2: raise cls.skipException('Test skipped under python 2') if not CONF.compute_feature_enabled.metadata_service: raise cls.skipException('Test requires functional metadata agent') def _test_unicode_userdata(self, l3=None, ip_versions=None): # Verifying that nuage-metadata-agent correctly passes userdata # Provision OpenStack network resources network = self.create_network() router = self.create_router( external_network_id=CONF.network.public_network_id) if l3 else None for ip_version in ip_versions: subnet = self.create_subnet( network, ip_version=ip_version, mask_bits=24 if ip_version == 4 else 64, enable_dhcp=True) if router: self.router_attach(router, subnet) security_group = self.create_open_ssh_security_group() user_data = (u'\u0445\u0440\u0435\u043d-\u0441-' u'\u0440\u0443\u0447\u043a\u043e\u0439') server1 = self.create_tenant_server(networks=[network], security_groups=[security_group], user_data=user_data, prepare_for_connectivity=True) server1.verify_userdata(user_data) def test_unicode_userdata_l3_v4(self): self._test_unicode_userdata(l3=True, ip_versions=[4]) def test_unicode_userdata_l2_v4(self): self._test_unicode_userdata(l3=False, ip_versions=[4]) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') def test_unicode_userdata_l3_v6(self): self._test_unicode_userdata(l3=True, ip_versions=[6]) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') def test_unicode_userdata_l2_v6(self): self._test_unicode_userdata(l3=False, ip_versions=[6]) def test_unicode_userdata_l3_dualstack(self): self._test_unicode_userdata(l3=True, ip_versions=[6, 4]) def test_unicode_userdata_l2_dualstack(self): self._test_unicode_userdata(l3=False, ip_versions=[6, 4])
def test_multiple_ipv6_subnets_neg(self): # Provision OpenStack network network = self.create_network() # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) if Topology.has_single_stack_v6_support(): ipv6_subnet = self.create_subnet( network, cidr=IPNetwork("2fbe:4568:a:b::/64"), mask_bits=64, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) else: # When I add an a second IPv6 subnet, it should fail self.assertRaisesRegex( tempest_exceptions.BadRequest, "A network with an ipv6 subnet may only have maximum " "1 ipv4 and 1 ipv6 subnet", self.create_subnet, network, cidr=IPNetwork("2fbe:4568:a:b::/64"), mask_bits=64, ip_version=6, enable_dhcp=False)
class VSDManagedIPv6L2DomainDHCPManagedTest(BaseVSDManagedNetworksIPv6Test): dhcp_managed = True @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') @decorators.attr(type='smoke') def test_create_vsd_managed_ipv6_l2domain_with_ipv4_cidr_neg(self): vsd_l2domain_template = self.vsd_create_l2domain_template( dhcp_managed=True, ip_type="IPV6", cidr6=self.cidr6) self._verify_vsd_l2domain_template(vsd_l2domain_template, dhcp_managed=self.dhcp_managed, ip_type='IPV6', cidr6=self.cidr6) vsd_l2domain = self.vsd_create_l2domain(template=vsd_l2domain_template) self._verify_vsd_l2domain_with_template(vsd_l2domain, vsd_l2domain_template) # create OpenStack network net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) msg = ("Subnet with ip_version %(ip_version)s can't be linked to vsd " "subnet with IPType %(ip_type)s.") % { 'ip_version': 4, 'ip_type': vsd_l2domain.ip_type } kwargs = { 'cidr': self.cidr4, 'enable_dhcp': self.dhcp_managed, 'nuagenet': vsd_l2domain.id, 'net_partition': self.net_partition } self.assertRaisesRegex(exceptions.BadRequest, msg, self.create_subnet, network, **kwargs)
def test_os_managed_dual_stack_create_ipv6_only_port_neg(self): network = self.create_network() ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) if Topology.has_single_stack_v6_support(): port1 = self.create_port(network) self._verify_port(port1, subnet4=None, subnet6=ipv6_subnet) port_ip = IPAddress(port1['fixed_ips'][0]['ip_address']) port_args = { 'fixed_ips': [{ 'ip_address': port_ip + 10 }, { 'ip_address': port_ip + 11 }] } port2 = self.create_port(network, **port_args) self._verify_port(port2, subnet4=None, subnet6=ipv6_subnet) else: self.assertRaisesRegex( tempest_exceptions.BadRequest, "Port can't be a pure ipv6 port. Need ipv4 fixed ip.", self.create_port, network)
class VSDManagedIPv6SubnetL3Test(BaseVSDManagedNetworksIPv6Test): dhcp_managed = True @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') @decorators.attr(type='smoke') def test_create_vsd_managed_ipv6_subnet_with_ipv4_cidr_neg(self): name = data_utils.rand_name('l3domain-') vsd_l3domain_template = self.vsd_create_l3domain_template( name=name) vsd_l3domain = self.vsd_create_l3domain( name=name, template_id=vsd_l3domain_template.id) self.assertEqual(vsd_l3domain.name, name) zone_name = data_utils.rand_name('zone-') vsd_zone = self.vsd_create_zone(name=zone_name, domain=vsd_l3domain) subnet_name = data_utils.rand_name('l3domain-subnet-') subnet_ipv6_cidr = IPNetwork("2001:5f74:c4a5:b82e::/64") subnet_ipv6_gateway = str(IPAddress(subnet_ipv6_cidr) + 1) vsd_l3domain_subnet = self.create_vsd_subnet( name=subnet_name, zone=vsd_zone, ip_type="IPV6", cidr6=subnet_ipv6_cidr, gateway6=subnet_ipv6_gateway) # create OpenStack network net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) msg = ("Subnet with ip_version %(ip_version)s can't be linked to vsd " "subnet with IPType %(ip_type)s.") % { 'ip_version': 4, 'ip_type': vsd_l3domain_subnet.ip_type} kwargs = { 'cidr': self.cidr4, 'enable_dhcp': self.dhcp_managed, 'nuagenet': vsd_l3domain_subnet.id, 'net_partition': self.net_partition } self.assertRaisesRegex(exceptions.BadRequest, msg, self.create_subnet, network, **kwargs)
def _build_net_topology(self, router=None): network = self.create_network(manager=self.admin_manager) gateway_mac_address = None # Creates either single stack IPv4 / IPv6 or dualstack networks for ip_version in self.ip_versions: subnet = self.create_subnet(network, cidr=utils.gimme_a_cidr(ip_version), ip_version=ip_version, manager=self.admin_manager) # pre-6.0 i.e. no SS v6 support yet, do the below for v4 only: if router and (Topology.has_single_stack_v6_support() or ip_version == 4): self.router_attach(router, subnet, manager=self.admin_manager) vspk_subnet = self.vsd.get_subnet(by_subnet=subnet) # gateway mac is the same for IPv4/6 in dualstack network gateway_mac_address = vspk_subnet.gateway_mac_address return network, gateway_mac_address
def _verify_ipv6_subnet_with_vsd_l2_domain(self, subnet, by_subnet): """_verify_ipv6_subnet_with_vsd_l2_domain Verifies the VSD l2 domain defined by 'by_subnet' with the openstack subnet 'subnet'. @param by_subnet: the subnet via which the l2 domain will be retrieved @param subnet: the subnet to compare the L2 domain with """ vsd_l2_domain = self.vsd.get_l2domain(by_subnet=by_subnet) self.assertIsNotNone(vsd_l2_domain) self.assertIsNone(subnet['ipv6_ra_mode']) self.assertIsNone(subnet['ipv6_address_mode']) if Topology.has_single_stack_v6_support(): self.assertEqual('DUALSTACK', vsd_l2_domain.ip_type) self.assertEqual(subnet['cidr'], vsd_l2_domain.ipv6_address) self.assertEqual(subnet['enable_dhcp'], vsd_l2_domain.enable_dhcpv6) else: if subnet['enable_dhcp'] or by_subnet['enable_dhcp']: self.assertEqual('DUALSTACK', vsd_l2_domain.ip_type) self.assertEqual(subnet['cidr'], vsd_l2_domain.ipv6_address) else: self.assertIsNone(vsd_l2_domain.ip_type) self.assertIsNone(vsd_l2_domain.ipv6_address) if subnet['enable_dhcp']: filters = { 'device_owner': 'network:dhcp:nuage', 'network_id': subnet['network_id'] } dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(1, len(dhcp_ports)) for fixed_ip in dhcp_ports[0]['fixed_ips']: if fixed_ip['subnet_id'] == subnet['id']: self.assertEqual(fixed_ip['ip_address'], vsd_l2_domain.ipv6_gateway) elif Topology.is_v5: self.assertEqual(subnet['enable_dhcp'] or by_subnet['enable_dhcp'], vsd_l2_domain.dhcp_managed) else: self.assertTrue(vsd_l2_domain.dhcp_managed) self.assertIsNone(vsd_l2_domain.ipv6_gateway) self.assertFalse(subnet['vsd_managed'])
def _test_os_managed_subnet_ipv4_first(self, enable_dhcp=None): # Provision OpenStack network network = self.create_network() # Create an IPv4 subnet ipv4_subnet = self.create_subnet(network, ip_version=4, enable_dhcp=enable_dhcp, cleanup=False) # Verify L2Dom vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) self.assertIsNotNone(vsd_l2_domain) if enable_dhcp: self.assertEqual(vsd_l2_domain.ip_type, 'IPV4') # Verify port/Vport portv4 = self.create_port(network, cleanup=False) self._verify_port(portv4, subnet4=ipv4_subnet) self._verify_vport_in_l2_domain(portv4, vsd_l2_domain) # Create an IPv6 subnet in the same network ipv6_subnet = self.create_subnet(network, enable_dhcp=enable_dhcp, ip_version=6) # Verify the L2Dom is Dualstack now vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) self.assertIsNotNone(vsd_l2_domain) if enable_dhcp: self.assertEqual(vsd_l2_domain.ip_type, 'DUALSTACK') # Delete v4 Subnet/Port self.delete_port(portv4) self.delete_subnet(ipv4_subnet) vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv6_subnet) # Verify the L2Dom if Topology.has_single_stack_v6_support(): self.assertIsNotNone(vsd_l2_domain) if enable_dhcp: self.assertEqual(vsd_l2_domain.ip_type, 'IPV6') else: self.assertIsNone(vsd_l2_domain)
def skip_checks(cls): super(OsManagedSingleStackV6L2SubnetsTest, cls).skip_checks() if not Topology.has_single_stack_v6_support(): msg = 'There is no single-stack v6 support in current release' raise cls.skipException(msg)
def skip_checks(cls): super(Ipv6L3VsdManagedConnectivityTest, cls).skip_checks() if not Topology.has_single_stack_v6_support(): msg = 'There is no single-stack v6 support in current release' raise cls.skipException(msg)
class Ipv6L2VsdManagedConnectivityTest(NuageBaseTest): default_prepare_for_connectivity = True def _test_icmp_connectivity_l2_vsd_managed_pure_v6(self, stateful): # Provision VSD managed network resources l2domain_template = self.vsd_create_l2domain_template( ip_type="IPV6", cidr6=self.cidr6, gateway6=self.gateway6, enable_dhcpv6=True) vsd_l2domain = self.vsd_create_l2domain(template=l2domain_template) self.vsd.define_any_to_any_acl(vsd_l2domain, allow_ipv6=True, stateful=stateful) # Provision OpenStack network linked to VSD network resources network = self.create_network() self.create_l2_vsd_managed_subnet( network, vsd_l2domain, ip_version=6, dhcp_managed=True) # Launch tenant servers in OpenStack network server2 = self.create_tenant_server( [network]) server1 = self.create_tenant_server( [network], prepare_for_connectivity=True) # Test IPv6 connectivity between peer servers self.assert_ping(server1, server2, network, ip_version=6) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'No singe-stack v6 supported') def test_icmp_connectivity_stateful_acl_l2_vsd_managed_pure_v6(self): self._test_icmp_connectivity_l2_vsd_managed_pure_v6(stateful=True) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'No singe-stack v6 supported') def test_icmp_connectivity_stateless_acl_l2_vsd_managed_pure_v6(self): self._test_icmp_connectivity_l2_vsd_managed_pure_v6(stateful=False) def test_icmp_connectivity_l2_vsd_managed_dualstack(self): # Provision VSD managed network resources l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", cidr4=self.cidr4, gateway4=self.gateway4, cidr6=self.cidr6, gateway6=self.gateway6, enable_dhcpv6=True) vsd_l2domain = self.vsd_create_l2domain(template=l2domain_template) self.vsd.define_any_to_any_acl(vsd_l2domain, allow_ipv6=True) # Provision OpenStack network linked to VSD network resources network = self.create_network() self.create_l2_vsd_managed_subnet(network, vsd_l2domain) self.create_l2_vsd_managed_subnet( network, vsd_l2domain, ip_version=6, dhcp_managed=True) # Launch tenant servers in OpenStack network server2 = self.create_tenant_server( [network], prepare_for_connectivity=True) server1 = self.create_tenant_server( [network], prepare_for_connectivity=True) # Test IPv4 connectivity between peer servers self.assert_ping(server1, server2, network) # Test IPv6 connectivity between peer servers self.assert_ping(server1, server2, network, ip_version=6)
class UnicodeUserDataTest(NuageBaseTest): @classmethod def skip_checks(cls): super(UnicodeUserDataTest, cls).skip_checks() if not CONF.compute_feature_enabled.metadata_service: raise cls.skipException('Test requires functional metadata agent') def _test_unicode_userdata(self, l3=None, ip_versions=None): # Verifying that nuage-metadata-agent can handle user-data with # unicode. # Provision OpenStack network resources network = self.create_network() for ip_version in ip_versions: subnet = self.create_subnet( network, ip_version=ip_version, mask_bits=24 if ip_version == 4 else 64, enable_dhcp=True) if l3: router = self.create_router( external_network_id=CONF.network.public_network_id ) self.router_attach(router, subnet) security_group = self.create_open_ssh_security_group() user_data = (u'\u0445\u0440\u0435\u043d-\u0441-' u'\u0440\u0443\u0447\u043a\u043e\u0439') server1 = self.create_tenant_server( networks=[network], security_groups=[security_group], user_data=user_data, prepare_for_connectivity=True) curl_cmd = 'curl http://169.254.169.254/2009-04-04/user-data' result = server1.send(curl_cmd) self.assertIn(user_data, result) @decorators.attr(type='smoke') def test_unicode_userdata_l3_v4(self): self._test_unicode_userdata(l3=True, ip_versions=[4]) @decorators.attr(type='smoke') def test_unicode_userdata_l2_v4(self): self._test_unicode_userdata(l3=False, ip_versions=[4]) @decorators.attr(type='smoke') @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') def test_unicode_userdata_l3_v6(self): self._test_unicode_userdata(l3=True, ip_versions=[6]) @decorators.attr(type='smoke') @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') def test_unicode_userdata_l2_v6(self): self._test_unicode_userdata(l3=False, ip_versions=[6]) @decorators.attr(type='smoke') def test_unicode_userdata_l3_dualstack(self): self._test_unicode_userdata(l3=True, ip_versions=[6, 4]) @decorators.attr(type='smoke') def test_unicode_userdata_l2_dualstack(self): self._test_unicode_userdata(l3=False, ip_versions=[6, 4])
class OsManagedDualStackL2SubnetsTest(NuageBaseTest, nuage_test.NuageAdminNetworksTest): credentials = ['primary', 'admin'] # TODO(waelj) port to VSD helper @classmethod def setup_clients(cls): super(OsManagedDualStackL2SubnetsTest, cls).setup_clients() cls.nuage_client = NuageRestClient() def _verify_ipv6_subnet_with_vsd_l2_domain(self, subnet, by_subnet): """_verify_ipv6_subnet_with_vsd_l2_domain Verifies the VSD l2 domain defined by 'by_subnet' with the openstack subnet 'subnet'. @param by_subnet: the subnet via which the l2 domain will be retrieved @param subnet: the subnet to compare the L2 domain with """ vsd_l2_domain = self.vsd.get_l2domain(by_subnet=by_subnet) self.assertIsNotNone(vsd_l2_domain) self.assertIsNone(subnet['ipv6_ra_mode']) self.assertIsNone(subnet['ipv6_address_mode']) if Topology.has_single_stack_v6_support(): self.assertEqual('DUALSTACK', vsd_l2_domain.ip_type) self.assertEqual(subnet['cidr'], vsd_l2_domain.ipv6_address) self.assertEqual(subnet['enable_dhcp'], vsd_l2_domain.enable_dhcpv6) else: if subnet['enable_dhcp'] or by_subnet['enable_dhcp']: self.assertEqual('DUALSTACK', vsd_l2_domain.ip_type) self.assertEqual(subnet['cidr'], vsd_l2_domain.ipv6_address) else: self.assertIsNone(vsd_l2_domain.ip_type) self.assertIsNone(vsd_l2_domain.ipv6_address) if subnet['enable_dhcp']: filters = { 'device_owner': 'network:dhcp:nuage', 'network_id': subnet['network_id'] } dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(1, len(dhcp_ports)) for fixed_ip in dhcp_ports[0]['fixed_ips']: if fixed_ip['subnet_id'] == subnet['id']: self.assertEqual(fixed_ip['ip_address'], vsd_l2_domain.ipv6_gateway) elif Topology.is_v5: self.assertEqual(subnet['enable_dhcp'] or by_subnet['enable_dhcp'], vsd_l2_domain.dhcp_managed) else: self.assertTrue(vsd_l2_domain.dhcp_managed) self.assertIsNone(vsd_l2_domain.ipv6_gateway) self.assertFalse(subnet['vsd_managed']) # TODO(waelj) VSD-20971 / VSD-21874 # self.assertFalse(vsd_l2_domain.dualStackDynamicIPAllocation, # "VSD should not allocated IPv6 address") # TODO(waelj) port to VSD helper def _verify_vport_in_l2_domain(self, port, vsd_l2domain, **kwargs): nuage_vports = self.nuage_client.get_vport(nuage_constants.L2_DOMAIN, vsd_l2domain.id, filters='externalID', filter_values=port['id']) self.assertEqual( len(nuage_vports), 1, "Must find one VPort matching port: %s" % port['name']) nuage_vport = nuage_vports[0] self.assertThat(nuage_vport, ContainsDict({'name': Equals(port['id'])})) # verify all other kwargs as attributes (key,value) pairs for key, value in iteritems(kwargs): if isinstance(value, dict): # compare dict raise NotImplementedError if isinstance(value, list): # self.assertThat(port, ContainsDict({key: Equals(value)})) self.assertItemsEqual(port[key], value) else: self.assertThat(port, ContainsDict({key: Equals(value)})) def _verify_port(self, port, subnet4=None, subnet6=None, **kwargs): has_ipv4_ip = False has_ipv6_ip = False for fixed_ip in port['fixed_ips']: ip_address = fixed_ip['ip_address'] if subnet4 is not None and fixed_ip['subnet_id'] == subnet4['id']: self.verify_ip_in_allocation_pools(ip_address, subnet4['allocation_pools']) has_ipv4_ip = True if subnet6 is not None and fixed_ip['subnet_id'] == subnet6['id']: self.verify_ip_in_allocation_pools(ip_address, subnet6['allocation_pools']) has_ipv6_ip = True if subnet4: self.assertTrue( has_ipv4_ip, "Must have an IPv4 ip in subnet: %s" % subnet4['id']) if subnet6: self.assertTrue( has_ipv6_ip, "Must have an IPv6 ip in subnet: %s" % subnet6['id']) self.assertIsNotNone(port['mac_address']) # verify all other kwargs as attributes (key,value) pairs for key, value in iteritems(kwargs): if isinstance(value, dict): # compare dict raise NotImplementedError if isinstance(value, list): self.assertItemsEqual(port[key], value) else: self.assertThat(port, ContainsDict({key: Equals(value)})) ########################################################################### # Typical ########################################################################### @decorators.attr(type='smoke') def test_os_managed_dual_stack_subnet(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # Then a VSD L2 domain is created with type IPv4 vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) self.assertIsNotNone(vsd_l2_domain) self.assertEqual("IPV4", vsd_l2_domain.ip_type) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) # Then the VSD L2 domain is changed to IPtype DualStack self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet, ipv4_subnet) port = self.create_port(network) self._verify_port(port, subnet4=ipv4_subnet, subnet6=None), self._verify_vport_in_l2_domain(port, vsd_l2_domain) @decorators.attr(type='smoke') def test_os_managed_dual_stack_subnet_with_dhcp_managed_ipv6(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # And I add an IPv6 subnet with DHCP, it should be OK ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=True) self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet, ipv4_subnet) @testtools.skipUnless(Topology.has_dhcp_v6_support(), 'No dhcp v6 supported') @decorators.attr(type='smoke') def test_os_managed_dual_stack_subnet_with_dns_server(self): # Provision OpenStack network network = self.create_network() kwargs = { 6: { 'dns_nameservers': ['2001:4860:4860::8844', '2001:4860:4860::8888'] }, 4: { 'dns_nameservers': ['8.8.4.4', '8.8.8.8'] } } ipv4_subnet = self.create_subnet(network, **kwargs[4]) ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=True, **kwargs[6]) vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) nuage_dhcpv4opt = self.nuage_client.get_dhcpoption( nuage_constants.L2_DOMAIN, vsd_l2_domain.id, ipv4_subnet['ip_version']) self._check_dhcp_option(nuage_dhcpv4opt, ipv4_subnet) nuage_dhcpv6opt = self.nuage_client.get_dhcpoption( nuage_constants.L2_DOMAIN, vsd_l2_domain.id, ipv6_subnet['ip_version']) self._check_dhcp_option(nuage_dhcpv6opt, ipv6_subnet) def _check_dhcp_option(self, nuage_dhcpopt, subnet, l2=True): opt_index = 0 if subnet['ip_version'] == 4 and subnet.get('gateway_ip', None) and l2: self.assertGreater(len(nuage_dhcpopt), opt_index) self.assertEqual(self.ip_to_hex(subnet['gateway_ip']), nuage_dhcpopt[opt_index]['value']) self.assertEqual(nuage_dhcpopt[opt_index]['type'], "03") self.assertEqual( nuage_dhcpopt[opt_index]['externalID'], self.nuage_client.get_vsd_external_id(subnet.get('id'))) opt_index += 1 if subnet.get('dns_nameservers'): self.assertGreater(len(nuage_dhcpopt), opt_index) self.assertEqual(nuage_dhcpopt[opt_index]['type'], "06" if subnet['ip_version'] == 4 else "17") dns1 = self.ip_to_hex(subnet['dns_nameservers'][0]) dns2 = self.ip_to_hex(subnet['dns_nameservers'][1]) ip_length = 8 if subnet['ip_version'] == 4 else 32 dhcp_dns = ([ nuage_dhcpopt[opt_index]['value'][0:ip_length], nuage_dhcpopt[opt_index]['value'][ip_length:] ]) self.assertIn(dns1, dhcp_dns) self.assertIn(dns2, dhcp_dns) ########################################################################### # Special cases ########################################################################### @testtools.skipIf(Topology.is_v5, 'IPv6 CIDRs are fully restricted by default from 6.0 ' 'onwards only, i.e. when expert mode is left disabled') def test_os_managed_subnet_with_invalid_ipv6_prefixlen_neg(self): # Provision OpenStack network network = self.create_network() for ipv6_cidr in ['cafe:babe::/63', 'cafe:babe::/65']: ipv6_gateway = 'cafe:babe::1' self.assertRaisesRegex(tempest_exceptions.BadRequest, MSG_INVALID_IPV6_NETMASK, self.create_subnet, network, ip_version=6, cidr=IPNetwork(ipv6_cidr), mask_bits=IPNetwork(ipv6_cidr).prefixlen, gateway=ipv6_gateway) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') @decorators.attr(type='smoke') def test_os_managed_dhcp_subnet_ipv6_first(self): self._test_os_managed_subnet_ipv6_first(enable_dhcp=True) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') @decorators.attr(type='smoke') def test_os_managed_no_dhcp_subnet_ipv6_first(self): self._test_os_managed_subnet_ipv6_first(enable_dhcp=False) def _test_os_managed_subnet_ipv6_first(self, enable_dhcp=None): # Provision OpenStack network network = self.create_network() # Create an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=enable_dhcp, cleanup=False) # Verify L2Dom vsd_l2_domain = self.vsd.get_l2domain( vspk_filter='externalID == "{}"'.format( ExternalId(ipv6_subnet['network_id']).at_cms_id())) self.assertIsNotNone(vsd_l2_domain) filters = { 'device_owner': 'network:dhcp:nuage', 'network_id': network['id'] } self.assertEqual(vsd_l2_domain.ip_type, 'IPV6') dhcp_ports = self.ports_client.list_ports(**filters)['ports'] if Topology.has_dhcp_v6_support(): self.assertEqual(enable_dhcp, vsd_l2_domain.enable_dhcpv6) if enable_dhcp: self.assertEqual(1, len(dhcp_ports)) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['subnet_id'], ipv6_subnet['id']) else: self.assertEqual(0, len(dhcp_ports)) # Verify port/Vport portv6 = self.create_port(network, cleanup=False) self._verify_port(portv6, subnet6=ipv6_subnet) self._verify_vport_in_l2_domain(portv6, vsd_l2_domain) # Create an IPv4 subnet in the same network ipv4_subnet = self.create_subnet(network, enable_dhcp=enable_dhcp) # Verify the L2Dom is Dualstack now vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv6_subnet) self.assertIsNotNone(vsd_l2_domain) self.assertEqual(vsd_l2_domain.ip_type, 'DUALSTACK') dhcp_ports = self.ports_client.list_ports(**filters)['ports'] if enable_dhcp: self.assertTrue(vsd_l2_domain.enable_dhcpv4) self.assertEqual(1, len(dhcp_ports)) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['subnet_id'], ipv4_subnet['id']) self.assertEqual(dhcp_ports[0]['fixed_ips'][1]['subnet_id'], ipv6_subnet['id']) else: self.assertFalse(vsd_l2_domain.enable_dhcpv4) self.assertEqual(0, len(dhcp_ports)) # Delete Subnet/Port self.delete_port(portv6) self.delete_subnet(ipv6_subnet) vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) # Verify the L2Dom self.assertIsNotNone(vsd_l2_domain) self.assertEqual(vsd_l2_domain.ip_type, 'IPV4') self.assertFalse(vsd_l2_domain.enable_dhcpv6) if enable_dhcp: self.assertEqual(1, len(dhcp_ports)) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['subnet_id'], ipv4_subnet['id']) else: self.assertEqual(0, len(dhcp_ports)) @decorators.attr(type='smoke') def test_os_managed_dhcp_subnet_ipv4_first(self): self._test_os_managed_subnet_ipv4_first(enable_dhcp=True) @decorators.attr(type='smoke') def test_os_managed_no_dhcp_subnet_ipv4_first(self): self._test_os_managed_subnet_ipv4_first(enable_dhcp=False) def _test_os_managed_subnet_ipv4_first(self, enable_dhcp=None): # Provision OpenStack network network = self.create_network() # Create an IPv4 subnet ipv4_subnet = self.create_subnet(network, ip_version=4, enable_dhcp=enable_dhcp, cleanup=False) # Verify L2Dom vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) self.assertIsNotNone(vsd_l2_domain) if enable_dhcp: self.assertEqual(vsd_l2_domain.ip_type, 'IPV4') # Verify port/Vport portv4 = self.create_port(network, cleanup=False) self._verify_port(portv4, subnet4=ipv4_subnet) self._verify_vport_in_l2_domain(portv4, vsd_l2_domain) # Create an IPv6 subnet in the same network ipv6_subnet = self.create_subnet(network, enable_dhcp=enable_dhcp, ip_version=6) # Verify the L2Dom is Dualstack now vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) self.assertIsNotNone(vsd_l2_domain) if enable_dhcp: self.assertEqual(vsd_l2_domain.ip_type, 'DUALSTACK') # Delete v4 Subnet/Port self.delete_port(portv4) self.delete_subnet(ipv4_subnet) vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv6_subnet) # Verify the L2Dom if Topology.has_single_stack_v6_support(): self.assertIsNotNone(vsd_l2_domain) if enable_dhcp: self.assertEqual(vsd_l2_domain.ip_type, 'IPV6') else: self.assertIsNone(vsd_l2_domain) @decorators.attr(type='smoke') # OPENSTACK-1926 def test_os_managed_dual_stack_subnet_ipv4_create_delete_create(self): network = self.create_network() ipv4_subnet = self.create_subnet(network, cleanup=False) self.assertIsNotNone(ipv4_subnet) ipv6_subnet = self.create_subnet(network, ip_version=6, gateway=None) self.assertIsNotNone(ipv6_subnet) self.check_dhcp_port(network['id'], [4, 6]) # delete IPv4 subnet self.manager.subnets_client.delete_subnet(ipv4_subnet['id']) self.check_dhcp_port(network['id'], [6]) # create again self.create_subnet(network) @decorators.attr(type='smoke') # OPENSTACK-1926 def test_os_managed_dual_stack_subnet_ipv6_create_delete_create(self): network = self.create_network() ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) ipv6_subnet = self.create_subnet(network, ip_version=6, gateway=None, cleanup=False) self.assertIsNotNone(ipv6_subnet) self.check_dhcp_port(network['id'], [4, 6]) # delete self.manager.subnets_client.delete_subnet(ipv6_subnet['id']) self.check_dhcp_port(network['id'], [4]) # create again ipv6_subnet = self.create_subnet(network, ip_version=6, gateway=None) self.assertIsNotNone(ipv6_subnet) @decorators.attr(type='smoke') def test_os_managed_dual_stack_subnet_with_ipv4_only_ports(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) # And I create a port in the network self.create_port(network) # TODO(waelj) Then the port has only an IPv4 address # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) # TODO(waelj) Then the port has both an IPv4 and IPv6 address # And I create a port in the network self.create_port(network) # TODO(waelj) Then the port has both an IPv4 and IPv6 address # Then the VSD L2 domain is changed to IPtype DualStack self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet, ipv4_subnet) @decorators.attr(type='smoke') def test_os_managed_dual_stack_subnet_no_gateway(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # Then a VSD L2 domain is created with type IPv4 vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) self.assertIsNotNone(vsd_l2_domain) self.assertEqual("IPV4", vsd_l2_domain.ip_type) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, gateway=None, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) # Then the VSD L2 domain is changed to IPtype DualStack self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet, ipv4_subnet) port = self.create_port(network) self._verify_port(port, subnet4=ipv4_subnet, subnet6=None), self._verify_vport_in_l2_domain(port, vsd_l2_domain) @decorators.attr(type='smoke') def test_os_managed_dual_stack_subnet_unmanaged(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network, enable_dhcp=False) self.assertIsNotNone(ipv4_subnet) # Then a VSD L2 domain is created with type IPv4 vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) self.assertIsNotNone(vsd_l2_domain) if Topology.is_v5: self.assertIsNone(vsd_l2_domain.ip_type) else: self.assertEqual(vsd_l2_domain.ip_type, 'IPV4') # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) # Then the VSD L2 domain is changed to IPtype DualStack self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet, ipv4_subnet) port = self.create_port(network) self.assertIsNotNone(port) @decorators.attr(type='smoke') def test_no_vsd_auto_assignment_for_ipv6_addresses(self): network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # Then a VSD L2 domain is created with type IPv4 vsd_l2_domain = self.nuage_client.get_l2domain( by_subnet=ipv4_subnet)[0] self.assertIsNotNone(vsd_l2_domain) self.assertFalse( vsd_l2_domain['dynamicIpv6Address' if Topology. is_v5 else 'dualStackDynamicIPAllocation'], 'VSD should not allocated IPv6 address') # When I add an IPv6 subnet ipv6_cidr = IPNetwork('cafe:babe::/64') ipv6_subnet = self.create_subnet( network, cidr=ipv6_cidr, mask_bits=ipv6_cidr.prefixlen, gateway=IPAddress(ipv6_cidr.first + 1), ip_version=6, allocation_pools=[{ 'start': IPAddress('cafe:babe::a:0:0:0'), 'end': IPAddress('cafe:babe::a:ffff:ffff:ffff') }]) self.assertIsNotNone(ipv6_subnet) vsd_l2_domain = self.nuage_client.get_l2domain( by_subnet=ipv4_subnet)[0] self.assertIsNotNone(vsd_l2_domain) self.assertFalse( vsd_l2_domain['dynamicIpv6Address' if Topology. is_v5 else 'dualStackDynamicIPAllocation'], 'VSD should not allocated IPv6 address') # When I create a port outside the pool, it should succeed ip_out_of_ipv6_allocation_pool = IPAddress('cafe:babe::b:0:0:0') port_args = { 'fixed_ips': [{ 'subnet_id': ipv4_subnet['id'] }, { 'subnet_id': ipv6_subnet['id'], 'ip_address': ip_out_of_ipv6_allocation_pool }] } port = self.create_port(network, **port_args) self.assertIsNotNone(port) ######################################## # IPv6 address formats ######################################## def test_create_subnet_with_special_address_formats(self): # noinspection PyPep8 valid_ipv6 = [ ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e:0000:0000:0000:0001"), # valid address range, gateway full addressing - at first address ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e::1"), # valid address range, gateway zero's compressed addressing # - at first address ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e:0:000::1"), # valid address range, gateway partly compressed addressing # - at first address ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e:ffff:ffff:ffff:ffff"), # valid address, gateway at last address ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e:f483:3427:ab3e:bc21"), # valid address, gateway at random address ("2001:5F74:c4A5:B82e::/64", "2001:5f74:c4a5:b82e:f483:3427:aB3E:bC21"), # valid address, gateway at random address - mixed case ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e:f4:00::f"), # valid address, gateway at random address - compressed ("3ffe:0b00:0000:0001:5f74:0001:c4a5:b82e/64", "3ffe:0b00:0000:0001:5f74:0001:c4a5:ffff"), # prefix not matching bit mask ] # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) for ipv6_cidr, ipv6_gateway in valid_ipv6: # When I add an IPv6 subnet ipv6_subnet = self.create_subnet( network, ip_version=6, cidr=IPNetwork(ipv6_cidr), mask_bits=IPNetwork(ipv6_cidr).prefixlen, gateway=ipv6_gateway, enable_dhcp=False, cleanup=False) self.assertIsNotNone(ipv6_subnet) # Then the VSD L2 domain is changed to IPtype DualStack self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet, by_subnet=ipv4_subnet) # And I create a port in the network port = self.create_port(network, cleanup=False) self._verify_port(port, subnet4=ipv4_subnet, subnet6=ipv6_subnet), self.manager.ports_client.delete_port(port['id']) self.subnets_client.delete_subnet(ipv6_subnet['id']) ########################################################################### # Update IPv6 subnet attributes ########################################################################### @decorators.attr(type='smoke') def test_os_managed_dual_stack_subnet_update_no_vsd(self): # Update of openstack subnet attributes which are by design not # replicated to VSD network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network, enable_dhcp=False) self.assertIsNotNone(ipv4_subnet) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) # Then the VSD L2 domain is changed to IPtype DualStack self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet, ipv4_subnet) # Update attributes subnet_attributes = { 'name': "updated name", 'description': "My subnet description" } ipv6_subnet_updated = self.update_subnet(ipv6_subnet, enable_dhcp=False, **subnet_attributes) self.assertThat("updated name", Equals(ipv6_subnet_updated['name'])) self.assertThat("My subnet description", Equals(ipv6_subnet_updated['description'])) vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv4_subnet) self.assertIsNotNone(vsd_l2_domain) # L2 domain description should match with network name # if it is dualstack self.assertThat( vsd_l2_domain.description, Equals(ipv4_subnet['name'] if Topology.is_v5 else network['name'])) @decorators.attr(type='smoke') # OPENSTACK-1943 def test_os_managed_dual_stack_subnet_update_gw_no_gw(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) # Then the VSD L2 domain is changed to DualStack self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet, ipv4_subnet) # Update attributes subnet_attributes = {'gateway_ip': None} ipv6_subnet_updated = self.update_subnet(ipv6_subnet, enable_dhcp=False, **subnet_attributes) self._verify_ipv6_subnet_with_vsd_l2_domain(ipv6_subnet_updated, ipv4_subnet) self.assertIsNone(ipv6_subnet_updated['gateway_ip']) ########################################################################### # Negative cases ########################################################################### @decorators.attr(type='negative') @decorators.attr(type='smoke') def test_os_managed_dual_stack_create_ipv6_only_port_neg(self): network = self.create_network() ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) if Topology.has_single_stack_v6_support(): port1 = self.create_port(network) self._verify_port(port1, subnet4=None, subnet6=ipv6_subnet) port_ip = IPAddress(port1['fixed_ips'][0]['ip_address']) port_args = { 'fixed_ips': [{ 'ip_address': port_ip + 10 }, { 'ip_address': port_ip + 11 }] } port2 = self.create_port(network, **port_args) self._verify_port(port2, subnet4=None, subnet6=ipv6_subnet) else: self.assertRaisesRegex( tempest_exceptions.BadRequest, "Port can't be a pure ipv6 port. Need ipv4 fixed ip.", self.create_port, network) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'No singe-stack v6 supported') @decorators.attr(type='smoke') def test_os_managed_dual_stack_update_port_to_ipv6_only(self): network = self.create_network() self.create_subnet(network) self.create_subnet(network, ip_version=6, enable_dhcp=False) port = self.create_port(network) # 1. remove the v4 ip from the port v4_ip = next((ip for ip in port['fixed_ips'] if _is_v4_ip(ip)), None) v4_ip_a = IPAddress(v4_ip['ip_address']) v6_ip = next((ip for ip in port['fixed_ips'] if _is_v6_ip(ip)), None) v6_ip_a = IPAddress(v6_ip['ip_address']) f_ips = {'fixed_ips': [{'ip_address': v6_ip_a}]} self.update_port(port, **f_ips) # 2. add 2nd v6 ip (must succeed) f_ips = { 'fixed_ips': [{ 'ip_address': v4_ip_a }, { 'ip_address': v6_ip_a }, { 'ip_address': v6_ip_a + 1 }] } self.update_port(port, **f_ips) # 3. now remove v4 again f_ips = { 'fixed_ips': [{ 'ip_address': v6_ip_a }, { 'ip_address': v6_ip_a + 1 }] } self.update_port(port, **f_ips) ########################################################################### # Negative cases ########################################################################### @decorators.attr(type='negative') def test_subnet_with_dhcp_unmanaged_ipv6_attr_slaac_neg(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # When I add an IPv6 subnet with DHCP, it should fail with BadRequest self.assertRaisesRegex( tempest_exceptions.BadRequest, "Invalid input for operation: " + "ipv6_ra_mode or ipv6_address_mode cannot be set when " "enable_dhcp is set to False.", self.create_subnet, network, ip_version=6, enable_dhcp=False, ipv6_ra_mode='slaac', ipv6_address_mode='slaac') @decorators.attr(type='negative') def test_subnet_with_dhcp_managed_ipv6_only_attr_slaac_neg(self): # Provision OpenStack network network = self.create_network() self.assertRaisesRegex( tempest_exceptions.BadRequest, "Attribute ipv6_ra_mode must be 'dhcpv6-stateful' or not set.", self.create_subnet, network, mask_bits=64, ip_version=6, enable_dhcp=True, ipv6_ra_mode='slaac', ipv6_address_mode='slaac') @decorators.attr(type='negative') def test_subnet_with_dhcp_managed_ipv6_attr_slaac_neg(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # And I add an IPv6 subnet with slaac, it should fail with BadRequest self.assertRaisesRegex( tempest_exceptions.BadRequest, "Attribute ipv6_ra_mode must be 'dhcpv6-stateful' or not set.", self.create_subnet, network, mask_bits=64, ip_version=6, enable_dhcp=True, ipv6_ra_mode='slaac', ipv6_address_mode='slaac') @decorators.attr(type='negative') def test_multiple_ipv6_subnets_neg(self): # Provision OpenStack network network = self.create_network() # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) if Topology.has_single_stack_v6_support(): ipv6_subnet = self.create_subnet( network, cidr=IPNetwork("2fbe:4568:a:b::/64"), mask_bits=64, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) else: # When I add an a second IPv6 subnet, it should fail self.assertRaisesRegex( tempest_exceptions.BadRequest, "A network with an ipv6 subnet may only have maximum " "1 ipv4 and 1 ipv6 subnet", self.create_subnet, network, cidr=IPNetwork("2fbe:4568:a:b::/64"), mask_bits=64, ip_version=6, enable_dhcp=False) @decorators.attr(type='negative') def test_dual_stack_subnet_multiple_ipv4_subnets_neg(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) if Topology.is_v5: msg = ('A network with an ipv6 subnet may only have maximum 1 ipv4' ' and 1 ipv6 subnet') else: msg = ('A network can only have maximum 1 ipv4 and 1 ipv6 subnet' ' existing together') self.assertRaisesRegex(tempest_exceptions.BadRequest, msg, self.create_subnet, network) @decorators.attr(type='negative') def test_multiple_ipv4_subnets_with_ipv6_subnet_neg(self): if self.is_dhcp_agent_present(): raise self.skipException( 'Cannot run this test case when DHCP agent is enabled') # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # When I add an IPv4 subnet ipv4_subnet2 = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet2) if Topology.is_v5: msg = ('A network with an ipv6 subnet may only have maximum 1 ' 'ipv4 and 1 ipv6 subnet') else: msg = ('A network can only have maximum 1 ipv4 and 1 ipv6 subnet ' 'existing together') # When I add an IPv6 subnet, it should fail self.assertRaisesRegex(tempest_exceptions.BadRequest, msg, self.create_subnet, network, cidr=IPNetwork("2fbe:4568:a:b::/64"), mask_bits=64, ip_version=6, enable_dhcp=False) @decorators.attr(type='negative') def test_delete_ipv4_subnet_with_port_from_dual_stack_subnets_neg(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # And I create a port in the network port1 = self.create_port(network) self.assertIsNotNone(port1) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) self.assertRaisesRegex( tempest_exceptions.Conflict, "One or more ports have an IP allocation from this subnet", self.subnets_client.delete_subnet, ipv4_subnet['id']) @decorators.attr(type='negative') def test_delete_ipv4_subnet_with_dualstack_port_neg(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # And I create a port in the network port1 = self.create_port(network) self.assertIsNotNone(port1) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False, cleanup=False) self.assertIsNotNone(ipv6_subnet) # Then I can delete the IPv6 subnet self.subnets_client.delete_subnet(ipv6_subnet['id']) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) # And I create a port in the network port2 = self.create_port(network) self.assertIsNotNone(port2) # Then I can't clean the subnet anymore self.assertRaisesRegex( tempest_exceptions.Conflict, "One or more ports have an IP allocation from this subnet", self.subnets_client.delete_subnet, ipv6_subnet['id']) ######################################## # IPv6 address formats ######################################## def test_create_subnet_invalid_ipv6_gateway_neg(self): invalid_ipv6 = [ ( # Reserved addresses # See https://www.iana.org/assignments/ # iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml "fe80:5f74:c4a5:b82e::/120", "fe80:5f74:c4a5:b82e::1", MSG_RESERVED_IPV6_ADDRESS % "fe80:5f74:c4a5:b82e::/120"), ( # Reserved addresses: 6to4 "2002:5f74:c4a5:b82e::/120", "2002:5f74:c4a5:b82e::1", (MSG_RESERVED_IPV6_ADDRESS % '2002:5f74:c4a5:b82e::/120') if Topology.is_v5 else MSG_INVALID_IPV6_NETMASK), ("2001:5f74:c4a5:b82e::/63", "2001:5f74:c4a5:b82e::1", MSG_INVALID_IPV6_NETMASK), ("::/0", "::1", "Invalid input for operation: 0 is not allowed as CIDR prefix " "length."), ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82b:ffff:ffff:ffff:ffff", MSG_GATEWAY_NOT_IN_SUBNET_CIDR), # Gateway not valid on CIDR ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e::/128", MSG_GATEWAY_INVALID_IP_ADDRESS % "2001:5f74:c4a5:b82e::/128"), # Gateway should be single address ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e::ZZZZ", MSG_GATEWAY_INVALID_IP_ADDRESS % "2001:5f74:c4a5:b82e::ZZZZ"), # Gateway should be valid address ("2001:5f74:c4a5:b82e::/64", "169.172.0.0", MSG_INVALID_GATEWAY_FOR_IP_TYPE % "169.172.0.0"), # Gateway is an IPv4 address ] # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) for ipv6_cidr, ipv6_gateway, msg in invalid_ipv6: self.assertRaisesRegex(tempest_exceptions.BadRequest, msg, self.create_subnet, network, ip_version=6, cidr=IPNetwork(ipv6_cidr), mask_bits=IPNetwork(ipv6_cidr).prefixlen, gateway=ipv6_gateway, enable_dhcp=False) def test_create_port_with_invalid_address_formats_neg(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network) self.assertIsNotNone(ipv4_subnet) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet( network, cidr=IPNetwork("2001:5f74:c4a5:b82e::/64"), mask_bits=64, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) # noinspection PyPep8 invalid_ipv6 = [ ('::1', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # Loopback ('FE80::1', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # Link local address ("FF00:5f74:c4a5:b82e:ffff:ffff:ffff:ffff", MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # multicast ('FF00::1', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # multicast address ('::1', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # not specified address ('::', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # empty address ("2001:ffff:ffff:ffff:ffff:ffff:ffff:ffff", MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # valid address, not in subnet ('', MSG_INVALID_INPUT_FOR_FIXED_IPS), # empty string ("2001:5f74:c4a5:b82e:ffff:ffff:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_FIXED_IPS), # invalid address, too much segments ("2001:5f74:c4a5:b82e:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_FIXED_IPS), # invalid address, seven segments ("2001;5f74.c4a5.b82e:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_FIXED_IPS), # invalid address, wrong characters ("2001:5f74:c4a5:b82e:100.12.13.1", MSG_INVALID_INPUT_FOR_FIXED_IPS ), # invalid fornmat: must have :: between hex and decimal part. ] for ipv6, msg in invalid_ipv6: port_args = { 'fixed_ips': [{ 'subnet_id': ipv4_subnet['id'], 'ip_address': IPNetwork(ipv4_subnet['cidr'])[+10] }, { 'subnet_id': ipv6_subnet['id'], 'ip_address': ipv6 }] } self.assertRaisesRegex(tempest_exceptions.BadRequest, msg % ipv6, self.create_port, network, **port_args) ########################################################################### # Update IPv6 subnet attributes - negative ########################################################################### def test_os_managed_dual_stack_subnet_update_neg(self): # Provision OpenStack network network = self.create_network() # When I create an IPv4 subnet ipv4_subnet = self.create_subnet(network, enable_dhcp=False) self.assertIsNotNone(ipv4_subnet) # When I add an IPv6 subnet ipv6_subnet = self.create_subnet(network, ip_version=6, enable_dhcp=False) self.assertIsNotNone(ipv6_subnet) self.assertRaisesRegex(tempest_exceptions.BadRequest, "Cannot update read-only attribute ip_version", self.update_subnet, ipv6_subnet, ip_version=4)
class DNSScenarioTest(nuage_test.NuageBaseTest): default_prepare_for_connectivity = True def _test_dns_up_to_vm(self, ip_versions=None, is_l3=None): dns = {6: 'cafe:babe:cafe:babe:cafe:babe:cafe:babe', 4: '1.1.1.1'} network = self.create_network() subnet = None for ip_version in ip_versions: subnet = self.create_subnet(network, ip_version=ip_version, dns_nameservers=[dns.get(ip_version)]) if is_l3: router = self.create_router( external_network_id=CONF.network.public_network_id) self.router_attach(router, subnet) # create open-ssh security group ssh_security_group = self.create_open_ssh_security_group() server = self.create_tenant_server( [network], security_groups=[ssh_security_group], prepare_for_connectivity=True) # makes sure that all the DNSs configured. server.send(cmd="[ `cat /etc/resolv.conf | grep nameserver | " "wc -l` = {} ]".format(len(ip_versions)), timeout=300) result = server.send(cmd="cat /etc/resolv.conf | grep nameserver") for ip_version in ip_versions: self.assertIn(dns.get(ip_version), result, 'DNS={} is not configured ' 'properly.'.format(dns.get(ip_version))) @decorators.attr(type='smoke') def test_dns_up_to_vm_l2_v4(self): self._test_dns_up_to_vm(ip_versions=[4], is_l3=False) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'No singe-stack v6 supported') def test_dns_up_to_vm_l2_v6(self): self._test_dns_up_to_vm(ip_versions=[6], is_l3=False) def test_dns_up_to_vm_l3_v4(self): self._test_dns_up_to_vm(ip_versions=[4], is_l3=True) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'No singe-stack v6 supported') @decorators.attr(type='smoke') def test_dns_up_to_vm_l3_v6(self): self._test_dns_up_to_vm(ip_versions=[6], is_l3=True) @testtools.skipUnless(Topology.has_dhcp_v6_support(), 'No dhcp v6 supported') def test_dns_up_to_vm_l2_dualstack(self): self._test_dns_up_to_vm(ip_versions=[6, 4], is_l3=False) @testtools.skipUnless(Topology.has_dhcp_v6_support(), 'No dhcp v6 supported') @decorators.attr(type='smoke') def test_dns_up_to_vm_l3_dualstack(self): self._test_dns_up_to_vm(ip_versions=[6, 4], is_l3=True)
def skip_checks(cls): super(AllowedAddressPairIpV6NuageTest, cls).skip_checks() if not Topology.has_single_stack_v6_support(): raise cls.skipException('There is no single-stack v6 support ' 'in current release')
def skip_checks(cls): super(NuageNetworksIpV6Test, cls).skip_checks() if not Topology.has_single_stack_v6_support(): msg = 'There is no single-stack v6 support in current release' raise cls.skipException(msg)
def skip_checks(cls): super(StatelessSecuritygroupTestV6, cls).skip_checks() if not Topology.has_single_stack_v6_support(): msg = 'There is no single-stack v6 support in current release' raise cls.skipException(msg)
class VSDManagedDualStackSubnetL3Test(BaseVSDManagedNetworksIPv6Test): ########################################################################### # Typical cases ########################################################################### @decorators.attr(type='smoke') def test_create_ipv6_subnet_in_vsd_managed_l3domain(self): name = data_utils.rand_name('l3domain-') vsd_l3domain_template = self.vsd_create_l3domain_template(name=name) vsd_l3domain = self.vsd_create_l3domain( name=name, template_id=vsd_l3domain_template.id) self.assertEqual(vsd_l3domain.name, name) zone_name = data_utils.rand_name('zone-') vsd_zone = self.vsd_create_zone(name=zone_name, domain=vsd_l3domain) subnet_name = data_utils.rand_name('l3domain-subnet-') subnet_cidr = IPNetwork('10.10.100.0/24') subnet_gateway = str(IPAddress(subnet_cidr) + 1) subnet_ipv6_cidr = IPNetwork("2001:5f74:c4a5:b82e::/64") subnet_ipv6_gateway = str(IPAddress(subnet_ipv6_cidr) + 1) vsd_l3domain_subnet = self.create_vsd_subnet( name=subnet_name, zone=vsd_zone, ip_type="DUALSTACK", cidr4=subnet_cidr, gateway4=subnet_gateway, cidr6=subnet_ipv6_cidr, gateway6=subnet_ipv6_gateway) self.assertEqual(vsd_l3domain_subnet.name, subnet_name) # create Openstack IPv4 subnet on Openstack based on VSD l3dom subnet net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) ipv4_subnet = self.create_subnet( network, gateway=subnet_gateway, cidr=subnet_cidr, enable_dhcp=True, mask_bits=IPNetwork(subnet_cidr).prefixlen, nuagenet=vsd_l3domain_subnet.id, net_partition=Topology.def_netpartition) self.assertEqual(ipv4_subnet['cidr'], str(subnet_cidr)) # create Openstack IPv6 subnet on Openstack based on VSD l3dom subnet ipv6_subnet = self.create_subnet( network, ip_version=6, gateway=vsd_l3domain_subnet.ipv6_gateway, cidr=IPNetwork(vsd_l3domain_subnet.ipv6_address), mask_bits=IPNetwork(vsd_l3domain_subnet.ipv6_address).prefixlen, enable_dhcp=False, nuagenet=vsd_l3domain_subnet.id, net_partition=Topology.def_netpartition) filters = { 'device_owner': 'network:dhcp:nuage', 'network_id': ipv4_subnet['network_id'] } dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(1, len(dhcp_ports)) self.assertEqual(1, len(dhcp_ports[0]['fixed_ips'])) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['subnet_id'], ipv4_subnet['id']) self.assertEqual(ipv6_subnet['cidr'], vsd_l3domain_subnet.ipv6_address) # create a port in the network port = self.create_port(network) self._verify_port(port, subnet4=ipv4_subnet, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l3_subnet(port, vsd_l3domain_subnet) ########################################################################### # Special cases ########################################################################### ######################################## # backwards compatibility ######################################## def test_create_ipv4_subnet_in_vsd_managed_l3domain_ipv4(self): name = data_utils.rand_name('l3domain-') vsd_l3domain_template = self.vsd_create_l3domain_template(name=name) vsd_l3domain = self.vsd_create_l3domain( name=name, template_id=vsd_l3domain_template.id) self.assertEqual(vsd_l3domain.name, name) zone_name = data_utils.rand_name('zone-') vsd_zone = self.vsd_create_zone(name=zone_name, domain=vsd_l3domain) subnet_name = data_utils.rand_name('l3domain-subnet-') subnet_cidr = IPNetwork('10.10.100.0/24') subnet_gateway = str(IPAddress(subnet_cidr) + 1) vsd_l3domain_subnet = self.create_vsd_subnet(name=subnet_name, zone=vsd_zone, cidr4=subnet_cidr, gateway4=subnet_gateway, ip_type="IPV4") self.assertEqual("IPV4", vsd_l3domain_subnet.ip_type) self.assertIsNone(vsd_l3domain_subnet.external_id) self.assertIsNone(vsd_l3domain_subnet.ipv6_address) self.assertIsNone(vsd_l3domain_subnet.ipv6_gateway) self.assertEqual(str(subnet_cidr.ip), vsd_l3domain_subnet.address) self.assertEqual(subnet_gateway, vsd_l3domain_subnet.gateway) def test_create_ipv4_subnet_in_vsd_managed_l3domain_no_type(self): name = data_utils.rand_name('l3domain-') vsd_l3domain_template = self.vsd_create_l3domain_template(name=name) vsd_l3domain = self.vsd_create_l3domain( name=name, template_id=vsd_l3domain_template.id) self.assertEqual(vsd_l3domain.name, name) zone_name = data_utils.rand_name('zone-') vsd_zone = self.vsd_create_zone(name=zone_name, domain=vsd_l3domain) subnet_name = data_utils.rand_name('l3domain-subnet-') subnet_cidr = IPNetwork('10.10.100.0/24') subnet_gateway = str(IPAddress(subnet_cidr) + 1) vsd_l3domain_subnet = self.create_vsd_subnet(name=subnet_name, zone=vsd_zone, cidr4=subnet_cidr, gateway4=subnet_gateway) self.assertEqual("IPV4", vsd_l3domain_subnet.ip_type) self.assertIsNone(vsd_l3domain_subnet.external_id) self.assertIsNone(vsd_l3domain_subnet.ipv6_address) self.assertIsNone(vsd_l3domain_subnet.ipv6_gateway) self.assertEqual(str(subnet_cidr.ip), vsd_l3domain_subnet.address) self.assertEqual(subnet_gateway, vsd_l3domain_subnet.gateway) ######################################## # minimal attributes - default values ######################################## ########################################################################### # Negative cases ########################################################################### @decorators.attr(type='smoke') def test_create_ipv6_subnet_in_vsd_managed_l3domain_ipv4(self): name = data_utils.rand_name('l3domain-') vsd_l3domain_template = self.vsd_create_l3domain_template(name=name) vsd_l3domain = self.vsd_create_l3domain( name=name, template_id=vsd_l3domain_template.id) self.assertEqual(vsd_l3domain.name, name) zone_name = data_utils.rand_name('zone-') vsd_zone = self.vsd_create_zone(name=zone_name, domain=vsd_l3domain) subnet_name = data_utils.rand_name('l3domain-subnet-') subnet_cidr = IPNetwork('10.10.100.0/24') subnet_gateway = str(IPAddress(subnet_cidr) + 1) vsd_l3domain_subnet = self.create_vsd_subnet(name=subnet_name, zone=vsd_zone, cidr4=subnet_cidr, gateway4=subnet_gateway, ip_type="IPV4") # create Openstack IPv4 subnet on Openstack based on VSD l3dom subnet net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) subnet_ipv6_cidr = IPNetwork("2001:5f74:c4a5:b82e::/64") subnet_ipv6_gateway = str(IPAddress(subnet_ipv6_cidr) + 1) # shall not create Openstack IPv6 subnet on Openstack based on # VSD l3domain subnet with type IPV4 self.assertRaisesRegex(tempest_exceptions.BadRequest, "Subnet with ip_version 6 can't be linked to " "vsd subnet with IPType IPV4", self.create_subnet, network, ip_version=6, gateway=subnet_ipv6_gateway, cidr=subnet_ipv6_cidr, mask_bits=subnet_ipv6_cidr.prefixlen, enable_dhcp=False, nuagenet=vsd_l3domain_subnet.id, net_partition=Topology.def_netpartition) @decorators.attr(type='smoke') def test_create_ipv4_subnet_without_dhcp_in_vsd_managed_l3domain(self): name = data_utils.rand_name('l3domain-') vsd_l3domain_template = self.vsd_create_l3domain_template(name=name) vsd_l3domain = self.vsd_create_l3domain( name=name, template_id=vsd_l3domain_template.id) self.assertEqual(vsd_l3domain.name, name) zone_name = data_utils.rand_name('zone-') vsd_zone = self.vsd_create_zone(name=zone_name, domain=vsd_l3domain) subnet_name = data_utils.rand_name('l3domain-subnet-') subnet_cidr = IPNetwork('10.10.100.0/24') subnet_gateway = str(IPAddress(subnet_cidr) + 1) vsd_l3domain_subnet = self.create_vsd_subnet(name=subnet_name, zone=vsd_zone, cidr4=subnet_cidr, gateway4=subnet_gateway, ip_type="IPV4") # create Openstack IPv4 subnet on Openstack based on VSD l3dom subnet net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) # create Openstack IPv4 subnet on Openstack based on VSD l3dom subnet self.assertRaisesRegex(tempest_exceptions.BadRequest, 'enable_dhcp in subnet must be True', self.create_subnet, network, gateway=subnet_gateway, cidr=subnet_cidr, mask_bits=subnet_cidr.prefixlen, enable_dhcp=False, nuagenet=vsd_l3domain_subnet.id, net_partition=Topology.def_netpartition) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'No singe-stack v6 supported') @decorators.attr(type='smoke') def test_os_managed_v6_conversions_l2_l3_v6_dualstack(self): # Provision OpenStack network/subnet/router network = self.create_network() ipv6_subnet = self.create_subnet(network, ip_version=6) # verify l2 dom vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv6_subnet) self.assertEqual(vsd_l2_domain.ip_type, 'IPV6') router = self.create_router() vsd_l3_domain = self.vsd.get_l3domain(by_router_id=router['id']) # attach v6 subnet to router / verify l3 dom self.router_attach(router, ipv6_subnet, cleanup=False) vsd_l3_subnet = self.vsd.get_subnet_from_domain(domain=vsd_l3_domain, by_subnet=ipv6_subnet) self.assertEqual(vsd_l3_subnet.ip_type, 'IPV6') # create/verify port port = self.create_port(network) self._verify_port(port, subnet6=ipv6_subnet), self._verify_vport_in_l3_subnet(port, vsd_l3_subnet) # pure ipv6 to dualstack ipv4_subnet = self.create_subnet(network, cleanup=False) vsd_l3_subnet = self.vsd.get_subnet_from_domain(domain=vsd_l3_domain, by_subnet=ipv6_subnet) self.assertEqual(vsd_l3_subnet.ip_type, 'DUALSTACK') # dualstack to ipv6 self.delete_subnet(ipv4_subnet) vsd_l3_subnet = self.vsd.get_subnet_from_domain(domain=vsd_l3_domain, by_subnet=ipv6_subnet) self.assertEqual(vsd_l3_subnet.ip_type, 'IPV6') # v6L3 to v6L2 self.router_detach(router, ipv6_subnet) vsd_l2_domain = self.vsd.get_l2domain(by_subnet=ipv6_subnet) self.assertEqual(vsd_l2_domain.ip_type, 'IPV6')
class VSDManagedDualStackL2DHCPManagedTest(VSDManagedDualStackCommonBase): os_dhcp_managed = True vsd_dhcp_managed = True def link_dualstack_net_l2( self, cidr4=None, mask_bits4=None, dhcp4_port=None, gateway4=None, cidr6=None, mask_bits6=None, dhcp6_port=None, gateway6=None, pool4=None, pool6=None, vsd_l2dom=None, should_pass4=True, should_pass6=True): cidr4 = cidr4 or IPNetwork('10.10.100.0/24') mask_bits4 = mask_bits4 or cidr4.prefixlen dhcp4_port = dhcp4_port or str(cidr4[1]) cidr6 = cidr6 or IPNetwork('cafe:babe::/64') mask_bits6 = mask_bits6 or cidr6.prefixlen if vsd_l2dom is None: vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", dhcp_managed=True, cidr4=cidr4, cidr6=cidr6, gateway=dhcp4_port) vsd_l2dom = self.vsd_create_l2domain( template=vsd_l2domain_template) # create OpenStack network net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) # create OpenStack IPv4 subnet on OpenStack based on VSD l2domain kwargs4 = { 'gateway': gateway4, 'cidr': cidr4, 'mask_bits': mask_bits4, 'nuagenet': vsd_l2dom.id, 'net_partition': self.net_partition } if pool4: kwargs4['allocation_pools'] = [pool4] if should_pass4: ipv4_subnet = self.create_subnet(network, **kwargs4) self.assertEqual(ipv4_subnet['cidr'], str(cidr4)) if pool4: subnet_pool4 = ipv4_subnet['allocation_pools'] self.assertEqual(1, len(subnet_pool4)) self.assertEqual(pool4, subnet_pool4[0]) else: self.assertRaises(exceptions.BadRequest, self.create_subnet, network, **kwargs4) # create OpenStack IPv6 subnet on OpenStack based on VSD l2dom subnet kwargs6 = { 'gateway': gateway6, 'cidr': cidr6, 'mask_bits': mask_bits6, 'ip_version': 6, 'enable_dhcp': False, 'nuagenet': vsd_l2dom.id, 'net_partition': self.net_partition } if pool6: kwargs6['allocation_pools'] = [pool6] if should_pass6: ipv6_subnet = self.create_subnet(network, **kwargs6) self.assertEqual(str(cidr6), ipv6_subnet['cidr']) if pool6: subnet_pool6 = ipv6_subnet['allocation_pools'] self.assertEqual(1, len(subnet_pool6)) self.assertEqual(pool6, subnet_pool6[0]) else: self.assertRaises(exceptions.BadRequest, self.create_subnet, network, **kwargs6) return vsd_l2dom @decorators.attr(type='smoke') def test_dualstack_vsd_mgd_l2dom_dhcp_mgd(self): self.link_dualstack_net_l2() @decorators.attr(type='smoke') def test_dualstack_vsd_mgd_l2dom_dhcp_mgd_allocation_pools(self): pool4 = {'start': '10.10.100.100', 'end': '10.10.100.109'} pool6 = {'start': 'cafe:babe::100', 'end': 'cafe:babe::109'} self.link_dualstack_net_l2(pool4=pool4, pool6=pool6) @decorators.attr(type='smoke') def test_dual_ds_vsd_mgd_l2dom_dhcp_mgd_disjunct_allocation_pools(self): pool4 = {'start': '10.10.100.100', 'end': '10.10.100.109'} pool6 = {'start': 'cafe:babe::100', 'end': 'cafe:babe::109'} vsd_l2dom = self.link_dualstack_net_l2(pool4=pool4, pool6=pool6) pool4 = {'start': '10.10.100.110', 'end': '10.10.100.119'} pool6 = {'start': 'cafe:babe::110', 'end': 'cafe:babe::119'} self.link_dualstack_net_l2(pool4=pool4, pool6=pool6, vsd_l2dom=vsd_l2dom) @decorators.attr(type='smoke') def test_dual_ds_vsd_mgd_l2dom_dhcp_mgd_non_disj_v4_alloc_pools_neg(self): pool4 = {'start': '10.10.100.100', 'end': '10.10.100.110'} pool6 = {'start': 'cafe:babe::100', 'end': 'cafe:babe::109'} vsd_l2dom = self.link_dualstack_net_l2(pool4=pool4, pool6=pool6) pool4 = {'start': '10.10.100.110', 'end': '10.10.100.119'} pool6 = {'start': 'cafe:babe::110', 'end': 'cafe:babe::119'} self.link_dualstack_net_l2(pool4=pool4, pool6=pool6, vsd_l2dom=vsd_l2dom, should_pass4=False) @decorators.attr(type='smoke') def test_dual_ds_vsd_mgd_l2dom_dhcp_mgd_non_disj_v6_alloc_pools_neg(self): pool4 = {'start': '10.10.100.100', 'end': '10.10.100.109'} pool6 = {'start': 'cafe:babe::100', 'end': 'cafe:babe::110'} vsd_l2dom = self.link_dualstack_net_l2(pool4=pool4, pool6=pool6) pool4 = {'start': '10.10.100.110', 'end': '10.10.100.119'} pool6 = {'start': 'cafe:babe::110', 'end': 'cafe:babe::119'} self.link_dualstack_net_l2(pool4=pool4, pool6=pool6, vsd_l2dom=vsd_l2dom, should_pass6=False) @decorators.attr(type='smoke') def test_create_ipv6_subnet_in_vsd_mgd_l2dom_dhcp_mgd_with_ports(self): """test_create_ipv6_subnet_in_vsd_managed_l2domain_dhcp_managed OpenStack IPv4 and IPv6 subnets linked to VSD l2 dualstack l2domain - create VSD l2 domain template dualstack - create VSD l2 domain - create OS network - create OS subnets - create OS port """ # create l2domain on VSD vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4) self._verify_vsd_l2domain_template(vsd_l2domain_template, ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4) vsd_l2domain = self.vsd_create_l2domain(template=vsd_l2domain_template) self._verify_vsd_l2domain_with_template( vsd_l2domain, vsd_l2domain_template) # create OpenStack IPv4 subnet on OpenStack based on VSD l2domain net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) ipv4_subnet = self.create_subnet( network, gateway=None, cidr=self.cidr4, mask_bits=self.mask_bits4_unsliced, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual(ipv4_subnet['cidr'], str(self.cidr4)) # create a port in the network port_ipv4_only = self.create_port(network, cleanup=False) self._verify_port(port_ipv4_only, subnet4=ipv4_subnet, subnet6=None, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port_ipv4_only, vsd_l2domain) # create OpenStack IPv6 subnet on OpenStack based on VSD l2dom subnet ipv6_subnet = self.create_subnet( network, ip_version=6, gateway=vsd_l2domain_template.ipv6_gateway, cidr=self.cidr6, mask_bits=self.mask_bits6, enable_dhcp=False, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual( ipv6_subnet['cidr'], vsd_l2domain_template.ipv6_address) # Mind ... VSD will have allocated an IP to the prev created port now # We need to sure we don't create port now which collides with that # Therefore clean up this port first now self.ports_client.delete_port(port_ipv4_only['id']) # create a port with fixed-ip in the IPv4 subnet, and no IP in IPv6 port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 7)}]} port = self.create_port(network, **port_args) self._verify_port(port, subnet4=ipv4_subnet, subnet6=None), self._verify_vport_in_l2_domain(port, vsd_l2domain) # create a port with fixed-ip in the IPv4 subnet and in IPv6 port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 11)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 11)}]} port = self.create_port(network, **port_args) self._verify_port(port, subnet4=ipv4_subnet, subnet6=ipv6_subnet), self._verify_vport_in_l2_domain(port, vsd_l2domain) # can have multiple fixed ip's in same subnet port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 33)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 33)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 34)}]} port = self.create_port(network, **port_args) self._verify_port(port, subnet4=ipv4_subnet, subnet6=ipv6_subnet, status='DOWN') self._verify_vport_in_l2_domain(port, vsd_l2domain) # create a port in the network # OpenStack now chooses a random IP address. # To avoid conflict with the above fixed IP's, do this case last port = self.create_port(network) self._verify_port(port, subnet4=ipv4_subnet, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port, vsd_l2domain) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'No singe-stack v6 supported') @decorators.attr(type='smoke') def test_create_ipv6_subnet_in_vsd_mgd_l2domain_with_ipv6_network_first( self): """test_create_ipv6_subnet_in_vsd_mgd_l2domain_with_ipv6_network_first OpenStack IPv4 and IPv6 subnets linked to VSD l2 dualstack l2 domain - create VSD l2 domain template dualstack - create VSD l2 domain - create OS network - create OS subnets -- first the ipv6 network -- than the ipv4 network - create OS port """ # create l2domain on VSD vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4) self._verify_vsd_l2domain_template(vsd_l2domain_template, ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4) vsd_l2domain = self.vsd_create_l2domain(template=vsd_l2domain_template) self._verify_vsd_l2domain_with_template( vsd_l2domain, vsd_l2domain_template) # create OpenStack IPv6 subnet on OpenStack based on VSD l2dom subnet net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) ipv6_subnet = self.create_subnet( network, ip_version=6, gateway=vsd_l2domain_template.ipv6_gateway, cidr=IPNetwork(vsd_l2domain_template.ipv6_address), mask_bits=IPNetwork( vsd_l2domain_template.ipv6_address).prefixlen, enable_dhcp=False, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual(ipv6_subnet['cidr'], vsd_l2domain_template.ipv6_address) filters = { 'device_owner': 'network:dhcp:nuage', 'network_id': network['id'] } dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(0, len(dhcp_ports)) port = self.create_port(network) self._verify_port(port, subnet4=None, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port, vsd_l2domain) # create OpenStack IPv4 subnet on OpenStack based on VSD l2domain ipv4_subnet = self.create_subnet( network, gateway=None, cidr=self.cidr4, mask_bits=self.mask_bits4_unsliced, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual(ipv4_subnet['cidr'], str(self.cidr4)) dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(1, len(dhcp_ports)) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['subnet_id'], ipv4_subnet['id']) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['ip_address'], vsd_l2domain.gateway) # create a port in the network - IPAM by OS port = self.create_port(network) self._verify_port(port, subnet4=ipv4_subnet, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port, vsd_l2domain) # create a port in the network - IPAM by OS port = self.create_port(network) self._verify_port(port, subnet4=ipv4_subnet, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port, vsd_l2domain) ########################################################################### # From base class ########################################################################### def test_create_vsd_l2domain_template_dualstack_valid(self): self._create_vsd_l2domain_template_dualstack_valid() ########################################################################### # Special cases ########################################################################### ######################################## # backwards compatibility ######################################## @decorators.attr(type='smoke') def test_ipv4_subnet_linked_to_ipv4_vsd_l2domain(self): vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="IPV4", cidr4=self.cidr4, dhcp_managed=True) self._verify_vsd_l2domain_template( vsd_l2domain_template, ip_type="IPV4", dhcp_managed=True, cidr4=self.cidr4, gateway=self.gateway4, netmask=str(self.cidr4.netmask)) vsd_l2domain = self.vsd_create_l2domain(template=vsd_l2domain_template) self._verify_vsd_l2domain_with_template( vsd_l2domain, vsd_l2domain_template) # create OpenStack IPv4 subnet on OpenStack based on VSD l2domain net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) ipv4_subnet = self.create_subnet( network, gateway=None, cidr=self.cidr4, mask_bits=self.mask_bits4_unsliced, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual(ipv4_subnet['cidr'], str(self.cidr4)) # create a port in the network port_ipv4_only = self.create_port(network) self._verify_port(port_ipv4_only, subnet4=ipv4_subnet, subnet6=None, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port_ipv4_only, vsd_l2domain) ######################################## # minimal attributes - default values ######################################## @nuage_test.skip_because(bug='VSD-18509') @decorators.attr(type='smoke') def test_create_vsd_l2domain_template_dualstack_valid_failing_at_vsd(self): valid_ipv6 = [ ("0:0:0:ffff::/64", "::ffff:100.12.13.1"), # ("2001:5f74:c4a5:b82e::/64", "2001:5f74:c4a5:b82e::100.12.13.1"), # valid address, gateway at mixed ipv4 and ipv6 format # (digit-dot notation) ] for ipv6_cidr, ipv6_gateway in valid_ipv6: vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", cidr4=self.cidr4, dhcp_managed=True, ipv6_address=ipv6_cidr, ipv6_gateway=ipv6_gateway ) self._verify_vsd_l2domain_template(vsd_l2domain_template, ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, ipv6_address=ipv6_cidr, ipv6_gateway=ipv6_gateway) @decorators.attr(type='smoke') def test_create_fixed_ipv6_ports_in_vsd_managed_l2domain(self): """test_create_fixed_ipv6_ports_in_vsd_managed_l2domain OpenStack IPv4 and IPv6 subnets linked to VSD l2 dualstack l2domain - create VSD l2 domain template dualstack - create VSD l2 domain - create OS network - create OS subnets - create OS port """ # create l2domain on VSD vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4, gateway6=self.gateway6, enable_dhcpv4=True, enable_dhcpv6=True) self._verify_vsd_l2domain_template(vsd_l2domain_template, ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, ipv6_gateway=self.gateway6, gateway=self.gateway4) vsd_l2domain = self.vsd_create_l2domain(template=vsd_l2domain_template) self._verify_vsd_l2domain_with_template( vsd_l2domain, vsd_l2domain_template) # create OpenStack IPv4 subnet on OpenStack based on VSD l2domain net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) ipv4_subnet = self.create_subnet( network, gateway=None, cidr=self.cidr4, mask_bits=self.mask_bits4_unsliced, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual(ipv4_subnet['cidr'], str(self.cidr4)) # create a port in the network port_ipv4_only = self.create_port(network) self._verify_port(port_ipv4_only, subnet4=ipv4_subnet, subnet6=None, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) nuage_vports = self.nuage_client.get_vport( nuage_constants.L2_DOMAIN, vsd_l2domain.id, filters='externalID', filter_values=port_ipv4_only['id']) self.assertEqual( len(nuage_vports), 1, "Must find one VPort matching port: %s" % port_ipv4_only['name']) nuage_vport = nuage_vports[0] self.assertThat(nuage_vport, ContainsDict({'name': Equals(port_ipv4_only['id'])})) # create OpenStack IPv6 subnet on OpenStack based on VSD l2dom subnet ipv6_subnet = self.create_subnet( network, ip_version=6, gateway=self.gateway6, cidr=self.cidr6, mask_bits=self.mask_bits6, enable_dhcp=True, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual( ipv6_subnet['cidr'], vsd_l2domain_template.ipv6_address) # create a port in the network port = self.create_port(network) self._verify_port(port, subnet4=ipv4_subnet, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) nuage_vports = self.nuage_client.get_vport( nuage_constants.L2_DOMAIN, vsd_l2domain.id, filters='externalID', filter_values=port['id']) self.assertEqual( len(nuage_vports), 1, "Must find one VPort matching port: %s" % port['name']) nuage_vport = nuage_vports[0] self.assertThat(nuage_vport, ContainsDict({'name': Equals(port['id'])})) ########################################################################### # Negative cases ########################################################################### @decorators.attr(type='smoke') def test_ipv6_subnet_linked_to_ipv4_vsd_l2domain_neg(self): vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="IPV4", cidr4=self.cidr4, dhcp_managed=True) self._verify_vsd_l2domain_template( vsd_l2domain_template, ip_type="IPV4", dhcp_managed=True, cidr4=self.cidr4, gateway=self.gateway4, netmask=str(self.cidr4.netmask)) vsd_l2domain = self.vsd_create_l2domain( template=vsd_l2domain_template) self._verify_vsd_l2domain_with_template( vsd_l2domain, vsd_l2domain_template) # create OpenStack IPv6 subnet on linked to VSD l2domain net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) self.assertRaisesRegex( exceptions.BadRequest, "Subnet with ip_version 6 can't be linked " "to vsd subnet with IPType IPV4", self.create_subnet, network, ip_version=6, enable_dhcp=False, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) @decorators.attr(type='smoke') def test_create_port_in_vsd_managed_l2domain_dhcp_managed_neg(self): """test_create_port_in_vsd_managed_l2domain_dhcp_managed_neg OpenStack IPv4 and IPv6 subnets linked to VSD l2 dualstack l2domain - create VSD l2 domain template dualstack - create VSD l2 domain - create OS network - create OS subnets - create OS port """ # create l2domain on VSD vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4) self._verify_vsd_l2domain_template(vsd_l2domain_template, ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4) vsd_l2domain = self.vsd_create_l2domain(template=vsd_l2domain_template) self._verify_vsd_l2domain_with_template( vsd_l2domain, vsd_l2domain_template) # create OpenStack IPv4 subnet on OpenStack based on VSD l2domain net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) ipv4_subnet = self.create_subnet( network, gateway=None, cidr=self.cidr4, mask_bits=self.mask_bits4_unsliced, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual(ipv4_subnet['cidr'], str(self.cidr4)) # shall not create a port with fixed-ip IPv6 in ipv4 subnet port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 21)}]} self.assertRaisesRegex( exceptions.BadRequest, "IP address %s is not a valid IP for the specified subnet" % (IPAddress(self.cidr6.first + 21)), self.create_port, network, **port_args) # create OpenStack IPv6 subnet on OpenStack based on VSD l2dom subnet ipv6_subnet = self.create_subnet( network, ip_version=6, gateway=self.gateway6, cidr=self.cidr6, mask_bits=self.mask_bits6, enable_dhcp=False, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) # shall not create port with IP already in use port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 10)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 10)}]} valid_port = self.create_port(network, **port_args) self.assertIsNotNone(valid_port) port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 11)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 10)}]} self.assertRaisesRegex( exceptions.Conflict, 'IP address {} already allocated ' 'in subnet {}'.format(IPAddress(self.cidr6.first + 10), ipv6_subnet['id']), self.create_port, network, **port_args) # shall not create port with fixed ip in outside cidr port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 201)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first - 20)}]} self.assertRaisesRegex( exceptions.BadRequest, "IP address %s is not a valid IP for the specified subnet" % (IPAddress(self.cidr6.first - 20)), self.create_port, network, **port_args) if not Topology.has_single_stack_v6_support(): return # remainder of test needs single-stack v6 # shall not a port with no ip in the IPv4 subnet but only fixed-ip IPv6 port_args = {'fixed_ips': [{'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 21)}]} port = self.create_port(network, **port_args) self._verify_port(port, subnet4=None, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port, vsd_l2domain) port_args = {'fixed_ips': [{'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 22)}]} port = self.create_port(network, **port_args) self._verify_port(port, subnet4=None, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port, vsd_l2domain) # TODO(KRIS) Try to make sense of this # # # OpenStack-17001 - VSD accepts os port creation in L2 dualstack # # network with fixed-ip = IPv6Gateway IP # # shall not create port with fixed ip on the IPv6 gateway address # port_args = dict(fixed_ips=[{'subnet_id': ipv4_subnet['id']}, # {'subnet_id': ipv6_subnet['id'], # 'ip_address': # vsd_l2domain_template.ipv6_gateway} # ]) # if Release(CONF.nuage_sut.openstack_version) >= Release('Newton'): # expected_exception = exceptions.Conflict, # expected_message = "IP address %s already allocated in " # "subnet %s" \ # % (vsd_l2domain_template.ipv6_gateway, # ipv6_subnet['id']) # else: # expected_exception = exceptions.ServerFault # expected_message = "The IP address %s is in use." %\ # vsd_l2domain_template.ipv6_gateway, # # self.assertRaisesRegex( # expected_exception, # expected_message, # self.create_port, # network, # **port_args) @decorators.attr(type='smoke') def test_create_port_neg(self): """test_create_port_neg OpenStack IPv4 and IPv6 subnets linked to VSD l2 dualstack l2domain - create VSD l2 domain template dualstack - create VSD l2 domain - create OS network - create OS subnets - create OS port """ # create l2domain on VSD vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6) vsd_l2domain = self.vsd_create_l2domain(template=vsd_l2domain_template) # create OpenStack IPv4 subnet on OpenStack based on VSD l2domain net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) ipv4_subnet = self.create_subnet( network, gateway=None, cidr=self.cidr4, enable_dhcp=True, mask_bits=self.mask_bits4_unsliced, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) ipv6_subnet = self.create_subnet( network, ip_version=6, gateway=self.gateway6, cidr=self.cidr6, mask_bits=self.mask_bits6, enable_dhcp=False, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) # noinspection PyPep8 invalid_ipv6 = [ ('::1', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # Loopback ('FE80::1', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # Link local address ("FF00:5f74:c4a5:b82e:ffff:ffff:ffff:ffff", MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # multicast ('FF00::1', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # multicast address ('::1', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # not specified address ('::', MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # empty address ("2001:ffff:ffff:ffff:ffff:ffff:ffff:ffff", MSG_INVALID_IP_ADDRESS_FOR_SUBNET), # valid address, not in subnet ('', MSG_INVALID_INPUT_FOR_FIXED_IPS), # empty string ("2001:5f74:c4a5:b82e:ffff:ffff:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_FIXED_IPS), # invalid address, too much segments ("2001:5f74:c4a5:b82e:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_FIXED_IPS), # invalid address, seven segments ("2001;5f74.c4a5.b82e:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_FIXED_IPS), # invalid address, wrong characters ("2001:5f74:c4a5:b82e:100.12.13.1", MSG_INVALID_INPUT_FOR_FIXED_IPS), # invalid format: must have :: between hex and decimal part. ] for ipv6, msg in invalid_ipv6: port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 40)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': ipv6}]} self.assertRaisesRegex(exceptions.BadRequest, msg % ipv6, self.create_port, network, **port_args) # Telenor scenario with multiple vsd managed subnets in a network @decorators.attr(type='smoke') def test_link_multi_l2domain_to_network_dualstack(self): net_name = data_utils.rand_name('multi-vsd-mgd-dualstack') network = self.create_network(network_name=net_name) vsd_l2domain_template1 = self.vsd_create_l2domain_template( ip_type="DUALSTACK", cidr4=IPNetwork('10.0.0.0/24'), cidr6=IPNetwork('cafe:babe::/64'), dhcp_managed=True, enable_dhcpv6=True ) vsd_l2domain1 = self.vsd_create_l2domain( template=vsd_l2domain_template1) vsd_l2domain_template2 = self.vsd_create_l2domain_template( ip_type="DUALSTACK", cidr4=IPNetwork('10.1.0.0/24'), cidr6=IPNetwork('cbfe:babe::/64'), dhcp_managed=True, enable_dhcpv6=True ) vsd_l2domain2 = self.vsd_create_l2domain( template=vsd_l2domain_template2) v4_1 = self.create_subnet( network, cidr=IPNetwork('10.0.0.0/24'), mask_bits=24, gateway=None, nuagenet=vsd_l2domain1.id, net_partition=Topology.def_netpartition) filters = { 'device_owner': 'network:dhcp:nuage', 'network_id': network['id'] } dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(1, len(dhcp_ports)) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['subnet_id'], v4_1['id']) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['ip_address'], vsd_l2domain1.gateway) v6_1 = self.create_subnet( network, ip_version=6, cidr=IPNetwork('cafe:babe::/64'), mask_bits=self.mask_bits6, nuagenet=vsd_l2domain1.id, net_partition=Topology.def_netpartition) if Topology.has_dhcp_v6_support(): dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(1, len(dhcp_ports)) self.assertEqual(dhcp_ports[0]['fixed_ips'][1]['subnet_id'], v6_1['id']) self.assertEqual(dhcp_ports[0]['fixed_ips'][1]['ip_address'], vsd_l2domain1.ipv6_gateway) if self.is_dhcp_agent_present(): self.assertRaises( exceptions.BadRequest, self.create_subnet, network, cidr=IPNetwork('10.1.0.0/24'), mask_bits=24, gateway=None, nuagenet=vsd_l2domain2.id, net_partition=Topology.def_netpartition) self.assertRaises( exceptions.BadRequest, self.create_subnet, network, ip_version=6, cidr=IPNetwork('cbfe:babe::/64'), mask_bits=64, nuagenet=vsd_l2domain2.id, net_partition=Topology.def_netpartition) else: v4_2 = self.create_subnet( network, cidr=IPNetwork('10.1.0.0/24'), mask_bits=24, gateway=None, nuagenet=vsd_l2domain2.id, net_partition=Topology.def_netpartition) if Topology.has_dhcp_v6_support(): dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(2, len(dhcp_ports)) for dhcp_port in dhcp_ports: if dhcp_port['fixed_ips'][0]['subnet_id'] == v4_2['id']: self.assertEqual( dhcp_port['fixed_ips'][0]['ip_address'], vsd_l2domain2.gateway) v6_2 = self.create_subnet( network, ip_version=6, cidr=IPNetwork('cbfe:babe::/64'), mask_bits=self.mask_bits6, nuagenet=vsd_l2domain2.id, net_partition=Topology.def_netpartition) if Topology.has_dhcp_v6_support(): dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(2, len(dhcp_ports)) for dhcp_port in dhcp_ports: if dhcp_port['fixed_ips'][1]['subnet_id'] == v6_2['id']: self.assertEqual( dhcp_port['fixed_ips'][1]['ip_address'], vsd_l2domain2.ipv6_gateway) # check ports # dualstack port of same l2domain kwargs = { 'fixed_ips': [{'subnet_id': v4_1['id']}, {'subnet_id': v6_1['id']}] } self.create_port(network, **kwargs) kwargs = { 'fixed_ips': [{'subnet_id': v4_2['id']}, {'subnet_id': v6_2['id']}] } self.create_port(network, **kwargs) kwargs = { 'fixed_ips': [{'subnet_id': v4_1['id']}, {'subnet_id': v6_2['id']}] } self.assertRaises( exceptions.BadRequest, self.create_port, network, **kwargs ) kwargs = { 'fixed_ips': [{'subnet_id': v6_1['id']}, {'subnet_id': v4_2['id']}] } self.assertRaises( exceptions.BadRequest, self.create_port, network, **kwargs ) # Telenor scenario with multiple vsd managed subnets in a network @decorators.attr(type='smoke') def test_link_multi_l2domain_to_network_mix_dualstack(self): if self.is_dhcp_agent_present(): raise self.skipException( 'Multiple VSD managed subnets linked to different l2domains ' 'in a network not supported when DHCP agent is enabled.') net_name = data_utils.rand_name('multi-vsd-mgd-dualstack') network = self.create_network(network_name=net_name) vsd_l2domain_template1 = self.vsd_create_l2domain_template( ip_type="DUALSTACK", cidr4=IPNetwork('10.0.0.0/24'), cidr6=IPNetwork('cafe:babe::/64'), dhcp_managed=True, enable_dhcpv6=True ) vsd_l2domain1 = self.vsd_create_l2domain( template=vsd_l2domain_template1) vsd_l2domain_template2 = self.vsd_create_l2domain_template( ip_type="DUALSTACK", cidr4=IPNetwork('10.1.0.0/24'), cidr6=IPNetwork('cbfe:babe::/64'), dhcp_managed=True, enable_dhcpv6=True ) vsd_l2domain2 = self.vsd_create_l2domain( template=vsd_l2domain_template2) v4_subnet = self.create_subnet( network, cidr=IPNetwork('10.0.0.0/24'), mask_bits=24, gateway=None, nuagenet=vsd_l2domain1.id, net_partition=Topology.def_netpartition) filters = { 'device_owner': 'network:dhcp:nuage', 'network_id': network['id'] } dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(1, len(dhcp_ports)) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['subnet_id'], v4_subnet['id']) self.assertEqual(dhcp_ports[0]['fixed_ips'][0]['ip_address'], vsd_l2domain1.gateway) v6_subnet = self.create_subnet( network, ip_version=6, cidr=IPNetwork('cbfe:babe::/64'), mask_bits=64, nuagenet=vsd_l2domain2.id, net_partition=Topology.def_netpartition) if Topology.has_dhcp_v6_support(): dhcp_ports = self.ports_client.list_ports(**filters)['ports'] self.assertEqual(2, len(dhcp_ports)) for dhcp_port in dhcp_ports: if dhcp_port['fixed_ips'][0]['subnet_id'] == v6_subnet['id']: self.assertEqual( dhcp_port['fixed_ips'][0]['ip_address'], vsd_l2domain2.ipv6_gateway)
def test_create_port_in_vsd_managed_l2domain_dhcp_managed_neg(self): """test_create_port_in_vsd_managed_l2domain_dhcp_managed_neg OpenStack IPv4 and IPv6 subnets linked to VSD l2 dualstack l2domain - create VSD l2 domain template dualstack - create VSD l2 domain - create OS network - create OS subnets - create OS port """ # create l2domain on VSD vsd_l2domain_template = self.vsd_create_l2domain_template( ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4) self._verify_vsd_l2domain_template(vsd_l2domain_template, ip_type="DUALSTACK", dhcp_managed=True, cidr4=self.cidr4, cidr6=self.cidr6, gateway=self.gateway4) vsd_l2domain = self.vsd_create_l2domain(template=vsd_l2domain_template) self._verify_vsd_l2domain_with_template( vsd_l2domain, vsd_l2domain_template) # create OpenStack IPv4 subnet on OpenStack based on VSD l2domain net_name = data_utils.rand_name('network-') network = self.create_network(network_name=net_name) ipv4_subnet = self.create_subnet( network, gateway=None, cidr=self.cidr4, mask_bits=self.mask_bits4_unsliced, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) self.assertEqual(ipv4_subnet['cidr'], str(self.cidr4)) # shall not create a port with fixed-ip IPv6 in ipv4 subnet port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 21)}]} self.assertRaisesRegex( exceptions.BadRequest, "IP address %s is not a valid IP for the specified subnet" % (IPAddress(self.cidr6.first + 21)), self.create_port, network, **port_args) # create OpenStack IPv6 subnet on OpenStack based on VSD l2dom subnet ipv6_subnet = self.create_subnet( network, ip_version=6, gateway=self.gateway6, cidr=self.cidr6, mask_bits=self.mask_bits6, enable_dhcp=False, nuagenet=vsd_l2domain.id, net_partition=self.net_partition) # shall not create port with IP already in use port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 10)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 10)}]} valid_port = self.create_port(network, **port_args) self.assertIsNotNone(valid_port) port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 11)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 10)}]} self.assertRaisesRegex( exceptions.Conflict, 'IP address {} already allocated ' 'in subnet {}'.format(IPAddress(self.cidr6.first + 10), ipv6_subnet['id']), self.create_port, network, **port_args) # shall not create port with fixed ip in outside cidr port_args = {'fixed_ips': [{'subnet_id': ipv4_subnet['id'], 'ip_address': IPAddress( self.cidr4.first + 201)}, {'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first - 20)}]} self.assertRaisesRegex( exceptions.BadRequest, "IP address %s is not a valid IP for the specified subnet" % (IPAddress(self.cidr6.first - 20)), self.create_port, network, **port_args) if not Topology.has_single_stack_v6_support(): return # remainder of test needs single-stack v6 # shall not a port with no ip in the IPv4 subnet but only fixed-ip IPv6 port_args = {'fixed_ips': [{'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 21)}]} port = self.create_port(network, **port_args) self._verify_port(port, subnet4=None, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port, vsd_l2domain) port_args = {'fixed_ips': [{'subnet_id': ipv6_subnet['id'], 'ip_address': IPAddress( self.cidr6.first + 22)}]} port = self.create_port(network, **port_args) self._verify_port(port, subnet4=None, subnet6=ipv6_subnet, status='DOWN', nuage_policy_groups=None, nuage_redirect_targets=[], nuage_floatingip=None) self._verify_vport_in_l2_domain(port, vsd_l2domain)
def skip_checks(cls): super(AllowedAddressPairV6Test, cls).skip_checks() if not Topology.has_single_stack_v6_support(): msg = 'There is no single-stack v6 support in current release' raise cls.skipException(msg)
class SecGroupNuageTest(nuage_test.NuageBaseTest): is_l3 = False # ip_versions: tuple with all ip versions to be used, eg (4, 6) ip_versions = (4, 6) if Topology.has_single_stack_v6_support(): scenarios = testscenarios.scenarios.multiply_scenarios([('L3', { 'is_l3': True }), ('L2', { 'is_l3': False })], [('IPv4', { 'ip_versions': (4, ) }), ('IPv6', { 'ip_versions': (6, ) }), ('Dualstack', { 'ip_versions': (4, 6) })]) else: scenarios = testscenarios.scenarios.multiply_scenarios([('L3', { 'is_l3': True }), ('L2', { 'is_l3': False })], [('IPv4', { 'ip_versions': (4, ) }), ('Dualstack', { 'ip_versions': (4, 6) })]) @classmethod def resource_setup(cls): super(SecGroupNuageTest, cls).resource_setup() cls.network = cls.create_cls_network() cls.subnet4 = cls.subnet6 = None if 4 in cls.ip_versions: cls.subnet4 = cls.create_cls_subnet(cls.network, ip_version=4) if 6 in cls.ip_versions: cls.subnet6 = cls.create_cls_subnet(cls.network, ip_version=6) cls.router = None if cls.is_l3: cls.router = cls.create_cls_router() if cls.subnet4: cls.router_cls_attach(cls.router, cls.subnet4) if cls.subnet6: cls.router_cls_attach(cls.router, cls.subnet6) cls.domain = cls.vsd.get_l3_domain_by_subnet(cls.subnet4 or cls.subnet6) else: cls.domain = cls.vsd.get_l2domain( by_subnet=cls.subnet4 or cls.subnet6) def _verify_sg(self, sg, ports, pg_expected_without_port=False, domain=None): """_verify_sg :param sg: Security Group :param ports: Ports currently using SG in class domain :param pg_expected_without_port: Is a PG expected even when there are no ports attached. :param domain: VSD domain where the PG is located """ domain = domain or self.domain # Retrieve by external id ext_id_filter = self.vsd.get_external_id_filter(sg['id']) pgs = domain.policy_groups.get(filter=ext_id_filter) if ports: # PG expected self.assertEqual(1, len(pgs), "Unexpected amount of PG found for SG.") else: if not pg_expected_without_port: # Pg cleaned up or never created self.assertEmpty(pgs, "Unexpected PG found") return else: # No cleanup expected, verify PG created for previous vport self.assertEqual(1, len(pgs), "Unexpected amount of PG found for SG.") pg = pgs[0] # Verify PG properties self.assertEqual(sg['name'], pg.description) self.assertEqual('SOFTWARE', pg.type) # Verify attached vports vports = pg.vports.get() self.assertEqual(len(ports), len(vports)) expected_ext_port_ids = { self.vsd.external_id(port['id']) for port in ports } actual_ext_vport_ids = {vport.external_id for vport in vports} self.assertEqual(expected_ext_port_ids, actual_ext_vport_ids) # Verify Sg Rules for sg_rule in sg['security_group_rules']: self._verify_sg_rule(pg, sg, sg_rule, domain=domain) def _verify_sg_rule(self, pg, sg, sg_rule, is_reverse_rule=False, domain=None): """_verify_sg_rule :param pg: Policygroup :param sg: Securitygroup :param sg_rule: security group rule to check :param is_reverse_rule: True if the rule is a reverse rule of an actual sg_rule. Used for not checking the reverse of a reverse rule. :param domain: VSD domain where ACL is located """ domain = domain or self.domain is_ipv4 = sg_rule['ethertype'] == 'IPv4' stateful_icmp_types = (n_constants.STATEFUL_ICMP_V4_TYPES if is_ipv4 else n_constants.STATEFUL_ICMP_V6_TYPES) ext_id_filter = self.vsd.get_external_id_filter(sg_rule['id']) if sg_rule['direction'] == 'ingress': acl_entry = domain.egress_acl_entry_templates.get_first( filter=ext_id_filter) else: acl_entry = domain.ingress_acl_entry_templates.get_first( filter=ext_id_filter) self.assertIsNotNone( acl_entry, "aclEntryTemplate not found for " "SG Rule: {}".format(sg_rule)) # Remote group id refers to another Policy Group remote_pg = None if sg_rule.get('remote_group_id'): ext_id_filter = self.vsd.get_external_id_filter( sg_rule['remote_group_id']) remote_pgs = domain.policy_groups.get(ext_id_filter) self.assertNotEmpty(remote_pgs, "Remote PG not found") remote_pg = remote_pgs[0] # Remote ip prefix refers to enterprise network / network macro enterprise_network = None if sg_rule.get('remote_ip_prefix'): ip_network = netaddr.IPNetwork(sg_rule['remote_ip_prefix']) enterprise_network = self._get_enterprise_network(ip_network) # Ethertype self.assertEqual(n_constants.PROTO_NAME_TO_NUM[sg_rule['ethertype']], acl_entry.ether_type) # Protocol os_protocol = sg_rule['protocol'] try: expected_protocol = int(os_protocol) except (ValueError, TypeError): if not os_protocol: expected_protocol = 'ANY' elif os_protocol == 'icmp' and sg_rule['ethertype'] == 'IPv6': expected_protocol = n_constants.PROTO_NAME_TO_NUM['icmpv6'] else: expected_protocol = n_constants.PROTO_NAME_TO_NUM[os_protocol] self.assertEqual(expected_protocol, acl_entry.protocol) # Stateful if not sg['stateful']: expected_stateful = False elif str(os_protocol) in ['icmp', 'icmpv6', 'ipv6-icmp', 1, 58]: if Topology.up_to_nuage('5.4') and not is_ipv4: # no support for icmp v6 in 5.4 expected_stateful = True else: # ICMP rules are not stateful unless special cases if (not sg_rule['port_range_min'] and not sg_rule['port_range_max']): expected_stateful = False elif (sg_rule['port_range_min'] not in stateful_icmp_types): expected_stateful = False else: expected_stateful = True else: expected_stateful = True self.assertEqual(expected_stateful, acl_entry.stateful) # Network Type if (sg_rule.get('remote_group_id') or sg_rule.get('remote_external_group_id')): expected_network_type = 'POLICYGROUP' elif sg_rule.get('remote_ip_prefix'): expected_network_type = 'ENTERPRISE_NETWORK' else: if Topology.from_nuage('20.10'): expected_network_type = 'ANY' else: # Legacy usage of ANY network macro / enterprise network expected_network_type = 'ENTERPRISE_NETWORK' self.assertEqual(expected_network_type, acl_entry.network_type) # Network ID if sg_rule.get('remote_external_group_id'): expected_network_id = sg_rule['remote_external_group_id'] elif sg_rule.get('remote_ip_prefix'): expected_network_id = enterprise_network.id elif sg_rule.get('remote_group_id'): expected_network_id = remote_pg.id else: if Topology.from_nuage('20.10'): # No network id, as ANY type is used expected_network_id = None else: # Legacy usage of ANY network macro / enterprise network address = '0.0.0.0/0' if is_ipv4 else '::/0' ip_network = netaddr.IPNetwork(address) enterprise_network = self._get_enterprise_network(ip_network) expected_network_id = enterprise_network.id self.assertEqual(expected_network_id, acl_entry.network_id) # Location type self.assertEqual('POLICYGROUP', acl_entry.location_type) # Location ID self.assertEqual(pg.id, acl_entry.location_id) # Action self.assertEqual('FORWARD', acl_entry.action) # DSCP self.assertEqual('*', acl_entry.dscp) # TCP/UDP specific attributes if sg_rule['protocol'] in ['tcp', 'udp']: # Source port self.assertEqual('*', acl_entry.source_port) # Destination port if (not sg_rule['port_range_min'] and not sg_rule['port_range_max']): expected_dest_port = '*' elif sg_rule['port_range_min'] == sg_rule['port_range_max']: expected_dest_port = str(sg_rule['port_range_min']) else: expected_dest_port = '{}-{}'.format(sg_rule['port_range_min'], sg_rule['port_range_max']) self.assertEqual(expected_dest_port, acl_entry.destination_port) # ICMP specific attributes elif sg_rule['protocol'] in ['icmp', 'icmpv6', 'ipv6-icmp', 1, 58]: if sg_rule['port_range_min']: self.assertEqual(str(sg_rule['port_range_min']), acl_entry.icmp_type) if sg_rule['port_range_max']: self.assertEqual(str(sg_rule['port_range_max']), acl_entry.icmp_code) # check reverse ICMP rule if needed if Topology.up_to_nuage('5.4') and not is_ipv4: # no support for icmpv6 reverse rules return else: acl_icmp_type = (int(acl_entry.icmp_type) if acl_entry.icmp_type != '*' else '*') if (acl_icmp_type not in stateful_icmp_types and not is_reverse_rule): sg_rule['direction'] = ('ingress' if sg_rule['direction'] == 'egress' else 'egress') self._verify_sg_rule(pg, sg, sg_rule, is_reverse_rule=True, domain=domain) def _get_enterprise_network(self, ip_network): if ip_network.version == 4: vsd_filter = 'address IS "{}" and netmask IS "{}"'.format( ip_network.ip, ip_network.netmask) else: vsd_filter = 'IPv6Address IS "{}"'.format(ip_network) enterprise_network = ( self.vsd.get_default_enterprise().enterprise_networks.get_first( filter=vsd_filter)) self.assertIsNotNone(enterprise_network) return enterprise_network @decorators.attr(type='smoke') def test_create_update_delete_sg(self): sg = self.create_security_group() sg2 = self.create_security_group() # Create for ipversions: # - normal rule, for all applicable protocols # - normal rule, TCP protocol, port 80 # - normal rule, UDP protocol, port 80, egress # - networkmacro rule for 90.0.0.0/24 # - remote group id rule for SG2 for ip_version in self.ip_versions: ethertype = 'IPv' + str(ip_version) # - normal rule, for all applicable protocols if ip_version == 6: if Topology.up_to_openstack('stein'): protocols = (n_constants.IPV6_PROTO_NAME + [n_constants.IPV6_PROTO_NAME_LEGACY]) else: # Train onwards, legacy is canonicalized # https://review.opendev.org/#/c/453346/14 protocols = n_constants.IPV6_PROTO_NAME else: protocols = n_constants.IPV4_PROTO_NAME for protocol in protocols: self.create_security_group_rule_with_manager( sg, protocol=protocol, direction='ingress', ethertype=ethertype) # - normal rule, TCP protocol, port 80 self.create_security_group_rule_with_manager(sg, protocol='tcp', direction='ingress', ethertype=ethertype, port_range_min=80, port_range_max=80) # - normal rule, UDP protocol, port 80, egress self.create_security_group_rule_with_manager(sg, protocol='udp', direction='egress', ethertype=ethertype, port_range_min=80, port_range_max=80) # - networkmacro rule for 90.0.0.0/24 or cafe:babe::/64 remote_ip_prefix = ('90.0.0.0/24' if ip_version == 4 else 'cafe:babe::/64') self.create_security_group_rule_with_manager( sg, direction='egress', ethertype=ethertype, remote_ip_prefix=remote_ip_prefix) # - remote group id rule for SG2 self.create_security_group_rule_with_manager( sg, direction='egress', ethertype=ethertype, remote_group_id=sg2['id']) port = self.create_port(self.network, security_groups=[sg['id']]) # Verify VSD # Get updated SG with SGRules sg = self.get_security_group(sg['id']) self._verify_sg(sg, ports=[port]) # Update Security group name name = "updated SG name" sg = self.update_security_group(sg, name=name) self._verify_sg(sg, ports=[port]) # Delete port from SG self.delete_port(port) # cleanup happens before 20.10, not after. pg_expected = Topology.from_nuage('20.10') self._verify_sg(sg, ports=[], pg_expected_without_port=pg_expected) def test_sg_rule_icmp(self): # ICMP has stateless and stateful types sg = self.create_security_group() for ip_version in self.ip_versions: if Topology.up_to_nuage('5.4') and ip_version == 6: # do not test ipv6 icmp on 5.4 and below continue ethertype = 'IPv' + str(ip_version) stateful_types = (n_constants.STATEFUL_ICMP_V4_TYPES if ip_version == 4 else n_constants.STATEFUL_ICMP_V6_TYPES) icmp_protocol = 'icmp' if ip_version == 4 else 'ipv6-icmp' # Create stateful rules for stateful_type in stateful_types: self.create_security_group_rule_with_manager( security_group=sg, direction='ingress', ethertype=ethertype, protocol=icmp_protocol, port_range_min=stateful_type, port_range_max=0) # Create stateless rule: icmp_type: 69 self.create_security_group_rule_with_manager( security_group=sg, direction='egress', ethertype=ethertype, protocol=icmp_protocol, port_range_min=69, port_range_max=0) # Check for cross-contamination between IPV4 and IPV6 stateful # types by creating with icmp_code that is stateful in the # other ethertype all_stateful_types = (n_constants.STATEFUL_ICMP_V4_TYPES + n_constants.STATEFUL_ICMP_V6_TYPES) for stateful_type in all_stateful_types: if stateful_type not in stateful_types: self.create_security_group_rule_with_manager( security_group=sg, direction='ingress', ethertype=ethertype, protocol=icmp_protocol, port_range_min=stateful_type, port_range_max=0) # Check legacy icmpv6 usage if ip_version == 6: self.create_security_group_rule_with_manager( security_group=sg, direction='egress', ethertype=ethertype, protocol='icmpv6', port_range_min=68, port_range_max=0) sg = self.get_security_group(sg['id']) port = self.create_port(self.network, security_groups=[sg['id']]) # Verify VSD # Get updated SG with SGRules sg = self.get_security_group(sg['id']) self._verify_sg(sg, ports=[port]) def test_sg_multiple_domains(self): network2 = self.create_network() subnet4 = subnet6 = None if 4 in self.ip_versions: subnet4 = self.create_subnet(network2, ip_version=4) if 6 in self.ip_versions: subnet6 = self.create_subnet(network2, ip_version=6) if self.is_l3: router = self.create_router() if subnet4: self.router_attach(router, subnet4) if subnet6: self.router_attach(router, subnet6) domain2 = self.vsd.get_l3_domain_by_subnet(subnet4 or subnet6) else: domain2 = self.vsd.get_l2domain(by_subnet=subnet4 or subnet6) # Create PG with rules, in self.network and network2 sg = self.create_security_group() for ip_version in self.ip_versions: ethertype = 'IPv' + str(ip_version) self.create_security_group_rule_with_manager(security_group=sg, direction='egress', ethertype=ethertype, protocol='tcp', port_range_min=1830, port_range_max=1830) port = self.create_port(self.network, security_groups=[sg['id']]) port2 = self.create_port(network2, security_groups=[sg['id']]) # Verify VSD # Get updated SG with SGRules sg = self.get_security_group(sg['id']) self._verify_sg(sg, ports=[port]) self._verify_sg(sg, ports=[port2], domain=domain2) def test_create_security_group_rule_invalid_ip_prefix_negative(self): # /0 cidr for a non-single ip prefix if 4 not in self.ip_versions: self.skipTest("Invalid ip prefix only applicable to IPv4") sg = self.create_security_group() self.create_security_group_rule_with_manager( security_group=sg, direction='ingress', ethertype='IPv4', protocol='tcp', port_range_min=76, port_range_max=77, remote_ip_prefix='192.168.1.0/0') msg = ('Non supported remote CIDR in security rule:' ' Does not match n.n.n.n where n=1-3' ' decimal digits and the mask is not all zeros , ' 'address is 192.168.1.0 , mask is 0.0.0.0') self.assertRaisesRegex(exceptions.BadRequest, msg, self.create_port, self.network, security_groups=[sg['id']]) def test_create_security_group_rule_invalid_nw_macro_negative(self): # Non /0 cidr for a single ip prefix. if 4 not in self.ip_versions: self.skipTest("Invalid ip prefix only applicable to IPv4") sg = self.create_security_group() self.create_security_group_rule_with_manager( security_group=sg, direction='ingress', ethertype='IPv4', protocol='tcp', port_range_min=1914, port_range_max=1918, remote_ip_prefix='172.16.50.210/24') msg = ('Non supported remote CIDR in security rule:' ' Network IP Address 172.16.50.210 must have' ' host bits set to 0.') self.assertRaisesRegex(exceptions.BadRequest, msg, self.create_port, self.network, security_groups=[sg['id']]) def test_create_security_group_rule_ipv6_ip_prefix(self): if 6 not in self.ip_versions: self.skipTest("Longer ip prefix only applicable to IPv6") sg = self.create_security_group() for prefix in [0, 1, 30, 63, 64, 65, 127, 128]: if prefix == 0: ip_prefix = '::/' + str(prefix) else: ip_prefix = '2001::/' + str(prefix) self.create_security_group_rule_with_manager( security_group=sg, direction='ingress', ethertype="IPv6", protocol='tcp', port_range_min=1940, port_range_max=1945, remote_ip_prefix=ip_prefix) port = self.create_port(self.network, security_groups=[sg['id']]) self._verify_sg(sg, [port]) def test_security_group_rule_invalid_ip_prefix_update_port_negative(self): # Update port with invalid security group if 4 not in self.ip_versions: self.skipTest("Invalid ip prefix only applicable to IPv4") sg = self.create_security_group() self.create_security_group_rule_with_manager( security_group=sg, direction='ingress', ethertype='IPv4', protocol='tcp', port_range_min=1815, port_range_max=1830, remote_ip_prefix='192.168.1.0/0') msg = ('Non supported remote CIDR in security rule:' ' Does not match n.n.n.n where n=1-3' ' decimal digits and the mask is not all zeros , address is' ' 192.168.1.0 , mask is 0.0.0.0') port = self.create_port(self.network, security_groups=[]) # Update port with illegal security group -> assert nothing changed self.assertRaisesRegex(exceptions.BadRequest, msg, self.update_port, port, security_groups=[sg['id']]) ext_id_filter = self.vsd.get_external_id_filter(sg['id']) pgs = self.domain.policy_groups.get(filter=ext_id_filter) self.assertEqual(len(pgs), 0) ext_id_filter = self.vsd.get_external_id_filter(port['id']) vport = self.domain.vports.get(filter=ext_id_filter)[0] self.assertEmpty(vport.policy_groups.get()) def test_remote_group_id_before_port_usage(self): """test_remote_ip_prefix_before_port_usage Use a SG as remote group id before using it on a port. """ sg = self.create_security_group() sg2 = self.create_security_group() for ip_version in self.ip_versions: ethertype = 'IPv' + str(ip_version) self.create_security_group_rule_with_manager(security_group=sg, direction='egress', ethertype=ethertype, protocol='tcp', port_range_min=1830, port_range_max=1830) self.create_security_group_rule_with_manager(security_group=sg2, direction='ingress', ethertype=ethertype, protocol='tcp', port_range_min=1789, port_range_max=1799) # Use SG2 as a remote group id in SG1 self.create_security_group_rule_with_manager( security_group=sg, direction='egress', ethertype=ethertype, remote_group_id=sg2['id']) port = self.create_port(self.network, security_groups=[sg['id']]) sg = self.get_security_group(sg['id']) sg2 = self.get_security_group(sg2['id']) self._verify_sg(sg, [port]) # Verify the entire SG was created correctly even though it is not used self._verify_sg(sg2, [], pg_expected_without_port=True) port2 = self.create_port(self.network, security_groups=[sg2['id']]) self._verify_sg(sg2, [port2]) def test_circular_remote_group_id(self): """"test_circular_remote_group_id Test whether a circular dependency between two SG within their rules is handled. """ sg = self.create_security_group() sg2 = self.create_security_group() for ip_version in self.ip_versions: ethertype = 'IPv' + str(ip_version) self.create_security_group_rule_with_manager( security_group=sg, direction='egress', ethertype=ethertype, remote_group_id=sg2['id']) self.create_security_group_rule_with_manager( security_group=sg2, direction='egress', ethertype=ethertype, remote_group_id=sg['id']) port = self.create_port(self.network, security_groups=[sg['id']]) sg = self.get_security_group(sg['id']) sg2 = self.get_security_group(sg2['id']) self._verify_sg(sg, [port]) self._verify_sg(sg2, [], pg_expected_without_port=True)
def skip_checks(cls): super(NuageExtraDHCPOptionsOSv6ManagedL2Test, cls).skip_checks() if not Topology.has_single_stack_v6_support(): msg = 'There is no single-stack v6 support in current release' raise cls.skipException(msg)
class AllowedAddressPairIpV6OSManagedTest(BaseAllowedAddressPair): _ip_version = 6 """Tests the Neutron Allowed Address Pair API extension The following API operations are tested with this extension: create port list ports update port show port v2.0 of the Neutron API is assumed. It is also assumed that the following options are defined in the [network-feature-enabled] section of etc/tempest.conf api_extensions """ _interface = 'json' @decorators.attr(type='smoke') def test_create_port_with_aap_ipv6_moving_from_l2_to_l3_validation(self): network = self.create_network() # Create port with allowed address pair attribute subnet4 = self.create_subnet( network, ip_version=4, enable_dhcp=True) subnet6 = self.create_subnet( network, ip_version=6, enable_dhcp=False) if CONF.nuage_sut.ipam_driver == 'nuage_vsd_managed': # If nuage_vsd_managed ipam is enabled, a nuage:vip port is needed port_args = { 'fixed_ips': [ {'ip_address': str(IPAddress(self.cidr6.first) + 10)}], 'device_owner': 'nuage:vip' } self.create_port(network, **port_args) port_args = {'fixed_ips': [ {'ip_address': str(IPAddress(self.cidr4.first) + 8)}, {'ip_address': str(IPAddress(self.cidr6.first) + 8)}], 'allowed_address_pairs': [ {'ip_address': str(IPAddress(self.cidr6.first) + 10), 'mac_address': VALID_MAC_ADDRESS}]} port = self.create_port(network, **port_args) # Confirm port was created with allowed address pair attribute self._verify_port( port, subnet4=subnet4, subnet6=subnet6) self._verify_l2_vport_by_id(port, SPOOFING_ENABLED, subnet4=subnet4) router = self.create_router() self.assertIsNotNone(router) vsd_l3_domain = self.vsd.get_l3domain(by_router_id=router['id']) self.assertIsNotNone(vsd_l3_domain) self.router_attach(router, subnet4) self._verify_l3_vport_by_id(router, port, SPOOFING_DISABLED, subnet4=subnet4) self.router_detach(router, subnet4) self._verify_l2_vport_by_id(port, SPOOFING_ENABLED, subnet4=subnet4) self.router_attach(router, subnet4) self._verify_l3_vport_by_id(router, port, SPOOFING_DISABLED, subnet4=subnet4) self.assertRaisesRegex( tempest_exceptions.Conflict, "One or more ports have an IP allocation from this subnet.", self.delete_subnet, subnet4) @decorators.attr(type='smoke') def test_delete_v6_subnet_with_ip_as_vip_in_v4_subnet_neg(self): network = self.create_network() subnet4 = self.create_subnet( network, ip_version=4, enable_dhcp=True) subnet6 = self.create_subnet( network, ip_version=6, enable_dhcp=False) router = self.create_router() self.router_attach(router, subnet4) port_args = {'fixed_ips': [{'subnet_id': subnet4['id'], 'ip_address': str(IPAddress(self.cidr4.first) + 10)}], 'allowed_address_pairs': [{'ip_address': str(IPAddress(self.cidr6.first) + 10), 'mac_address': VALID_MAC_ADDRESS}]} port = self.create_port(network, **port_args) msg = ('IP {} is in use for nuage VIP, hence cannot delete the subnet' ).format(port['allowed_address_pairs'][0]['ip_address']) self.assertRaisesRegex(tempest_exceptions.BadRequest, msg, self.delete_subnet, subnet6) @testtools.skipIf(not Topology.has_single_stack_v6_support(), 'There is no single-stack v6 support in current release') def test_delete_v4_subnet_with_ip_as_vip_in_v6_subnet_neg(self): network = self.create_network() subnet4 = self.create_subnet( network, ip_version=4, enable_dhcp=True) subnet6 = self.create_subnet( network, ip_version=6, enable_dhcp=False) router = self.create_router() self.router_attach(router, subnet6) port_args = {'fixed_ips': [{'subnet_id': subnet6['id'], 'ip_address': str( IPAddress(self.cidr6.first) + 10)}], 'allowed_address_pairs': [{'ip_address': str(IPAddress(self.cidr4.first) + 10), 'mac_address': VALID_MAC_ADDRESS}]} port = self.create_port(network, **port_args) msg = ('IP {} is in use for nuage VIP, hence cannot delete the subnet' ).format(port['allowed_address_pairs'][0]['ip_address']) self.assertRaisesRegex(tempest_exceptions.BadRequest, msg, self.delete_subnet, subnet4) @decorators.attr(type='smoke') def test_create_port_with_invalid_address_formats_neg_l2_and_l3(self): network = self.create_network() subnet4 = self.create_subnet( network, ip_version=4, enable_dhcp=True) subnet6 = self.create_subnet( network, ip_version=6, enable_dhcp=False) # noinspection PyPep8 reserved_valid_ipv6 = [ '::1', # Loopback 'FE80::1', # Link local address 'FF00:5f74:c4a5:b82e:ffff:ffff:ffff:ffff', # multicast 'FF00::1', # multicast address '::', # empty string '2001:ffff:ffff:ffff:ffff:ffff:ffff:ffff', # valid address, not in subnet ] invalid_ipv6 = [ ('', MSG_INVALID_INPUT_FOR_AAP_IPS), # empty string ("2001:5f74:c4a5:b82e:ffff:ffff:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_AAP_IPS), # invalid address, too much segments ("2001:5f74:c4a5:b82e:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_AAP_IPS), # invalid address, seven segments ("2001;5f74.c4a5.b82e:ffff:ffff:ffff", MSG_INVALID_INPUT_FOR_AAP_IPS), # invalid address, wrong characters ("2001:5f74:c4a5:b82e:100.12.13.1", MSG_INVALID_INPUT_FOR_AAP_IPS), # invalid format: must have :: between hex and decimal part. ] # ### L2 ##### for ipv6 in reserved_valid_ipv6: port_args = {'allowed_address_pairs': [ {'ip_address': ipv6, 'mac_address': VALID_MAC_ADDRESS}]} port = self.create_port(network, **port_args) self._verify_port( port, subnet4=subnet4, subnet6=subnet6) self._verify_l2_vport_by_id(port, SPOOFING_ENABLED, subnet4=subnet4) for ipv6, msg in invalid_ipv6: port_args = {'allowed_address_pairs': [ {'ip_address': ipv6, 'mac_address': VALID_MAC_ADDRESS}]} self.assertRaisesRegex(tempest_exceptions.BadRequest, msg % ipv6, self.create_port, network, **port_args) @decorators.attr(type='smoke') def test_fip2ipv6vip(self): # Base resources network = self.create_network() subnet4 = self.create_subnet( network, ip_version=4, enable_dhcp=True) subnet6 = self.create_subnet( network, ip_version=6, enable_dhcp=False) router = self.create_router( admin_state_up=True, external_network_id=CONF.network.public_network_id) self.assertIsNotNone(router, "Unable to create router") self.router_attach(router, subnet4) # Create VIP_port port_args = { 'allowed_address_pairs': [ {'ip_address': str(IPAddress(self.cidr4.first) + 7)}, {'ip_address': str(IPAddress(self.cidr6.first) + 7)} ], 'fixed_ips': [ {'subnet_id': subnet6['id'], 'ip_address': str(IPAddress(self.cidr6.first) + 11)}], 'device_owner': "nuage:vip"} vip_port = self.create_port(network=network, **port_args) self.assertIsNotNone(vip_port, "Unable to create vip port") # Create floating ip and attach to VIP_PORT floating_ip = self.create_floatingip() self.assertIsNotNone(floating_ip, "Unabe to create floating ip") msg = 'Cannot add floating IP to port %s that' \ ' has no fixed IPv4 addresses.' % vip_port['id'] self.assertRaisesRegex(tempest_exceptions.ClientRestClientException, msg, self.update_floatingip, floatingip=floating_ip, port_id=vip_port['id']) @decorators.attr(type='smoke') def test_provision_ports_without_address_pairs_in_l2_subnet_unmanaged( self): network = self.create_network() subnet4 = self.create_subnet( network, ip_version=4, enable_dhcp=True) subnet6 = self.create_subnet( network, ip_version=6, enable_dhcp=False) vsd_l2_domain = self.vsd.get_l2domain(by_subnet=subnet4) for scenario, port_config in iteritems(self.port_configs): LOG.info("TESTCASE scenario {}".format(scenario)) self._check_crud_port(scenario, network, subnet4, subnet6, vsd_l2_domain, constants.L2_DOMAIN) @decorators.attr(type='smoke') def test_provision_ports_with_address_pairs_in_l3_subnet(self): network = self.create_network() subnet4 = self.create_subnet( network, ip_version=4, enable_dhcp=True) subnet6 = self.create_subnet( network, ip_version=6, enable_dhcp=False) router = self.create_router() self.router_attach(router, subnet4) domain = self.vsd.get_domain(by_router_id=router['id']) zone = self.vsd.get_zone(domain=domain, by_router_id=router['id']) vsd_subnet = self.vsd.get_subnet(zone=zone, by_subnet=subnet4) for scenario, port_config in iteritems(self.port_configs): LOG.info("TESTCASE scenario {}".format(scenario)) self._check_crud_port(scenario, network, subnet4, subnet6, vsd_subnet, constants.SUBNETWORK)
def skip_checks(cls): super(TrunkTestJSONV6, cls).skip_checks() if not Topology.has_single_stack_v6_support(): msg = 'There is no single-stack v6 support in current release' raise cls.skipException(msg)
class AvrsOsManagedConnectivityTest(E2eTestBase): # Test scenarios, generate tests for product of these lists is_icmpv6_offload_supported = True if Topology.has_single_stack_v6_support(): scenarios = testscenarios.scenarios.multiply_scenarios([ ('L3', {'is_l3': True}), ('L2', {'is_l3': False}) ], [ ('IPv4', {'ip_versions': E2eTestBase.IP_VERSIONS_V4}), ('IPv6', {'ip_versions': E2eTestBase.IP_VERSIONS_V6}), ('Dualstack', {'ip_versions': E2eTestBase.IP_VERSIONS_DUALSTACK}) ]) else: scenarios = testscenarios.scenarios.multiply_scenarios([ ('L3', {'is_l3': True}), ('L2', {'is_l3': False}) ], [ ('IPv4', {'ip_versions': E2eTestBase.IP_VERSIONS_V4}), ('Dualstack', {'ip_versions': E2eTestBase.IP_VERSIONS_DUALSTACK}) ]) @classmethod def setUpClass(cls): super(AvrsOsManagedConnectivityTest, cls).setUpClass() hypervisors = cls.get_hypervisors('avrs') cls.selected_hypervisors = random.sample(hypervisors, min(2, len(hypervisors))) def dump_flows(self, hypervisor): """Dump flows on hypervisor""" flows = json.loads(self.execute_on_hypervisor( hypervisor, 'sudo fpcmd fp-vswitch-flows-json')) return AvrsFlowQuery(flows) def test_restart_avrs(self): if Topology.api_workers > 1: raise self.skipException('Skip OVS restart tests when multiple ' 'workers are present') # Provision OpenStack network resources. network = self.create_network() subnet = self.create_subnet(network) router = self.create_router( external_network_id=CONF.network.public_network_id) self.router_attach(router, subnet) # Create open-ssh security group. ssh_security_group = self.create_open_ssh_security_group() # Launch tenant servers in OpenStack network. server2 = self.create_tenant_server( [network], security_groups=[ssh_security_group], prepare_for_connectivity=True) server1 = self.create_tenant_server( [network], security_groups=[ssh_security_group], prepare_for_connectivity=True) # Test connectivity between peer servers. self.assert_ping(server1, server2, network) for hypervisor in self.selected_hypervisors: self.restart_avrs(hypervisor['host_ip']) # Test connectivity between peer servers again. self.assert_ping(server1, server2, network) def test_fast_path_same_hv_virtio_virtio(self): super( AvrsOsManagedConnectivityTest, self)._test_same_hv_virtio_virtio() def test_fast_path_diff_hv_virtio_virtio(self): super( AvrsOsManagedConnectivityTest, self)._test_diff_hv_virtio_virtio()
def skip_checks(cls): super(TestSecGroupScaleBase, cls).skip_checks() if (not Topology.has_single_stack_v6_support() and cls.ip_versions == (6, )): raise cls.skipException("Single Stack IPV6 not supported")