コード例 #1
0
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)
コード例 #3
0
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)
コード例 #5
0
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)
コード例 #6
0
 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)
コード例 #10
0
 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)
コード例 #11
0
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)
コード例 #12
0
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)
コード例 #14
0
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)
コード例 #15
0
 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')
コード例 #16
0
 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)
コード例 #17
0
 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)
コード例 #18
0
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')
コード例 #19
0
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)
コード例 #20
0
    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)
コード例 #21
0
 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)
コード例 #22
0
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)
コード例 #23
0
 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)
コード例 #24
0
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)
コード例 #25
0
 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)
コード例 #26
0
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()
コード例 #27
0
 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")