vmware-nsx-tempest-plugin/vmware_nsx_tempest_plugin/tests/nsxv/scenario/test_multiple_transport_zon...

292 lines
13 KiB
Python

# Copyright 2016 OpenStack Foundation
# Copyright 2016 VMware Inc
# All Rights Reserved.
#
# 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 re
import six
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest import test
from vmware_nsx_tempest_plugin.services import nsxv_client
from vmware_nsx_tempest_plugin.tests.nsxv.scenario import (
manager_topo_deployment as dmgr)
from vmware_nsx_tempest_plugin.tests.nsxv.scenario import (
network_addon_methods as HELO)
CONF = config.CONF
class TestMultipleTransportZonesBasicOps(dmgr.TopoDeployScenarioManager):
"""Base class provides MTZ networks basic operations:
1: create MTZ networks and a tenant network.
2: create router and attached networks at step 1.
3: Boot one VM at each network.
4: select one VM, assign floatingip and from it ping other VMs'
fixed-ip to assure that VMs attached to different vdn_scope_ids,
and tennat network are asscessible.
"""
@classmethod
def skip_checks(cls):
super(TestMultipleTransportZonesBasicOps, cls).skip_checks()
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)
for ext in ['router', 'provider']:
if not test.is_extension_enabled(ext, 'network'):
msg = "%s extension not enabled." % ext
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
super(TestMultipleTransportZonesBasicOps, cls).resource_setup()
manager_ip = re.search(r"(\d{1,3}\.){3}\d{1,3}",
CONF.nsxv.manager_uri).group(0)
cls.vsm = nsxv_client.VSMClient(
manager_ip, CONF.nsxv.user, CONF.nsxv.password)
cls.nsxv_scope_ids = cls.get_all_scope_id_list(with_default_scope=True)
if len(cls.nsxv_scope_ids) < 2:
msg = "Only one transport zone deployed. Need at least 2."
raise cls.skipException(msg)
cls.provider_network_type = getattr(CONF.nsxv,
"provider_network_type",
'vxlan')
cls.MAX_MTZ = getattr(CONF.nsxv, 'max_mtz', 0) or 3
@classmethod
def resource_cleanup(cls):
super(TestMultipleTransportZonesBasicOps, cls).resource_cleanup()
@classmethod
def get_all_scope_id_list(cls, with_default_scope=False):
"""return all scope IDs w/wo the default scope defined in NSX."""
scopes = cls.vsm.get_all_vdn_scopes()
scope_id_list = [x['objectId'] for x in scopes]
if with_default_scope:
return scope_id_list
try:
scope_id_list.remove(CONF.nsxv.vdn_scope_id)
except Exception:
pass
return scope_id_list
def setup(self):
super(TestMultipleTransportZonesBasicOps, self).setUp()
self.tp_svrs = {}
def tearDown(self):
self.delete_all_servers()
super(TestMultipleTransportZonesBasicOps, self).tearDown()
def create_project_network_subnet(self, name_prefix='mtz-project',
client_mgr=None):
client_mgr = client_mgr or self.manager
network_name = data_utils.rand_name(name_prefix)
network, subnet = HELO.create_network_subnet(
self, client_mgr=client_mgr, name=network_name)
return (network['id'], network, subnet)
def create_mtz_network_subnet(self, scope_id, tenant_project_id,
cidr=None, cidr_offset=0):
"""MTZ networks can only be created by ADMIN
All tenant network resources will be created by ADMIN.
"""
networks_client = self.admin_manager.networks_client
subnets_client = self.admin_manager.subnets_client
network_name = data_utils.rand_name('mtz-net')
create_body = {'name': network_name,
'provider:network_type': self.provider_network_type,
'provider:physical_network': scope_id}
network = HELO.create_network(self, client=networks_client,
tenant_id=tenant_project_id,
**create_body)
subnet = HELO.create_subnet(self, network, client=subnets_client,
name=network_name,
tenant_id=tenant_project_id,
cidr=cidr, cidr_offset=cidr_offset)
lswitch_list = self.vsm.get_all_logical_switches(scope_id)
lswitch_list = [x for x in lswitch_list if x['name'] == network['id']]
msg = ("network=%s is not configured by specified vdn_scope_id=%s"
% (network['id'], scope_id))
self.assertTrue(len(lswitch_list) == 1, msg=msg)
return (network['id'], network, subnet)
def create_router_by_type(self, router_type, client=None,
name=None, **kwargs):
routers_client = client or self.manager.routers_client
create_kwargs = dict(namestart='mtz-', external_gateway_info={
"network_id": CONF.network.public_network_id})
if router_type in ('shared', 'exclusive'):
create_kwargs['router_type'] = router_type
elif router_type in ('distributed'):
create_kwargs['distributed'] = True
create_kwargs.update(**kwargs)
router = HELO.router_create(self, client=routers_client,
**create_kwargs)
return router
def create_router_and_add_interfaces(self, router_type, nets,
client_mgr=None):
client_mgr = client_mgr or self.admin_manager
routers_client = client_mgr.routers_client
router = self.create_router_by_type(router_type,
client=routers_client)
if router_type == 'exclusive':
router_nsxv_name = '%s-%s' % (router['name'], router['id'])
exc_edge = self.vsm.get_edge(router_nsxv_name)
self.assertIsNotNone(exc_edge)
self.assertEqual(exc_edge['edgeType'], 'gatewayServices')
for net_id, (s_id, network, subnet, sg) in six.iteritems(nets):
# import pdb; pdb.set_trace()
HELO.router_interface_add(self, router['id'], subnet['id'],
client=routers_client)
return router
def clear_router_gateway_and_interfaces(self, router, nets, client=None):
routers_client = client or self.manager.routers_client
HELO.router_gateway_clear(self, router['id'],
client=routers_client)
for net_id, (s_id, network, subnet, sg) in six.iteritems(nets):
test_utils.call_and_ignore_notfound_exc(
HELO.router_interface_delete,
self, router['id'], subnet['id'], client=routers_client)
def _test_router_with_network_and_mtz_networks(self, router_type):
"""router attached with multiple TZs and one tenant network."""
client_mgr = self.manager
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
nets = {}
net_id, network, subnet = self.create_project_network_subnet(
'mtz-tenant', client_mgr=client_mgr)
tenant_project_id = client_mgr.networks_client.tenant_id
# create security_group with loginable rules
security_group = self._create_security_group(
security_groups_client=client_mgr.security_groups_client,
security_group_rules_client=client_mgr.security_group_rules_client,
namestart='mtz-tenant')
nets[net_id] = [None, network, subnet, security_group]
for cidr_step in range(0, self.MAX_MTZ):
s_id = scope_id_list[cidr_step % len(scope_id_list)]
net_id, network, subnet = self.create_mtz_network_subnet(
s_id, tenant_project_id, cidr_offset=(cidr_step + 2))
nets[net_id] = [s_id, network, subnet, security_group]
router = self.create_router_and_add_interfaces(router_type, nets,
client_mgr=client_mgr)
return router, nets
def run_servers_connectivity_test(self, servers):
# select one from the servers
net_id_list = servers.keys()
net_id = net_id_list[0]
other_net_id_list = net_id_list[1:]
username, password = self.get_image_userpass()
nsv = self.tp_svrs[net_id]
serv = nsv['server']
floatingip = self.create_floatingip_for_server(
serv, client_mgr=self.manager)
msg = ("Associate floatingip[%s] to server[%s]"
% (floatingip, serv['name']))
self._check_floatingip_connectivity(
floatingip, serv, should_connect=True, msg=msg)
serv_fip = floatingip['floating_ip_address']
dmgr.rm_sshkey(serv_fip)
ssh_client = dmgr.get_remote_client_by_password(
serv_fip, username, password)
not_reachable_list = []
for nid in other_net_id_list:
o_svr = servers[nid]['server']
o_net = servers[nid]['network']
o_ipaddr = self.get_server_fixed_ip(o_svr, o_net)
reachable = dmgr.is_reachable(ssh_client, o_ipaddr)
if not reachable:
not_reachable_list.append(o_ipaddr)
self.assertTrue(
len(not_reachable_list) == 0,
("Following Servers are not reachable: %s" % not_reachable_list))
def get_server_fixed_ip(self, server, network):
addr_list = server['addresses'][network['name']]
for addr in addr_list:
if addr['OS-EXT-IPS:type'] == 'fixed':
return addr['addr']
return None
def wait_for_servers_become_active(self, servers, client=None):
servers_client = client or self.admin_manager.servers_client
net_id_list = servers.keys()
for net_id in net_id_list:
nsv = self.tp_svrs[net_id]
serv = nsv['server']
waiters.wait_for_server_status(
servers_client, serv['id'], 'ACTIVE')
# update server context. A server might not have ip address
# if not in running/active state
act_server = servers_client.show_server(serv['id'])
self.tp_svrs[net_id]['server'] = act_server.get('server',
act_server)
def delete_all_servers(self, client=None):
servers_client = client or self.admin_manager.servers_client
for net_id in six.iterkeys(self.tp_svrs):
server = self.tp_svrs[net_id]['server']
test_utils.call_and_ignore_notfound_exc(
servers_client.delete, server['id'])
dmgr.waitfor_servers_terminated(servers_client)
def run_mtz_basic_ops(self, router_type):
self.tp_svrs = {}
router, nets = self._test_router_with_network_and_mtz_networks(
router_type)
servers_client = self.manager.servers_client
for net_id in six.iterkeys(nets):
s_id, network, subnet, security_group = nets[net_id]
"""
servers_client = (self.manager.servers_client if s_id is None
else self.admin_manager.servers_client)
"""
security_groups = [{'name': security_group['id']}]
svr = self.create_server_on_network(
network, security_groups,
name=network['name'],
servers_client=servers_client,
wait_on_boot=False)
self.tp_svrs[net_id] = dict(server=svr, s_id=s_id,
network=network, subnet=subnet,
security_group=security_group,
servers_client=servers_client)
self.wait_for_servers_become_active(self.tp_svrs)
self.run_servers_connectivity_test(self.tp_svrs)
class TestMTZBasicOpsOverSharedRouter(TestMultipleTransportZonesBasicOps):
@decorators.idempotent_id('190790fe-4cc4-4bb3-ae3e-4fa2031ca4e2')
def test_mtz_basic_ops_over_shared_router(self):
self.run_mtz_basic_ops(router_type='shared')
class TestMTZBasicOpsOverExclusiveRouter(TestMultipleTransportZonesBasicOps):
@decorators.idempotent_id('caf2be55-ea49-4783-87bf-103fcc5783db')
def test_mtz_basic_ops_over_exclusive_router(self):
self.run_mtz_basic_ops(router_type='exclusive')