Merge "Tempest:Deploy and Validate Neutron resources using HEAT Template on NSXT|V"

This commit is contained in:
Jenkins 2017-04-27 16:05:00 +00:00 committed by Gerrit Code Review
commit aa93f2251e
5 changed files with 396 additions and 85 deletions

View File

View File

@ -22,60 +22,71 @@ from oslo_log import log as logging
from tempest.api.orchestration import base
from tempest.common.utils import data_utils
from tempest import config
from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
from vmware_nsx_tempest.services import nsxv3_client
from vmware_nsx_tempest.services import nsxv_client
CONF = config.CONF
LOG = logging.getLogger(__name__)
DIR_PATH = '/opt/stack/vmware-nsx/vmware_nsx_tempest/tests/'
class HeatSmokeTest(base.BaseOrchestrationTest,
manager.NetworkScenarioTest):
"""
Deploy and Test Neutron Resources using HEAT.
"""Deploy and Test Neutron Resources using HEAT.
The script load the neutron resources from template and fully
validates successful deployment of all resources from the template.
The template consists of two toplogies with Shared and Exclusive router.
Tests will be common to toplogies (pls refer template for topo info)and
will be as below :
1. verify created resources from template
2. verify all created resouces from template
-->neutronDB-->NSXbackend
3. check same network connectivity
4. check cross network connectivity
"""
def setUp(self):
super(HeatSmokeTest, self).setUp()
self.external_network = CONF.scenario.outside_world_servers
@classmethod
def setup_clients(cls):
super(HeatSmokeTest, cls).setup_clients()
cls.routers_client = cls.os.routers_client
cls.backend = CONF.network.backend
if cls.backend == 'nsxv3':
cls.filename = 'nsxt_neutron_smoke'
cls.nsx = nsxv3_client.NSXV3Client(CONF.nsxv3.nsx_manager,
CONF.nsxv3.nsx_user,
CONF.nsxv3.nsx_password)
elif cls.backend == 'nsxv':
cls.filename = 'nsxv_neutron_smoke'
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)
@classmethod
def setup_credentials(cls):
cls.set_network_resources()
super(HeatSmokeTest, cls).setup_credentials()
@classmethod
def read_template(cls, name, ext='yaml'):
loc = ["templates", "%s.%s" % (name, ext)]
filepath = os.path.join(DIR_PATH, *loc)
loc = ["tests", "templates", "%s.%s" % (name, ext)]
dir_path = os.path.dirname(__file__).split('/')
dir_path.pop()
dir_path = '/'.join(dir_path)
filepath = os.path.join(dir_path, *loc)
if os.path.isfile(filepath):
with open(filepath, "r") as f:
content = f.read()
return content
else:
raise IOError("File %s not found " % filepath)
raise IOError
@classmethod
def load_template(cls, name, ext='yaml'):
loc = ["templates", "%s.%s" % (name, ext)]
filepath = os.path.join(DIR_PATH, *loc)
loc = ["tests", "templates", "%s.%s" % (name, ext)]
dir_path = os.path.dirname(__file__).split('/')
dir_path.pop()
dir_path = '/'.join(dir_path)
filepath = os.path.join(dir_path, *loc)
if os.path.isfile(filepath):
with open(filepath, "r") as f:
return yaml.safe_load(f)
else:
raise IOError("File %s not found " % filepath)
raise IOError
@classmethod
def resource_setup(cls):
@ -83,11 +94,11 @@ class HeatSmokeTest(base.BaseOrchestrationTest,
cls.stack_name = data_utils.rand_name('heat')
try:
cls.neutron_basic_template = cls.load_template(
'nsxv_neutron_smoke')
template = cls.read_template('nsxv_neutron_smoke')
cls.filename)
template = cls.read_template(cls.filename)
except IOError as e:
LOG.exception(("file nsxv_neutron_smoke.yaml not found %(rsp)s") %
{'rsp': e})
LOG.exception(("file %(rsp)s not found %(rsp1)s") %
{'rsp': cls.filename, 'rsp1': e})
cls.stack_identifier = cls.create_stack(cls.stack_name, template)
cls.client.wait_for_stack_status(cls.stack_identifier,
'CREATE_COMPLETE')
@ -98,21 +109,6 @@ class HeatSmokeTest(base.BaseOrchestrationTest,
for resource in cls.resources:
cls.test_resources[resource['logical_resource_id']] = resource
@classmethod
def setup_credentials(cls):
cls.set_network_resources()
super(HeatSmokeTest, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(HeatSmokeTest, cls).setup_clients()
cls.routers_client = cls.os.routers_client
cls.subnets_client = cls.os.subnets_client
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)
def _resource_list_check(self, resource):
# sorts out the resources and returns resource id
if resource == 'networks':
@ -121,7 +117,6 @@ class HeatSmokeTest(base.BaseOrchestrationTest,
elif resource == 'routers':
body = self.routers_client.list_routers()
component = 'OS::Neutron::Router'
print(body)
elif resource == 'servers':
body = self.servers_client.list_servers()
component = 'OS::Nova::Server'
@ -157,9 +152,7 @@ class HeatSmokeTest(base.BaseOrchestrationTest,
{'dest': remote_ip, 'src': floating_ip})
raise
@decorators.idempotent_id('f693a425-b018-4cde-96ab-cdd5b858e15c')
@test.attr(type=["smoke"])
def test_created_resources(self):
def check_created_resources(self):
"""Verifies created resources from template ."""
for resource in self.resources:
msg = 'resource %s not create successfully' \
@ -168,35 +161,40 @@ class HeatSmokeTest(base.BaseOrchestrationTest,
msg)
self.assertIsInstance(resource, dict)
@decorators.idempotent_id('3c3ccfcb-e50b-4372-82dc-d5b473acd506')
@test.attr(type=["smoke"])
def test_created_network(self):
def check_created_network(self):
"""Verifies created neutron networks."""
network_id_list = self._resource_list_check(resource='networks')
for network_id in network_id_list:
body = self.networks_client.show_network(network_id)
self.assertEqual('True', str(body['network']['admin_state_up']))
self.assertEqual('True', str(body['network']
['admin_state_up']))
msg = 'newtwork %s not found' % body['network']['name']
self.assertIsNotNone(self.vsm.get_logical_switch(network_id), msg)
if self.backend == 'nsxv3':
self.assertIsNotNone(self.nsx.get_logical_switch(
body['network']['name'], body['network']['id']), msg)
elif self.backend == 'nsxv':
self.assertIsNotNone(self.vsm.get_logical_switch(network_id),
msg)
@decorators.idempotent_id('b3b103a7-69b2-42ea-a1b8-aa11cc551df9')
@test.attr(type=["smoke"])
def test_created_router(self):
def check_created_router(self):
"""Verifies created router."""
router_id_list = self._resource_list_check(resource='routers')
for router_id in router_id_list:
body = self.routers_client.show_router(router_id)
self.assertEqual('True', str(body['router']['admin_state_up']))
if (body['router']['router_type']) != 'shared':
router_edge_name = "%s-%s" % (
body['router']['name'], body['router']['id'])
exc_edge = self.vsm.get_edge(router_edge_name)
msg = 'exc edge %s not found' % body['router']['name']
self.assertTrue(exc_edge is not None, msg)
if self.backend == 'nsxv3':
msg = 'router %s not found' % body['router']['name']
self.assertIsNotNone(self.nsx.get_logical_router(
body['router']['name'], body['router']['id']), msg)
elif self.backend == 'nsxv':
if (body['router']['router_type']) != 'shared':
router_edge_name = "%s-%s" % (
body['router']['name'], body['router']['id'])
exc_edge = self.vsm.get_edge(router_edge_name)
msg = 'exc edge %s not found' % body['router']['name']
self.assertTrue(exc_edge is not None, msg)
@decorators.idempotent_id('2b29dfef-6d9f-4a70-9377-af432100ef10')
@test.attr(type=["smoke"])
def test_created_server(self):
def check_created_server(self):
"""Verifies created sever."""
server_id_list = self._resource_list_check(resource='servers')
for server_id in server_id_list:
@ -204,24 +202,20 @@ class HeatSmokeTest(base.BaseOrchestrationTest,
msg = 'server %s not active ' % (server)
self.assertEqual('ACTIVE', str(server['status']), msg)
@decorators.idempotent_id('d937a607-aa5e-4cf1-bbf9-00044cbe7190')
@test.attr(type=["smoke"])
def test_topo1_same_network_connectivity_(self):
def check_topo1_same_network_connectivity(self):
"""Verifies same network connnectivity for Topology 1 """
address_list = []
topo1_server1_floatingip = self.get_stack_output(self.stack_identifier,
'topo1_server1_floatingip')
server4_private_ip = self.get_stack_output(self.stack_identifier,
'topo1_server4_private_ip')
topo1_server1_floatingip = self.get_stack_output(
self.stack_identifier, 'topo1_server1_floatingip')
server4_private_ip = self.get_stack_output(
self.stack_identifier, 'topo1_server4_private_ip')
address_list.append(server4_private_ip)
LOG.info((" floating ip :%(rsp)s and private ip list : %(rsp1)s") %
LOG.info(" floating ip :%(rsp)s and private ip list : %(rsp1)s" %
{"rsp": topo1_server1_floatingip, "rsp1": address_list})
self._check_server_connectivity(topo1_server1_floatingip, address_list,
should_connect=True)
@decorators.idempotent_id('fdbc8b1a-755a-4b37-93e7-0a268e422f05')
@test.attr(type=["smoke"])
def test_topo1_cross_network_connectivity(self):
def check_topo1_cross_network_connectivity(self):
"""Verifies cross network connnectivity for Topology 1 """
address_list = []
topo1_server1_floatingip = self.get_stack_output(
@ -232,21 +226,19 @@ class HeatSmokeTest(base.BaseOrchestrationTest,
'topo1_server3_private_ip')
address_list.append(server2_private_ip)
address_list.append(server3_private_ip)
LOG.info(("floating ip :%(rsp)s and private ip list : %(rsp1)s") %
LOG.info("floating ip :%(rsp)s and private ip list : %(rsp1)s" %
{"rsp": topo1_server1_floatingip, "rsp1": address_list})
self._check_server_connectivity(topo1_server1_floatingip, address_list,
should_connect=True)
@decorators.idempotent_id('bcefd117-c55e-499d-a34b-653b8981f1c5')
@test.attr(type=["smoke"])
def test_topo1_cross_external_connectivity(self):
def check_topo1_external_connectivity(self):
"""Verifies external network connnectivity for Topology 1 """
address_list = []
topo1_server1_floatingip = self.get_stack_output(self.stack_identifier,
'topo1_server1_floatingip')
topo1_server1_floatingip = self.get_stack_output(
self.stack_identifier, 'topo1_server1_floatingip')
external_network = self.external_network[0]
address_list.append(external_network)
LOG.info(("floating ip :%(rsp)s and external ip : %(rsp1)s") %
LOG.info("floating ip :%(rsp)s and external ip : %(rsp1)s" %
{"rsp": topo1_server1_floatingip, "rsp1": address_list})
self._check_server_connectivity(topo1_server1_floatingip, address_list,
should_connect=True)
self._check_server_connectivity(topo1_server1_floatingip,
address_list, should_connect=True)

View File

@ -0,0 +1,58 @@
# Copyright 2017 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.
from tempest.lib import decorators
from vmware_nsx_tempest.lib import heat
class HeatTest(heat.HeatSmokeTest):
"""
Deploy and Test Neutron Resources using HEAT.
The script loads the neutron resources from template and fully
validates successful deployment of all resources from the template.
"""
@decorators.idempotent_id('fcc70627-dee0-466a-a59c-ae844a7ec59d')
def test_topo1_created_resources(self):
"""Verifies created resources from template ."""
self.check_created_resources()
@decorators.idempotent_id('ed1e9058-88b6-417e-bfa1-12531fa16cd0')
def test_topo1_created_network(self):
"""Verifies created neutron networks."""
self.check_created_network()
@decorators.idempotent_id('58a1f904-18c6-43b3-8d7b-c1246b65ac1b')
def test_topo1_created_router(self):
"""Verifies created router."""
self.check_created_router()
@decorators.idempotent_id('dece79ae-03e8-4d77-9484-5552a1f23412')
def test_topo1_created_server(self):
"""Verifies created sever."""
self.check_created_server()
@decorators.idempotent_id('6e6cc35c-d58c-490c-ad88-f085c260bc73')
def test_topo1_same_network(self):
"""Verifies same network connnectivity for Topology 1 """
self.check_topo1_same_network_connectivity()
@decorators.idempotent_id('1ae85f38-c78a-43ca-9b39-278131907681')
def test_topo1_cross_network(self):
"""Verifies cross network connnectivity for Topology 1 """
self.check_topo1_cross_network_connectivity()

View File

@ -0,0 +1,58 @@
# Copyright 2017 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.
from tempest.lib import decorators
from vmware_nsx_tempest.lib import heat
class HeatTest(heat.HeatSmokeTest):
"""
Deploy and Test Neutron Resources using HEAT.
The script loads the neutron resources from template and fully
validates successful deployment of all resources from the template.
"""
@decorators.idempotent_id('cb772c73-5948-4bd3-91d1-d85af2577362')
def test_topo1_created_resources(self):
"""Verifies created resources from template ."""
self.check_created_resources()
@decorators.idempotent_id('4f4cb71e-404f-4810-8898-5d6d70650016')
def test_topo1_created_network(self):
"""Verifies created neutron networks."""
self.check_created_network()
@decorators.idempotent_id('7e6452de-62c1-4daf-a031-013889b1d4ba')
def test_topo1_created_router(self):
"""Verifies created router."""
self.check_created_router()
@decorators.idempotent_id('24a3c0f8-3482-47fe-8c80-561a264a66d0')
def test_topo1_created_server(self):
"""Verifies created sever."""
self.check_created_server()
@decorators.idempotent_id('1fc3b998-d730-4f90-8ad2-bc4f2eeb7157')
def test_topo1_same_network(self):
"""Verifies same network connnectivity for Topology 1 """
self.check_topo1_same_network_connectivity()
@decorators.idempotent_id('aec9b109-2501-41de-9a24-444ced8b2668')
def test_topo1_cross_network(self):
"""Verifies cross network connnectivity for Topology 1 """
self.check_topo1_cross_network_connectivity()

View File

@ -0,0 +1,203 @@
heat_template_version: 2013-05-23
description: >
Topology 1:
- 4 servers (Cirros))
- 2 Logical Switches
- 1 Logical Router (Shared)
- 2 Security Group allowing HTTP
parameters:
public_net:
label: Public Network ID for external connectivity
type: string
description: >
ID or name of public network
# Need to update this network UUID for each vPod.
default: public
cirros_image:
default: cirros-0.3.3-x86_64-ESX
description: "cirros image"
type: string
resources:
# Topology1
heat_NAT_web_net:
type: OS::Neutron::Net
properties:
name: heat_NAT_web
heat_NAT_web_subnet:
type: OS::Neutron::Subnet
properties:
network_id: { get_resource: heat_NAT_web_net }
cidr: 10.21.1.0/24
dns_nameservers: [ "10.166.17.90" ]
heat_NAT_db_net:
type: OS::Neutron::Net
properties:
name: heat_NAT_db
heat_NAT_db_subnet:
type: OS::Neutron::Subnet
properties:
network_id: { get_resource: heat_NAT_db_net }
cidr: 10.21.2.0/24
dns_nameservers: [ "10.166.17.90" ]
my_key:
type: OS::Nova::KeyPair
properties:
save_private_key: true
name: my_key
router:
type: OS::Neutron::Router
properties:
admin_state_up: true
name: heat_NAT_router
router_gw:
type: OS::Neutron::RouterGateway
properties:
network_id: { get_param: public_net}
router_id: { get_resource: router }
router_interface1:
type: OS::Neutron::RouterInterface
properties:
router_id: { get_resource: router }
subnet_id: { get_resource: heat_NAT_web_subnet }
router_interface2:
type: OS::Neutron::RouterInterface
properties:
router_id: { get_resource: router }
subnet_id: { get_resource: heat_NAT_db_subnet }
heat_NAT_web_secgroup:
type: OS::Neutron::SecurityGroup
properties:
name: heat_NAT_web_secgroup
rules:
- protocol: tcp
remote_ip_prefix: 0.0.0.0/0
port_range_min: 443
port_range_max: 443
- protocol: tcp
remote_ip_prefix: 0.0.0.0/0
port_range_min: 22
port_range_max: 22
- protocol: icmp
remote_ip_prefix: 0.0.0.0/0
heat_NAT_db_secgroup:
type: OS::Neutron::SecurityGroup
properties:
name: heat_NAT_db_secgroup
rules:
- protocol: tcp
remote_mode: remote_group_id
remote_group_id: { get_resource: heat_NAT_web_secgroup }
port_range_min: 3307
port_range_max: 3307
- protocol: icmp
remote_ip_prefix: 0.0.0.0/0
server1_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: heat_NAT_web_net }
security_groups:
- { get_resource: heat_NAT_web_secgroup }
server1_instance:
type: OS::Nova::Server
properties:
image: { get_param: cirros_image}
flavor: m1.tiny
key_name: { get_resource: my_key }
networks:
- port: { get_resource: server1_port }
server1_floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network_id: { get_param: public_net }
port_id: { get_resource: server1_port }
server2_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: heat_NAT_db_net }
security_groups:
- { get_resource: heat_NAT_db_secgroup }
server2_instance:
type: OS::Nova::Server
properties:
image: { get_param: cirros_image}
flavor: m1.tiny
key_name: { get_resource: my_key }
networks:
- port: { get_resource: server2_port }
server3_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: heat_NAT_db_net }
security_groups:
- { get_resource: heat_NAT_db_secgroup }
server3_instance:
type: OS::Nova::Server
properties:
image: { get_param: cirros_image}
flavor: m1.tiny
key_name: { get_resource: my_key }
networks:
- port: { get_resource: server3_port }
server4_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: heat_NAT_web_net }
security_groups:
- { get_resource: heat_NAT_web_secgroup }
server4_instance:
type: OS::Nova::Server
properties:
image: { get_param: cirros_image}
flavor: m1.tiny
key_name: { get_resource: my_key }
networks:
- port: { get_resource: server4_port }
outputs:
topo1_server1_floatingip:
description: Floating IP address of Topology1_Server1_floatingip
value: { get_attr: [ server1_floating_ip, floating_ip_address ] }
topo1_server1_private_ip:
description: Private IP address of the deployed compute instance
value: { get_attr: [server1_instance, networks, heat_NAT_web, 0] }
topo1_server2_private_ip:
description: Private IP address of the deployed compute instance
value: { get_attr: [server2_instance, networks, heat_NAT_db, 0] }
topo1_server3_private_ip:
description: Private IP address of the deployed compute instance
value: { get_attr: [server3_instance, networks, heat_NAT_db, 0] }
topo1_server4_private_ip:
description: Private IP address of the deployed compute instance
value: { get_attr: [server4_instance, networks, heat_NAT_web, 0] }
private_key:
description: Private key
value: { get_attr: [ my_key, private_key ] }