349 lines
15 KiB
Python
349 lines
15 KiB
Python
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import time
|
|
|
|
from tempest import config
|
|
from tempest.lib.common.utils import data_utils
|
|
from tempest.lib import decorators
|
|
from tempest.lib import exceptions
|
|
|
|
from vmware_nsx_tempest_plugin.common import constants
|
|
from vmware_nsx_tempest_plugin.lib import feature_manager
|
|
CONF = config.CONF
|
|
|
|
|
|
class NetworkOpsTest(feature_manager.FeatureManager):
|
|
|
|
@classmethod
|
|
def skip_checks(cls):
|
|
super(NetworkOpsTest, cls).skip_checks()
|
|
if not (CONF.network_feature_enabled.ipv6 and
|
|
CONF.network_feature_enabled.ipv6_subnet_attributes):
|
|
raise cls.skipException('IPv6 or its attributes not supported')
|
|
if not (CONF.network.project_networks_reachable or
|
|
CONF.network.public_network_id):
|
|
msg = ('Either project_networks_reachable must be "true", or '
|
|
'public_network_id must be defined.')
|
|
raise cls.skipException(msg)
|
|
|
|
@classmethod
|
|
def setup_clients(cls):
|
|
super(NetworkOpsTest, cls).setup_clients()
|
|
cls.cmgr_adm = cls.get_client_manager('admin')
|
|
|
|
@classmethod
|
|
def resource_setup(cls):
|
|
super(NetworkOpsTest, cls).resource_setup()
|
|
|
|
def _create_ipv6_subnet(self, network, router, cidr=None):
|
|
subnet_client = self.cmgr_adm.subnets_client
|
|
subnet_name = network['name'] + 'ipv6-sub'
|
|
address_cidr = CONF.network.project_network_v6_cidr
|
|
address_prefixlen = CONF.network.project_network_v6_mask_bits
|
|
if ((address_prefixlen >= 126)):
|
|
msg = ("Subnet %s isn't large enough for the test" % address_cidr)
|
|
raise exceptions.InvalidConfiguration(msg)
|
|
if not cidr:
|
|
allocation_pools = {'allocation_pools': [{
|
|
'start': str(address_cidr).split('/')[0] + '2',
|
|
'end':str(address_cidr).split('/')[0] + '70'}]}
|
|
subnet = self.create_topology_subnet(
|
|
subnet_name, network,
|
|
subnets_client=subnet_client,
|
|
routers_client=self.cmgr_adm.routers_client,
|
|
router_id=router['id'],
|
|
ip_version=6, ipv6_ra_mode='slaac',
|
|
ipv6_address_mode='slaac',
|
|
**allocation_pools)
|
|
else:
|
|
subnet = self.create_topology_subnet(
|
|
subnet_name, network,
|
|
subnets_client=subnet_client,
|
|
routers_client=self.cmgr_adm.routers_client,
|
|
router_id=router['id'],
|
|
ip_version=6, ipv6_ra_mode='slaac',
|
|
ipv6_address_mode='slaac',
|
|
cidr=cidr)
|
|
return subnet
|
|
|
|
def _create_single_ipv6_rtr_topology(self):
|
|
"""Create dual stack network with IPv4
|
|
and IPv6 subnet and attach them to a
|
|
router
|
|
"""
|
|
name = data_utils.rand_name("dual-network")
|
|
networks_client = self.cmgr_adm.networks_client
|
|
network = self.create_topology_network(
|
|
name,
|
|
networks_client=networks_client)
|
|
sg = self._create_security_group(network)
|
|
rtr_name = data_utils.rand_name("dual-rtr")
|
|
router = self.create_topology_router(
|
|
rtr_name, routers_client=self.cmgr_adm.routers_client)
|
|
subnet_client = self.cmgr_adm.subnets_client
|
|
subnet_name = network['name'] + 'ipv4-sub'
|
|
self.create_topology_subnet(
|
|
subnet_name, network,
|
|
subnets_client=subnet_client,
|
|
routers_client=self.cmgr_adm.routers_client,
|
|
router_id=router['id'],
|
|
cidr='20.20.0.0/16')
|
|
subnet_v6 = self._create_ipv6_subnet(network, router)
|
|
time.sleep(constants.NSX_NETWORK_REALISE_TIMEOUT)
|
|
return network, router, sg, subnet_v6
|
|
|
|
def _create_single_rtr_multiple_net_topology(self):
|
|
"""Create two dual stack networks with IPv4
|
|
and IPv6 subnet and attach them to the
|
|
same router
|
|
"""
|
|
name = data_utils.rand_name("dual-network-1")
|
|
networks_client = self.cmgr_adm.networks_client
|
|
network_1 = self.create_topology_network(
|
|
name,
|
|
networks_client=networks_client)
|
|
sg = self._create_security_group(network_1)
|
|
name = data_utils.rand_name("dual-network-2")
|
|
network_2 = self.create_topology_network(
|
|
name,
|
|
networks_client=networks_client)
|
|
rtr_name = data_utils.rand_name("dual-rtr")
|
|
router = self.create_topology_router(
|
|
rtr_name, routers_client=self.cmgr_adm.routers_client)
|
|
subnet_client = self.cmgr_adm.subnets_client
|
|
subnet_name = network_1['name'] + 'ipv4-sub'
|
|
self.create_topology_subnet(
|
|
subnet_name, network_1,
|
|
subnets_client=subnet_client,
|
|
routers_client=self.cmgr_adm.routers_client,
|
|
router_id=router['id'],
|
|
cidr='10.10.0.0/16')
|
|
self._create_ipv6_subnet(
|
|
network_1, router,
|
|
cidr='2010::/64')
|
|
time.sleep(constants.NSX_NETWORK_REALISE_TIMEOUT)
|
|
subnet_name = network_2['name'] + 'ipv4-sub'
|
|
self.create_topology_subnet(
|
|
subnet_name, network_2,
|
|
subnets_client=subnet_client,
|
|
routers_client=self.cmgr_adm.routers_client,
|
|
router_id=router['id'],
|
|
cidr='20.20.0.0/16')
|
|
self._create_ipv6_subnet(
|
|
network_2, router,
|
|
cidr='2011::/64')
|
|
time.sleep(constants.NSX_NETWORK_REALISE_TIMEOUT)
|
|
networks = [network_1, network_2]
|
|
return networks, router, sg
|
|
|
|
def _create_multiple_rtr_multiple_net_topology(self):
|
|
"""Create two dual stack networks with IPv4
|
|
and IPv6 subnet and attach them to two
|
|
different router
|
|
"""
|
|
name = data_utils.rand_name("dual-network-1")
|
|
networks_client = self.cmgr_adm.networks_client
|
|
network_1 = self.create_topology_network(
|
|
name,
|
|
networks_client=networks_client)
|
|
sg = self._create_security_group(network_1)
|
|
rtr_name = data_utils.rand_name("dual-rtr-1")
|
|
router_1 = self.create_topology_router(
|
|
rtr_name, routers_client=self.cmgr_adm.routers_client)
|
|
subnet_client = self.cmgr_adm.subnets_client
|
|
subnet_name = network_1['name'] + 'ipv4-sub'
|
|
self.create_topology_subnet(
|
|
subnet_name, network_1,
|
|
subnets_client=subnet_client,
|
|
routers_client=self.cmgr_adm.routers_client,
|
|
router_id=router_1['id'],
|
|
cidr='10.10.0.0/16')
|
|
self._create_ipv6_subnet(
|
|
network_1, router_1,
|
|
cidr='2012::/64')
|
|
time.sleep(constants.NSX_NETWORK_REALISE_TIMEOUT)
|
|
name = data_utils.rand_name("dual-network-2")
|
|
network_2 = self.create_topology_network(
|
|
name,
|
|
networks_client=networks_client)
|
|
rtr_name = data_utils.rand_name("dual-rtr-2")
|
|
router_2 = self.create_topology_router(
|
|
rtr_name, routers_client=self.cmgr_adm.routers_client)
|
|
subnet_name = network_2['name'] + 'ipv4-sub'
|
|
self.create_topology_subnet(
|
|
subnet_name, network_2,
|
|
subnets_client=subnet_client,
|
|
routers_client=self.cmgr_adm.routers_client,
|
|
router_id=router_2['id'],
|
|
cidr='20.20.0.0/16')
|
|
self._create_ipv6_subnet(
|
|
network_2, router_2,
|
|
cidr='2013::/64')
|
|
time.sleep(constants.NSX_NETWORK_REALISE_TIMEOUT)
|
|
networks = [network_1, network_2]
|
|
routers = [router_1, router_2]
|
|
return networks, routers, sg
|
|
|
|
def _create_security_group(self, network):
|
|
sec_rule_client = self.cmgr_adm.security_group_rules_client
|
|
sec_client = self.cmgr_adm.security_groups_client
|
|
sg = self._create_empty_security_group(
|
|
namestart="tempest-ipv6-", client=sec_client)
|
|
common_ruleset = [dict(direction='ingress', ethertype='IPv6'),
|
|
dict(direction='ingress', ethertype='IPv4'),
|
|
dict(direction='ingress', protocol='tcp',
|
|
port_range_min=22, port_range_max=22)]
|
|
for rule in common_ruleset:
|
|
self._create_security_group_rule(
|
|
sec_group_rules_client=sec_rule_client,
|
|
security_groups_client=sec_client,
|
|
secgroup=sg,
|
|
**rule)
|
|
return sg
|
|
|
|
@decorators.attr(type=['nsxv3', 'positive'])
|
|
@decorators.idempotent_id('67dc21c8-0f40-4bee-bc03-e44538437e19')
|
|
def test_ipv4_v6_connectivity_same_network(self):
|
|
"""Test IPv4 and IPv6 connectivity across
|
|
VMs connected across same network
|
|
"""
|
|
# Create topology with single router
|
|
network, rtr, sg, subnet_v6 = self._create_single_ipv6_rtr_topology()
|
|
# Boot two VMs on the same network
|
|
image_id = self.get_glance_image_id(['cirros', 'esx'])
|
|
self.create_topology_instance(
|
|
"vm_1", [network],
|
|
security_groups=[{'name': sg['name']}],
|
|
create_floating_ip=True, image_id=image_id,
|
|
clients=self.cmgr_adm)
|
|
vm1_server_floatingip = self.topology_servers["vm_1"][
|
|
"floating_ips"][0]
|
|
self.create_topology_instance(
|
|
"vm_2", [network],
|
|
security_groups=[{'name': sg['name']}],
|
|
create_floating_ip=True, image_id=image_id,
|
|
clients=self.cmgr_adm)
|
|
vm2_server_floatingip = self.topology_servers["vm_2"][
|
|
"floating_ips"][0]
|
|
# Check IPv4 connectivity across the same network
|
|
vm1_server = self.topology_servers["vm_1"]
|
|
vm2_server = self.topology_servers["vm_2"]
|
|
self.check_vm_internal_connectivity(
|
|
network, vm1_server_floatingip, vm1_server)
|
|
self.check_vm_internal_connectivity(
|
|
network, vm2_server_floatingip, vm2_server)
|
|
# Check IPv6 connectivity across the same network
|
|
self.check_vm_internal_ipv6_connectivity(
|
|
network, vm1_server_floatingip, vm1_server)
|
|
self.check_vm_internal_ipv6_connectivity(
|
|
network, vm2_server_floatingip, vm2_server)
|
|
|
|
@decorators.attr(type=['nsxv3', 'positive'])
|
|
@decorators.idempotent_id('0074ae58-2de9-4cb2-a225-12a2b093f8d2')
|
|
def test_ipv4_v6_connectivity_same_rtr_diff_network(self):
|
|
"""Test IPv4 and IPv6 connectivity across
|
|
VMs connected across different networks
|
|
on the same router
|
|
"""
|
|
# Create topology with single router
|
|
networks, rtr, sg = self._create_single_rtr_multiple_net_topology()
|
|
# Boot two VMs on the different network
|
|
image_id = self.get_glance_image_id(['cirros', 'esx'])
|
|
self.create_topology_instance(
|
|
"vm_1", [networks[0]],
|
|
security_groups=[{'name': sg['name']}],
|
|
create_floating_ip=True, image_id=image_id, clients=self.cmgr_adm)
|
|
vm1_server_floatingip = self.topology_servers["vm_1"][
|
|
"floating_ips"][0]
|
|
self.create_topology_instance(
|
|
"vm_2", [networks[1]],
|
|
security_groups=[{'name': sg['name']}],
|
|
create_floating_ip=True, image_id=image_id, clients=self.cmgr_adm)
|
|
vm2_server_floatingip = self.topology_servers["vm_2"][
|
|
"floating_ips"][0]
|
|
vm1_server = self.topology_servers["vm_1"]
|
|
vm2_server = self.topology_servers["vm_2"]
|
|
# Check connectivity across differnet network
|
|
# checking VM2 Connectivity with VM1's network
|
|
self.check_cross_network_connectivity(
|
|
networks[0], vm2_server_floatingip, vm2_server,
|
|
should_connect=True)
|
|
# checking VM1 Connectivity with VM2's network
|
|
self.check_cross_network_connectivity(
|
|
networks[1], vm1_server_floatingip, vm1_server,
|
|
should_connect=True)
|
|
# checking VM2 IPv6 Connectivity with VM1's network
|
|
self.check_cross_network_ipv6_connectivity(
|
|
networks[0], vm2_server_floatingip, vm2_server,
|
|
should_connect=True)
|
|
# checking VM1 IPv6 Connectivity with VM2's network
|
|
self.check_cross_network_ipv6_connectivity(
|
|
networks[1], vm1_server_floatingip, vm1_server,
|
|
should_connect=True)
|
|
|
|
@decorators.attr(type=['nsxv3', 'positive'])
|
|
@decorators.idempotent_id('0074ae58-2de9-4cb2-a225-12a2b093f8d2')
|
|
def test_ipv4_v6_connectivity_diff_rtr_diff_network(self):
|
|
"""Test IPv4 and IPv6 connectivity across
|
|
VMs connected across different networks
|
|
on different router
|
|
"""
|
|
# Create topology with two router
|
|
networks, rtrs, sg = self._create_multiple_rtr_multiple_net_topology()
|
|
# Boot two VMs on the different network
|
|
image_id = self.get_glance_image_id(['cirros', 'esx'])
|
|
self.create_topology_instance(
|
|
"vm_1", [networks[0]],
|
|
security_groups=[{'name': sg['name']}],
|
|
create_floating_ip=True, image_id=image_id, clients=self.cmgr_adm)
|
|
vm1_server_floatingip = self.topology_servers["vm_1"][
|
|
"floating_ips"][0]
|
|
self.create_topology_instance(
|
|
"vm_2", [networks[1]],
|
|
security_groups=[{'name': sg['name']}],
|
|
create_floating_ip=True, image_id=image_id, clients=self.cmgr_adm)
|
|
vm2_server_floatingip = self.topology_servers["vm_2"][
|
|
"floating_ips"][0]
|
|
vm1_server = self.topology_servers["vm_1"]
|
|
vm2_server = self.topology_servers["vm_2"]
|
|
# Check connectivity across differnet network
|
|
# checking VM2 IPv6 Connectivity with VM1's network
|
|
self.check_cross_network_ipv6_connectivity(
|
|
networks[0], vm2_server_floatingip, vm2_server,
|
|
should_connect=True)
|
|
# checking VM1 IPv6 Connectivity with VM2's network
|
|
self.check_cross_network_ipv6_connectivity(
|
|
networks[1], vm1_server_floatingip, vm1_server,
|
|
should_connect=True)
|
|
|
|
@decorators.attr(type=['nsxv3', 'negative'])
|
|
@decorators.idempotent_id('d514dd1b-3816-47c8-86bc-c16d9f4eb80a')
|
|
def test_deletion_ipv6_subnet_attached_port(self):
|
|
"""
|
|
Verify the deletion of an IPv6 subnet is not possible
|
|
while port is attached to the subnet
|
|
"""
|
|
# Create topology with single router
|
|
network, rtr, sg, subnet_v6 = self._create_single_ipv6_rtr_topology()
|
|
# Boot two VMs on the same network
|
|
image_id = self.get_glance_image_id(['cirros', 'esx'])
|
|
self.create_topology_instance(
|
|
"vm_1", [network],
|
|
security_groups=[{'name': sg['name']}],
|
|
create_floating_ip=True, image_id=image_id,
|
|
clients=self.cmgr_adm)
|
|
self.assertRaises(exceptions.Conflict,
|
|
self.cmgr_adm.subnets_client.delete_subnet,
|
|
subnet_v6['id'])
|