4a7989a5fc
1. l7policy and l7rules sunny day tests - very limit 2. enhance scenario tests to add reject policy & validate URL rejected when matched 3. fix scneario l7policy delete with framework delete function Change-Id: I63785e2e76c7793074215d393a965fb916422140
515 lines
20 KiB
Python
515 lines
20 KiB
Python
# Copyright 2015 Rackspace
|
|
#
|
|
# 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.
|
|
#
|
|
# 2016-03 (akang)
|
|
# ported from neutron-lbaas to comply to tempest framework
|
|
# NSX-v require vip-subnet attached to exclusive router
|
|
|
|
from oslo_log import log as logging
|
|
|
|
from tempest.api.network import base
|
|
from tempest import config
|
|
from tempest import test
|
|
|
|
from tempest.lib.common.utils import data_utils
|
|
from tempest.lib.common.utils import test_utils
|
|
from tempest.lib import exceptions
|
|
|
|
from vmware_nsx_tempest._i18n import _LI
|
|
from vmware_nsx_tempest.services.lbaas import health_monitors_client
|
|
from vmware_nsx_tempest.services.lbaas import l7policies_client
|
|
from vmware_nsx_tempest.services.lbaas import l7rules_client
|
|
from vmware_nsx_tempest.services.lbaas import listeners_client
|
|
from vmware_nsx_tempest.services.lbaas import load_balancers_client
|
|
from vmware_nsx_tempest.services.lbaas import members_client
|
|
from vmware_nsx_tempest.services.lbaas import pools_client
|
|
|
|
CONF = config.CONF
|
|
LOG = logging.getLogger(__name__)
|
|
NO_ROUTER_TYPE = CONF.nsxv.no_router_type
|
|
L7_POLICY_ACTIONS = ('REJECT', 'REDIRECT_TO_URL', 'REDIRECT_TO_POOL')
|
|
L7_RULE_TYPES = ('HOSTNAME', 'PATH', 'FILE_TYPE', 'HEADER', 'COOKIE')
|
|
L7_RULE_COMPARISON_TYPES = ('REGEXP', 'STARTS_WITH', 'ENDS_WITH',
|
|
'CONTAINS', 'EQUAL_TO')
|
|
|
|
|
|
class BaseTestCase(base.BaseNetworkTest):
|
|
|
|
# This class picks non-admin credentials and run the tempest tests
|
|
|
|
_lbs_to_delete = []
|
|
_setup_lbaas_non_admin_resource = True
|
|
|
|
@classmethod
|
|
def skip_checks(cls):
|
|
super(BaseTestCase, cls).skip_checks()
|
|
if not test.is_extension_enabled('lbaasv2', 'network'):
|
|
msg = "lbaasv2 extension not enabled."
|
|
raise cls.skipException(msg)
|
|
|
|
@classmethod
|
|
def resource_setup(cls):
|
|
super(BaseTestCase, cls).resource_setup()
|
|
|
|
if cls._setup_lbaas_non_admin_resource:
|
|
mgr = cls.get_client_manager()
|
|
cls.create_lbaas_clients(mgr)
|
|
cls.setup_lbaas_core_network()
|
|
|
|
@classmethod
|
|
def create_lbaas_clients(cls, mgr):
|
|
cls.load_balancers_client = load_balancers_client.get_client(mgr)
|
|
cls.listeners_client = listeners_client.get_client(mgr)
|
|
cls.pools_client = pools_client.get_client(mgr)
|
|
cls.members_client = members_client.get_client(mgr)
|
|
cls.health_monitors_client = health_monitors_client.get_client(mgr)
|
|
# l7-switching clients
|
|
cls.l7policies_client = l7policies_client.get_client(cls.manager)
|
|
cls.l7rules_client = l7rules_client.get_client(cls.manager)
|
|
|
|
@classmethod
|
|
def setup_lbaas_core_network(cls):
|
|
rand_number = data_utils.rand_name()
|
|
network_name = 'lbaas-network-' + rand_number
|
|
router_name = 'lbaas-router-' + rand_number
|
|
cls.network = cls.create_network(network_name)
|
|
cls.subnet = cls.create_subnet(cls.network)
|
|
cls.tenant_id = cls.subnet.get('tenant_id')
|
|
cls.subnet_id = cls.subnet.get('id')
|
|
# NSX-v: load-balancer's subnet need to attach to exclusive-router
|
|
router_cfg = dict(router_name=router_name, router_type='exclusive')
|
|
if NO_ROUTER_TYPE:
|
|
# router_type is NSX-v extension.
|
|
router_cfg.pop('router_type', None)
|
|
cls.router = cls.create_router(**router_cfg)
|
|
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
|
|
|
|
@classmethod
|
|
def resource_cleanup(cls):
|
|
for lb_id in cls._lbs_to_delete:
|
|
try:
|
|
statuses = cls._show_load_balancer_status_tree(lb_id)
|
|
lb = statuses.get('loadbalancer')
|
|
except exceptions.NotFound:
|
|
continue
|
|
for listener in lb.get('listeners', []):
|
|
for policy in listener.get('l7policies'):
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.l7policies_client.delete_l7policy,
|
|
policy.get('id'))
|
|
cls._wait_for_load_balancer_status(lb_id)
|
|
for pool in listener.get('pools'):
|
|
cls.delete_lb_pool_resources(lb_id, pool)
|
|
# delete listener
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.listeners_client.delete_listener,
|
|
listener.get('id'))
|
|
cls._wait_for_load_balancer_status(lb_id)
|
|
# delete pools not attached to listener, but loadbalancer
|
|
for pool in lb.get('pools', []):
|
|
cls.delete_lb_pool_resources(lb_id, pool)
|
|
# delete load-balancer
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls._delete_load_balancer, lb_id)
|
|
# NSX-v: delete exclusive router
|
|
cls.delete_router(cls.router)
|
|
super(BaseTestCase, cls).resource_cleanup()
|
|
|
|
@classmethod
|
|
def delete_lb_pool_resources(cls, lb_id, pool):
|
|
# delete pool's health-monitor
|
|
hm = pool.get('healthmonitor')
|
|
if hm:
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.health_monitors_client.delete_health_monitor,
|
|
pool.get('healthmonitor').get('id'))
|
|
cls._wait_for_load_balancer_status(lb_id)
|
|
# delete pool's members
|
|
members = pool.get('members', [])
|
|
for member in members:
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.members_client.delete_member,
|
|
pool.get('id'), member.get('id'))
|
|
cls._wait_for_load_balancer_status(lb_id)
|
|
# delete pool
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.pools_client.delete_pool, pool.get('id'))
|
|
cls._wait_for_load_balancer_status(lb_id)
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.LOG = logging.getLogger(cls._get_full_case_name())
|
|
super(BaseTestCase, cls).setUpClass()
|
|
|
|
def setUp(cls):
|
|
cls.LOG.info(_LI('Starting: {0}').format(cls._testMethodName))
|
|
super(BaseTestCase, cls).setUp()
|
|
|
|
def tearDown(cls):
|
|
super(BaseTestCase, cls).tearDown()
|
|
cls.LOG.info(_LI('Finished: {0}').format(cls._testMethodName))
|
|
|
|
@classmethod
|
|
def _create_load_balancer(cls, wait=True, **lb_kwargs):
|
|
lb = cls.load_balancers_client.create_load_balancer(**lb_kwargs)
|
|
lb = lb.get('loadbalancer', lb)
|
|
cls._lbs_to_delete.append(lb.get('id'))
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(lb.get('id'))
|
|
|
|
port = cls.ports_client.show_port(lb['vip_port_id'])
|
|
cls.ports.append(port['port'])
|
|
return lb
|
|
|
|
@classmethod
|
|
def _create_active_load_balancer(cls, **kwargs):
|
|
lb = cls._create_load_balancer(**kwargs)
|
|
lb = lb.get('loadbalancer', lb)
|
|
lb = cls._wait_for_load_balancer_status(lb.get('id'))
|
|
return lb
|
|
|
|
@classmethod
|
|
def _delete_load_balancer(cls, load_balancer_id, wait=True):
|
|
cls.load_balancers_client.delete_load_balancer(load_balancer_id)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(
|
|
load_balancer_id, delete=True)
|
|
|
|
@classmethod
|
|
def _update_load_balancer(cls, load_balancer_id, wait=True, **lb_kwargs):
|
|
lb = cls.load_balancers_client.update_load_balancer(
|
|
load_balancer_id, **lb_kwargs)
|
|
lb = lb.get('loadbalancer', lb)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(
|
|
load_balancer_id)
|
|
return lb
|
|
|
|
@classmethod
|
|
def _show_load_balancer(cls, load_balancer_id):
|
|
lb = cls.load_balancers_client.show_load_balancer(load_balancer_id)
|
|
lb = lb.get('loadbalancer', lb)
|
|
return lb
|
|
|
|
@classmethod
|
|
def _list_load_balancers(cls, **filters):
|
|
lbs = cls.load_balancers_client.list_load_balancers(**filters)
|
|
lb_list = lbs.get('loadbalancers', lbs)
|
|
return lb_list
|
|
|
|
@classmethod
|
|
def _wait_for_load_balancer_status(cls, load_balancer_id,
|
|
provisioning_status='ACTIVE',
|
|
operating_status='ONLINE',
|
|
delete=False):
|
|
return cls.load_balancers_client.wait_for_load_balancer_status(
|
|
load_balancer_id,
|
|
provisioning_status=provisioning_status,
|
|
operating_status=operating_status,
|
|
is_delete_op=delete)
|
|
|
|
@classmethod
|
|
def _show_load_balancer_status_tree(cls, load_balancer_id):
|
|
statuses = cls.load_balancers_client.show_load_balancer_status_tree(
|
|
load_balancer_id=load_balancer_id)
|
|
statuses = statuses.get('statuses', statuses)
|
|
return statuses
|
|
|
|
@classmethod
|
|
def _show_load_balancer_stats(cls, load_balancer_id):
|
|
stats = cls.load_balancers_client.show_load_balancer_stats(
|
|
load_balancer_id=load_balancer_id)
|
|
stats = stats.get('stats', stats)
|
|
return stats
|
|
|
|
@classmethod
|
|
def _create_listener(cls, wait=True, **listener_kwargs):
|
|
listener = cls.listeners_client.create_listener(**listener_kwargs)
|
|
listener = listener.get('listener', listener)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
return listener
|
|
|
|
@classmethod
|
|
def _delete_listener(cls, listener_id, wait=True):
|
|
cls.listeners_client.delete_listener(listener_id)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
|
|
@classmethod
|
|
def _update_listener(cls, listener_id, wait=True, **listener_kwargs):
|
|
listener = cls.listeners_client.update_listener(
|
|
listener_id, **listener_kwargs)
|
|
listener = listener.get('listener', listener)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(
|
|
cls.load_balancer.get('id'))
|
|
return listener
|
|
|
|
@classmethod
|
|
def _show_listener(cls, listener_id):
|
|
listener = cls.listeners_client.show_listener(listener_id)
|
|
listener = listener.get('listener', listener)
|
|
return listener
|
|
|
|
@classmethod
|
|
def _list_listeners(cls, **filters):
|
|
lbs = cls.listeners_client.list_listeners(**filters)
|
|
lb_list = lbs.get('listeners', lbs)
|
|
return lb_list
|
|
|
|
@classmethod
|
|
def _create_pool(cls, wait=True, **pool_kwargs):
|
|
pool = cls.pools_client.create_pool(**pool_kwargs)
|
|
pool = pool.get('pool', pool)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
return pool
|
|
|
|
@classmethod
|
|
def _delete_pool(cls, pool_id, wait=True):
|
|
cls.pools_client.delete_pool(pool_id)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
|
|
@classmethod
|
|
def _update_pool(cls, pool_id, wait=True, **pool_kwargs):
|
|
pool = cls.pools_client.update_pool(pool_id, **pool_kwargs)
|
|
pool = pool.get('pool', pool)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(
|
|
cls.load_balancer.get('id'))
|
|
return pool
|
|
|
|
@classmethod
|
|
def _show_pool(cls, pool_id):
|
|
pool = cls.pools_client.show_pool(pool_id)
|
|
pool = pool.get('pool', pool)
|
|
return pool
|
|
|
|
@classmethod
|
|
def _list_pools(cls, **filters):
|
|
pools = cls.pools_client.list_pools(**filters)
|
|
pool_list = pools.get('pools', pools)
|
|
return pool_list
|
|
|
|
def _create_health_monitor(self, wait=True, cleanup=True,
|
|
**health_monitor_kwargs):
|
|
hm = self.health_monitors_client.create_health_monitor(
|
|
**health_monitor_kwargs)
|
|
hm = hm.get('healthmonitor', hm)
|
|
if cleanup:
|
|
self.addCleanup(self._delete_health_monitor, hm.get('id'))
|
|
if wait:
|
|
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
|
|
return hm
|
|
|
|
def _delete_health_monitor(self, health_monitor_id, wait=True):
|
|
self.health_monitors_client.delete_health_monitor(health_monitor_id)
|
|
if wait:
|
|
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
|
|
|
|
def _update_health_monitor(self, health_monitor_id, wait=True,
|
|
**health_monitor_kwargs):
|
|
hm = self.health_monitors_client.update_health_monitor(
|
|
health_monitor_id, **health_monitor_kwargs)
|
|
hm = hm.get('healthmonitor', hm)
|
|
if wait:
|
|
self._wait_for_load_balancer_status(
|
|
self.load_balancer.get('id'))
|
|
return hm
|
|
|
|
def _show_health_monitor(self, health_monitor_id):
|
|
hm = self.health_monitors_client.show_health_monitor(health_monitor_id)
|
|
hm = hm.get('healthmonitor', hm)
|
|
return hm
|
|
|
|
def _list_health_monitors(self, **filters):
|
|
hms = self.health_monitors_client.list_health_monitors(**filters)
|
|
hm_list = hms.get('healthmonitors', hms)
|
|
return hm_list
|
|
|
|
@classmethod
|
|
def _create_member(cls, pool_id, wait=True, **member_kwargs):
|
|
member = cls.members_client.create_member(pool_id, **member_kwargs)
|
|
member = member.get('member', member)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
return member
|
|
|
|
@classmethod
|
|
def _delete_member(cls, pool_id, member_id, wait=True):
|
|
cls.members_client.delete_member(pool_id, member_id)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
|
|
@classmethod
|
|
def _update_member(cls, pool_id, member_id, wait=True,
|
|
**member_kwargs):
|
|
member = cls.members_client.update_member(
|
|
pool_id, member_id, **member_kwargs)
|
|
member = member.get('member', member)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(
|
|
cls.load_balancer.get('id'))
|
|
return member
|
|
|
|
@classmethod
|
|
def _show_member(cls, pool_id, member_id):
|
|
member = cls.members_client.show_member(pool_id, member_id)
|
|
member = member.get('member', member)
|
|
return member
|
|
|
|
@classmethod
|
|
def _list_members(cls, pool_id, **filters):
|
|
members = cls.members_client.list_members(pool_id, **filters)
|
|
member_list = members.get('members', members)
|
|
return member_list
|
|
|
|
@classmethod
|
|
def _create_l7policy(cls, wait=True, **kwargs):
|
|
l7policy = cls.l7policies_client.create_l7policy(**kwargs)
|
|
l7policy = l7policy.get('l7policy', l7policy)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
return l7policy
|
|
|
|
@classmethod
|
|
def _delete_l7policy(cls, policy_id, wait=True):
|
|
cls.l7policies_client.delete_l7policy(policy_id)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
|
|
@classmethod
|
|
def _update_l7policy(cls, policy_id, wait=True, **kwargs):
|
|
l7policy = cls.l7policies_client.update_l7policy(policy_id, **kwargs)
|
|
l7policy = l7policy.get('l7policy', l7policy)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
return l7policy
|
|
|
|
@classmethod
|
|
def _show_l7policy(cls, policy_id, **fields):
|
|
l7policy = cls.l7policies_client.show_l7policy(policy_id, **fields)
|
|
l7policy = l7policy.get('l7policy', l7policy)
|
|
return l7policy
|
|
|
|
@classmethod
|
|
def _list_l7policies(cls, **filters):
|
|
l7policies = cls.l7policies_client.list_l7policies(**filters)
|
|
l7policies = l7policies.get('l7policies', l7policies)
|
|
return l7policies
|
|
|
|
@classmethod
|
|
def _create_l7rule(cls, policy_id, wait=True, **kwargs):
|
|
l7rule = cls.l7rules_client.create_l7rule(policy_id, **kwargs)
|
|
l7rule = l7rule.get('rule', l7rule)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
return l7rule
|
|
|
|
@classmethod
|
|
def _delete_l7rule(cls, policy_id, rule_id, wait=True):
|
|
cls.l7rules_client.delete_l7rule(policy_id, rule_id)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
|
|
@classmethod
|
|
def _update_l7rule(cls, policy_id, rule_id, wait=True, **kwargs):
|
|
l7rule = cls.l7rules_client.update_l7rule(policy_id, rule_id,
|
|
**kwargs)
|
|
l7rule = l7rule.get('rule', l7rule)
|
|
if wait:
|
|
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
|
|
return l7rule
|
|
|
|
@classmethod
|
|
def _show_l7rule(cls, policy_id, rule_id, **fields):
|
|
l7rule = cls.l7rules_client.show_l7rule(policy_id, rule_id, **fields)
|
|
l7rule = l7rule.get('rule', l7rule)
|
|
return l7rule
|
|
|
|
@classmethod
|
|
def _list_l7rules(cls, policy_id, **filters):
|
|
l7rules = cls.l7rules_client.list_l7rules(policy_id, **filters)
|
|
l7rules = l7rules.get('rules', l7rules)
|
|
return l7rules
|
|
|
|
@classmethod
|
|
def _check_status_tree(cls, load_balancer_id, listener_ids=None,
|
|
pool_ids=None, health_monitor_id=None,
|
|
member_ids=None):
|
|
statuses = cls._show_load_balancer_status_tree(load_balancer_id)
|
|
load_balancer = statuses['loadbalancer']
|
|
assert 'ONLINE' == load_balancer['operating_status']
|
|
assert 'ACTIVE' == load_balancer['provisioning_status']
|
|
|
|
if listener_ids:
|
|
cls._check_status_tree_thing(listener_ids,
|
|
load_balancer['listeners'])
|
|
if pool_ids:
|
|
cls._check_status_tree_thing(pool_ids,
|
|
load_balancer['listeners']['pools'])
|
|
if member_ids:
|
|
cls._check_status_tree_thing(
|
|
member_ids,
|
|
load_balancer['listeners']['pools']['members'])
|
|
if health_monitor_id:
|
|
health_monitor = (
|
|
load_balancer['listeners']['pools']['health_monitor'])
|
|
assert health_monitor_id == health_monitor['id']
|
|
assert 'ACTIVE' == health_monitor['provisioning_status']
|
|
|
|
@classmethod
|
|
def _check_status_tree_thing(cls, actual_thing_ids, status_tree_things):
|
|
found_things = 0
|
|
status_tree_things = status_tree_things
|
|
assert len(actual_thing_ids) == len(status_tree_things)
|
|
for actual_thing_id in actual_thing_ids:
|
|
for status_tree_thing in status_tree_things:
|
|
if status_tree_thing['id'] == actual_thing_id:
|
|
assert 'ONLINE' == (
|
|
status_tree_thing['operating_status'])
|
|
assert 'ACTIVE' == (
|
|
status_tree_thing['provisioning_status'])
|
|
found_things += 1
|
|
assert len(actual_thing_ids) == found_things
|
|
|
|
@classmethod
|
|
def _get_full_case_name(cls):
|
|
name = '{module}:{case_name}'.format(
|
|
module=cls.__module__,
|
|
case_name=cls.__name__
|
|
)
|
|
return name
|
|
|
|
|
|
class BaseAdminTestCase(BaseTestCase):
|
|
|
|
# This class picks admin credentials and run the tempest tests
|
|
_setup_lbaas_non_admin_resource = False
|
|
|
|
@classmethod
|
|
def resource_setup(cls):
|
|
super(BaseAdminTestCase, cls).resource_setup()
|
|
|
|
cls.admin_mgr = cls.get_client_manager(credential_type='admin')
|
|
cls.admin_tenant_id = cls.admin_mgr.networks_client.tenant_id
|
|
cls.create_lbaas_clients(cls.admin_mgr)
|
|
cls.setup_lbaas_core_network()
|
|
|
|
@classmethod
|
|
def resource_cleanup(cls):
|
|
super(BaseAdminTestCase, cls).resource_cleanup()
|