Remove vmware_nsx_tempest

This now existsin the vmware_nsx_tempest_plugin

Change-Id: I76e5856deeeb06b87675314635d06aa0291143eb
Depends-On: I804c3fd1e0c9cbeb454677e7951072ad74391fec
This commit is contained in:
Gary Kotton 2017-07-28 15:01:01 +03:00 committed by garyk
parent 02c28ee5ea
commit 508c6262a2
143 changed files with 0 additions and 30124 deletions

View File

@ -21,8 +21,6 @@ classifier =
[files]
packages =
vmware_nsx
vmware_nsx_tempest
[entry_points]
console_scripts =
neutron-check-nsx-config = vmware_nsx.check_nsx_config:main
@ -53,8 +51,6 @@ vmware_nsx.neutron.nsxv.router_type_drivers =
shared = vmware_nsx.plugins.nsx_v.drivers.shared_router_driver:RouterSharedDriver
distributed = vmware_nsx.plugins.nsx_v.drivers.distributed_router_driver:RouterDistributedDriver
exclusive = vmware_nsx.plugins.nsx_v.drivers.exclusive_router_driver:RouterExclusiveDriver
tempest.test_plugins =
vmware-nsx-tempest-plugin = vmware_nsx_tempest.plugin:VMwareNsxTempestPlugin
oslo.config.opts =
nsx = vmware_nsx.opts:list_opts
networking_sfc.flowclassifier.drivers =

View File

@ -59,23 +59,10 @@ check_identical_policy_files () {
fi
}
check_no_duplicate_api_test_idempotent_ids() {
# For API tests, an idempotent ID is assigned to each single API test,
# those IDs should be unique
output=$(check-uuid --package vmware_nsx_tempest)
if [ "$?" -ne 0 ]; then
echo "There are duplicate idempotent ids in the API tests" >>$FAILURES
echo "please, assign unique uuids to each API test:" >>$FAILURES
echo "$output" >>$FAILURES
fi
}
# Add your checks here...
check_no_symlinks_allowed
check_pot_files_errors
#check_identical_policy_files
# Remove the comment below when we figure out how to consume pyshark
#check_no_duplicate_api_test_idempotent_ids
# Fail, if there are emitted failures
if [ -f $FAILURES ]; then

View File

@ -106,7 +106,6 @@ import-order-style = pep8
[hacking]
import_exceptions = vmware_nsx._i18n,
vmware_nsx_tempest._i18n
local-check-factory = neutron_lib.hacking.checks.factory
[testenv:genconfig]

View File

@ -1,92 +0,0 @@
Welcome!
========
vmware_nsx_tempest is a plugin module to openstack tempest project.
If you are not familiar with tempest, please refer to::
https://docs.openstack.org/developer/tempest
It is implemented with tempest external plugin.
The official design sepcification is at::
https://review.openstack.org/#/c/184992/
Overview
========
vmware_nsx_tempest hosts vmware_nsx's functional api and scenario tests.
All vmware_nsx_tempest tests are in "master" branch. For this reason,
it is recommended to have your own developer version of vmware-nsx repo
installed outside the devstack folder, /opt/stack/.
For example at /opt/devtest folder. In doing so, you can install
editable vmware-nsx repo under tempest VENV environemnt.
Installation:
-------------
#. On your own development folder, for example /opt/devtest/,
install your own tempest development env at /opt/devtest/os-tempest/::
$ cd /opt/devtest
$ git clone https://github.com/openstack/tempest os-tempest
#. Install virtualenv with the following command::
$ cd /opt/devtest/os-tempest
$ ./run_tempest.sh -u not_exist_tests
#. Install vmware-nsx master branch at /opt/devtest/vmware-nsx::
$ cd /opt/devtest
$ git clone https://github.com/openstack/vmware-nsx
#. Install vmware_nsx_tempest in your tempest development environment::
$ cd /opt/devtest/os-tempest
$ source .venv/bin/activate
$ pip install -e /opt/devtest/vmware-nsx/
Run command::
$ pip show vmware-nsx
You should observe the following statements::
Location: /opt/devtest/vmware-nsx
and under section of Entry-points::
[tempest.test_plugins]
vmware-nsx-tempest-plugin = vmware_nsx_tempest.plugin:VMwareNsxTempestPlugin
#. Validate installed vmware_nsx_tempest successfully do::
$ cd /opt/devtest/os-tempest
$ tools/with_venv.sh testr list-tests vmware_nsx_tempest.*l2_gateway
Your installation failed, if no tests are shown.
Execution:
----------
vmware_nsx_tempest tests are tempest tests, you need to
run from tempest directory. For example, to run only l2-gateway tests::
$ cd /opt/devtest/os-tempest
$ ./run_tempest.sh -t vmware_nsx_tempest.*test_l2_gateway
$ ./run_tempest.sh -d vmware_nsx_tempest.tests.nsxv.api.test_l2_gateway_connection.L2GatewayConnectionTest.test_csuld_single_device_interface_vlan
TechNote on vmware_nsx_tempest:
-------------------------------
vmware_nsx_tempest is a plugin to tempest, not neutron, nor vmware_nsx.
It is defined by tempest.test_plugins.
Modules within vmware_nsx_tempest can not see resources defined
by vmware_nsx. Commands like following are not acceptable, unless
vmware_nsx is installed in your tempest environment::
import vmware_nsx.shell.admin.plugins.common.utils as admin_utils

View File

@ -1,32 +0,0 @@
# 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 oslo_i18n
DOMAIN = "vmware-nsx-tempest"
_translators = oslo_i18n.TranslatorFactory(domain=DOMAIN)
# The primary translation function using the well-known name "_"
_ = _translators.primary
# The contextual translation function using the name "_C"
_C = _translators.contextual_form
# The plural translation function using the name "_P"
_P = _translators.plural_form
def get_available_languages():
return oslo_i18n.get_available_languages(DOMAIN)

View File

@ -1,61 +0,0 @@
# 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 oslo_log import log
LOG = log.getLogger(__name__)
# General constants.
ONE_SEC = 1
# L2GW constants.
L2GW = "l2_gateway"
L2GWS = L2GW + "s"
L2_GWS_BASE_URI = "/l2-gateways"
EXPECTED_HTTP_RESPONSE_200 = "200"
EXPECTED_HTTP_RESPONSE_201 = "201"
EXPECTED_HTTP_RESPONSE_204 = "204"
L2GWC = "l2_gateway_connection"
# MAC Learning constants
MAC_SW_PROFILE = "MacManagementSwitchingProfile"
PORT_SEC_PROFILE = "SpoofGuardSwitchingProfile"
SEC_GRPS_PROFILE = "SwitchSecuritySwitchingProfile"
# NSXV3 MDProxy constants.
MD_ERROR_CODE_WHEN_LS_BOUNDED = "10026"
INTERVAL_BETWEEN_EXEC_RETRY_ON_SSH = 5
MAX_NO_OF_TIMES_EXECUTION_OVER_SSH = 30
MD_BASE_URL = "http://169.254.169.254/"
# NSXV3 Port Security constants.
NSX_BACKEND_TIME_INTERVAL = 30
NSX_BACKEND_SMALL_TIME_INTERVAL = 10
NSX_BACKEND_VERY_SMALL_TIME_INTERVAL = 5
# DFW
NSX_FIREWALL_REALIZED_TIMEOUT = 120
# FWaaS
NO_OF_ENTRIES = 20
EXCLUSIVE_ROUTER = 'exclusive'
DISTRIBUTED_ROUTER = 'distributed'
TCP_PROTOCOL = 'tcp'
ICMP_PROTOCOL = 'icmp'
# NSXV3 Firewall
NSX_FIREWALL_REALIZED_DELAY = 2
APPLIANCE_NAME_STARTS_WITH = "vmw_"

View File

@ -1,199 +0,0 @@
# 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 oslo_config import cfg
from tempest import config
service_option = cfg.BoolOpt("vmware_nsx",
default=True,
help="Whether or not vmware_nsx is expected to be"
" available")
scenario_group = config.scenario_group
ScenarioGroup = [
cfg.FloatOpt('waitfor_disassoc',
default=15.0,
help="Wait for seconds after disassociation."),
cfg.FloatOpt('waitfor_assoc',
default=5.0,
help="Waitfor seconds after association."),
cfg.FloatOpt('waitfor_connectivity',
default=120.0,
help="Wait for seconds to become connected."),
cfg.ListOpt('outside_world_servers',
default=["8.8.8.8", "8.8.4.4"],
help="List of servers reside outside of openstack env."
" which is used to test default gateway behavior"
" when VMs are under logical routers,"
" & DNS are local to provider's settings."),
cfg.DictOpt('flat_alloc_pool_dict',
default={},
help="Define flat network ip range."
" required attributes are gateway, start, end"
" and cidr. Example value: gateway:10.1.1.253,"
" start:10.1.1.30,end:10.1.1.49,cidr=10.1.1.0/24"),
cfg.DictOpt('xnet_multiple_subnets_dict',
default={},
help="External network with multiple subnets."
" The primary subnet ip-range will be shrinked,"
" This is for the 2nd subnet, required attrs:"
" start:10.1.1.31,end:10.1.1.33,cidr=10.1.2.0/24"
" AND limit to only 3 ip addresses defined."),
]
network_group = config.network_group
NetworkGroup = [
cfg.StrOpt('l2gw_switch',
default='',
help="Distributed Virtual Portgroup to create VLAN port."),
cfg.DictOpt('l2gw_switch_dict',
default={},
help="dict version of l2gw_switch:"
"device_name:,interfaces:,segmentation_id:,"),
cfg.StrOpt('dns_search_domain',
default='vmware.com',
help="a valid domain that contains host defined at"
" attribute host_in_search_domain"),
cfg.StrOpt('host_in_search_domain',
default='mail',
help="host exists in dns_search_domain"),
cfg.StrOpt('public_network_cidr',
default='',
help="Public network cidr which provides external network"
" connectivity"),
cfg.StrOpt('backend',
default='nsxv',
help="NSX backend, valid values are nsxv|nsxv3"),
]
nsxv_group = cfg.OptGroup(name='nsxv',
title="NSX-v Configuration Options")
NSXvGroup = [
cfg.StrOpt('manager_uri',
default='https://10.0.0.10',
help="NSX-v manager ip address"),
cfg.StrOpt('user',
default='admin',
help="NSX-v manager username"),
cfg.StrOpt('password',
default='default',
help="NSX-v manager password"),
cfg.StrOpt('vdn_scope_id',
default='vdnscope-1',
help="NSX-v vdn scope id"),
cfg.IntOpt('max_mtz',
default=3,
help="Max Multiple Transport Zones used for testing."),
cfg.DictOpt('flat_alloc_pool_dict',
default={},
help=" Define flat network ip range."
" required attributes are gateway, start, end"
" and cidr. Example value: gateway:10.1.1.253,"
" start:10.1.1.30,end:10.1.1.49,cidr=10.1.1.0/24"),
cfg.StrOpt('vlan_physical_network',
default='',
help="physval_network to create vlan."),
cfg.IntOpt('provider_vlan_id',
default=888,
help="The default vlan_id for admin vlan."),
cfg.IntOpt('create_router_http_timeout',
default=900,
help="Specific for router_size tests. This value defines"
" how long http.request should retry."),
cfg.BoolOpt('no_router_type',
default=False,
help="router_type is NSXv extension."
"Set it to True allow tests to remove this attribute"
" when creating router."),
cfg.ListOpt('bugs_to_resolve',
default=[],
help="Bugs to be resolved. Define this at tempest.conf and"
" test case testtools.skipIf(condition, reasons) to"
" skip test cannot be run at specific plugin env."),
cfg.StrOpt('default_policy_id',
default='',
help="NSX security-policy ID used to create all tenants"
" default security-group-policy."
" This must be the same as the one at vmware/nsx.ini"),
cfg.StrOpt('alt_policy_id',
default='',
help="NSX security-policy ID used to create the 2nd"
" security-group-policy, and != default_policy_id."),
cfg.BoolOpt('allow_tenant_rules_with_policy',
default=False,
help="Default=False; a tenant cannot create security-group."
" If True, tenant can create non-policy security-group."
" Sync this value with nsx.ini file."),
]
l2gw_group = cfg.OptGroup(name='l2gw',
title="l2-gateway Configuration Options")
L2gwGroup = [
cfg.DictOpt('vlan_subnet_ipv4_dict',
default={},
help="Tenant's VLAN subnet cdir to connect to l2gw/VXLAN."
" Example: cidr=192.168.99.0/24,start:192.168.99.41"
" ,end:192.168.99.50,gateway=192.168.99.253"),
cfg.StrOpt('device_one_vlan',
default="",
help="l2g2 device with one VLAN"
" l2gw-1::dvportgroup-14420|3845"),
cfg.StrOpt('device_multiple_vlans',
default="",
help="l2gw device with multiple VLANs"
" l2gw-x::dvportgroup-14429|3880#3381#3382"),
cfg.StrOpt('multiple_interfaces_multiple_vlans',
default="",
help="l2gw multiple devices, interface has multiple VLANs"
" m-ifs::dvportgroup-144|138#246;dvportgroup-155|339"),
cfg.StrOpt('vlan_1',
default="16",
help="VLAN id"),
cfg.StrOpt('vlan_2',
default="17",
help="VLAN id"),
cfg.StrOpt("subnet_1_cidr",
default="192.168.1.0/24",
help="Subnet 1 network cidr."
"Example: 1.1.1.0/24"),
cfg.StrOpt('vm_on_vds_tz1_vlan16_ip',
default="192.168.1.203",
help="IPv4 IP address of VM3"),
cfg.StrOpt('vm_on_switch_vlan16',
default="192.168.1.204",
help="IPv4 IP address of VM4"),
cfg.StrOpt('vm_on_vds_tz2_vlan16_ip',
default="192.168.1.205",
help="IPv4 IP address of VM5"),
cfg.StrOpt('vm_on_vds_tz2_vlan17_ip',
default="192.168.1.206",
help="IPv4 IP address of VM6"),
]
nsxv3_group = cfg.OptGroup(name='nsxv3',
title="NSXv3 Configuration Options")
NSXv3Group = [
cfg.StrOpt('nsx_manager',
default='',
help="NSX manager IP address"),
cfg.StrOpt('nsx_user',
default='admin',
help="NSX manager username"),
cfg.StrOpt('nsx_password',
default='default',
help="NSX manager password"),
cfg.BoolOpt('native_dhcp_metadata',
default=False,
help="Enable or disable Native DHCP and MDProxy for nsxv3"),
]

View File

@ -1,90 +0,0 @@
Admin Policy
============
Admin policy, neutron extension secuirty-group-policy provides organization
to enforce traffic forwarding utilizing NSX security policy.
The "Admin Policy" feature is admin priviledge, normal project/tenant is not
able to create security-group-policy.
This feature can be enabled from devstack or manually.
Enable security-group-policy extention at bring up devstack
===========================================================
You can enable security-group-policy when starting up devstack.
However, if the policy-id does not exist, starting will fail.
To enable it, add the following tokens to local.conf:
NSXV_USE_NSX_POLICIES=True
NSXV_DEFAULT_POLICY_ID=policy-11
NSXV_ALLOW_TENANT_RULES_WITH_POLICY=True
Change values according to your needs though.
Enable security-group-policy extention manually
===============================================
Instruction is from the view of devstack
#. Add following items to /etc/neutron/policy.json::
"create_security_group:logging": "rule:admin_only",
"update_security_group:logging": "rule:admin_only",
"get_security_group:logging": "rule:admin_only",
"create_security_group:provider": "rule:admin_only",
"create_port:provider_security_groups": "rule:admin_only",
"create_security_group:policy": "rule:admin_only",
"update_security_group:policy": "rule:admin_only",
#. Add following key=value pair to session [nsxv] of /etc/neutron/plugin/vmware/nsx.ini::
use_nsx_policies = True
default_policy_id = policy-11
allow_tenant_rules_with_policy = False
# NOTE: For automation, set allow_tenant_rules_with_policy to True
tempest.conf
============
At session [nsxv] add the following 3 key=value pair:
default_policy_id = policy-11
alt_policy_id = policy-22
allow_tenant_rules_with_policy = False
# NOTE: default_policy_id and allow_tenant_rules_with_policy need to match nsx.ini
default_policy_id and alt_policy_id:
For API tests, both must exist at NSX.
For scenario tests, please refer to nsxv/scenario/test_admin_policy_basic_ops.py
In short::
policy-11 (policy-AA at script & test-plan) firewall rules::
action-1: dhcp-in/any/policy-security-groups/dhcp/Allow
action-2: dhcp-out/policy-security-groups/dhcp/Allow
action-3: ping-in/any/policy-security-groups/ICMP/Allow
action-4: ping-out/policy-security-groups/any/ICMP/Allow/
action-5: ssh-in/any/policy-security-groups/SSH/Allow/
action-6: ssh-in/any/policy-security-groups/SSH/Allow/
action-7: http-ok/any/policy-security-groups/HTTP,HTTPS/Allow/
action-8: sorry-nothing-allowed/any/policy-security-groups/Any/Reject
You can import policy-AA to NSX using the admin-policy-AA.blueprint
policy-22 (policy-BB at script & test-plan) firewall rules::
action-1: dhcp-in/any/policy-security-groups/dhcp/Allow
action-2: dhcp-out/policy-security-groups/dhcp/Allow
action-3: group-ping/policy-security-groups/policy-security-groups/ICMP/Allow/
action-4: ssh-in/any/policy-security-groups/SSH/Allow/
action-5: ssh-in/any/policy-security-groups/SSH/Allow/
action-6: http-ok/any/policy-security-groups/HTTP,HTTPS/Allow/
pction-7: sorry-nothing-allowed/any/policy-security-groups/Any/Reject
NOTE on ping: same as policy-11 but only allowed from policy-security-groups
You can import policy-BB to NSX using the admin-policy-BB.blueprint

View File

@ -1,74 +0,0 @@
Overview
========
This document describes what LBaaS tests are not supported at different
NSX plugin's and backends.
NOTE::
All LBaaS API & Scenario tests should PASS with exceptions
due to NSX plugins and features supported by backend.
For how tests can be skipped for specific plugin and backend,
please refer to paragraph "Config for Test Execution".
NOTE::
We no longer support LBaaS v1. So this document and LBaaS tests
only applys to releases from Mitaka/Marvin or later.
Limitation:
-----------
NSX-v with VMware LBaaS driver::
#. LBaaS networks need to attach to exclusive router
#. One tenant per subnet
#. L7 switching not supported
NSX-v3 with Octavia driver::
#. upstream implemenation - all tests should PASS.
#. scenario tests take long time, it might fail with fixture timeout.
Config for Test execution:
--------------------------
Following configuration attributes used to controll test execution::
#. no_router_type at group/session nsxv
Default is False, and is used to run LBaaS tests in NSX-v environment.
To run in NSX-t environment, set it to True
#. bugs_to_resolve at group/session nsxv
For test to skip if bug-ID presented in this attribute.
The test will use testtools.skipIf(condition, reason) to skip if its ID in the bugs_to_resolve list.
local.conf:
----------
NSX-v::
[nsxv]
no_router_type=False
bugs_to_resolve=1641902,1715126,1703396,1739510
NSX-v3::
[compute]
build_timeout=900
build_interval=2
[nsxv]
no_router_type=True
Execution:
----------
#. Use testr list-tests command to generate test suite for run API and Scenario tests::
tools/with_venv.sh testr list-tests nsxv.api.lbaas
tools/with_venv.sh testr list-tests nsxv.scenarion.test_lbaas
#. l7 switching tests take long time to complete. If got fixture timeout, do::
OS_TEST_TIMEOUT=2400 ./run_tempest.sh -t test_lbaas_l7_switching_ops

View File

@ -1,341 +0,0 @@
<securityPolicyHierarchy>
<name>admin-policy-AA</name>
<description>8 firewall rules - ping, ssh from anywhere are OK</description>
<securityPolicy>
<revision>0</revision>
<name>security-policy-AA</name>
<description>Security Policy AA</description>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>false</inheritanceAllowed>
<precedence>5500</precedence>
<actionsByCategory>
<category>firewall</category>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>dhcp-in</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>1</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>DHCP-Client</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>UDP</applicationProtocol>
<value>68</value>
</element>
</application>
<application>
<revision>0</revision>
<name>DHCP-Server</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>UDP</applicationProtocol>
<value>67</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>inbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>dhcp-out</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>2</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>DHCP-Client</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>UDP</applicationProtocol>
<value>68</value>
</element>
</application>
<application>
<revision>0</revision>
<name>DHCP-Server</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>UDP</applicationProtocol>
<value>67</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>outbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>ping-in</name>
<description>Everyone can ping me</description>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>3</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>ICMP Echo</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>echo-request</value>
</element>
</application>
<application>
<revision>0</revision>
<name>ICMP Redirect</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>redirect</value>
</element>
</application>
<application>
<revision>0</revision>
<name>ICMP Echo Reply</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>echo-reply</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>inbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>ping-out</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>4</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>ICMP Echo</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>echo-request</value>
</element>
</application>
<application>
<revision>0</revision>
<name>ICMP Redirect</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>redirect</value>
</element>
</application>
<application>
<revision>0</revision>
<name>ICMP Echo Reply</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>echo-reply</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>outbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>ssh-in-ok</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>5</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>SSH</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>TCP</applicationProtocol>
<value>22</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>inbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>ssh-out-ok</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>6</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>SSH</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>TCP</applicationProtocol>
<value>22</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>outbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>HTTP-ok</name>
<description>All can http(s) me</description>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>7</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>HTTP</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>TCP</applicationProtocol>
<value>80</value>
</element>
</application>
<application>
<revision>0</revision>
<name>HTTPS</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>TCP</applicationProtocol>
<value>443</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>inbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>sorry-nothing-allowed</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>8</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>reject</action>
<direction>inbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
</actionsByCategory>
<statusesByCategory>
<category>firewall</category>
<status>in_sync</status>
</statusesByCategory>
</securityPolicy>
</securityPolicyHierarchy>

View File

@ -1,285 +0,0 @@
<securityPolicyHierarchy>
<name>admin-policy-BB</name>
<description>policy-BB, ssh from anywhere are OK, but ping limited to same security-group</description>
<securityPolicy>
<revision>0</revision>
<name>security-policy-BB</name>
<description>Security Policy BB</description>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>false</inheritanceAllowed>
<precedence>5600</precedence>
<actionsByCategory>
<category>firewall</category>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>dhcp-in</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>1</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>DHCP-Client</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>UDP</applicationProtocol>
<value>68</value>
</element>
</application>
<application>
<revision>0</revision>
<name>DHCP-Server</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>UDP</applicationProtocol>
<value>67</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>inbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>dhcp-out</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>2</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>DHCP-Client</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>UDP</applicationProtocol>
<value>68</value>
</element>
</application>
<application>
<revision>0</revision>
<name>DHCP-Server</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>UDP</applicationProtocol>
<value>67</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>outbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>group-ping-ok</name>
<description>icmp only allowed from VM with same security-policy</description>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>3</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>ICMP Echo</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>echo-request</value>
</element>
</application>
<application>
<revision>0</revision>
<name>ICMP Redirect</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>redirect</value>
</element>
</application>
<application>
<revision>0</revision>
<name>ICMP Echo Reply</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>ICMP</applicationProtocol>
<value>echo-reply</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>intra</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>ssh-in-ok</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>4</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>SSH</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>TCP</applicationProtocol>
<value>22</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>inbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>ssh-out-ok</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>5</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>SSH</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>TCP</applicationProtocol>
<value>22</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>outbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>group-HTTP</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>6</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<applications>
<application>
<revision>0</revision>
<name>HTTP</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>TCP</applicationProtocol>
<value>80</value>
</element>
</application>
<application>
<revision>0</revision>
<name>HTTPS</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<inheritanceAllowed>true</inheritanceAllowed>
<element>
<applicationProtocol>TCP</applicationProtocol>
<value>443</value>
</element>
</application>
</applications>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>allow</action>
<direction>intra</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
<action class="firewallSecurityAction">
<revision>0</revision>
<name>sorry-nothing-allowed</name>
<clientHandle></clientHandle>
<isUniversal>false</isUniversal>
<universalRevision>0</universalRevision>
<category>firewall</category>
<executionOrder>7</executionOrder>
<isEnabled>true</isEnabled>
<isActionEnforced>false</isActionEnforced>
<invalidSecondaryContainers>false</invalidSecondaryContainers>
<invalidApplications>false</invalidApplications>
<logged>false</logged>
<action>reject</action>
<direction>inbound</direction>
<outsideSecondaryContainer>false</outsideSecondaryContainer>
</action>
</actionsByCategory>
<statusesByCategory>
<category>firewall</category>
<status>in_sync</status>
</statusesByCategory>
</securityPolicy>
</securityPolicyHierarchy>

View File

@ -1,234 +0,0 @@
# 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.
import collections
import netaddr
from oslo_log import log as logging
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions as lib_exc
from vmware_nsx_tempest.common import constants
from vmware_nsx_tempest.tests.scenario import manager
CONF = config.CONF
LOG = logging.getLogger(__name__)
class ApplianceManager(manager.NetworkScenarioTest):
server_details = collections.namedtuple('server_details',
['server', 'floating_ip',
'networks'])
def setUp(self):
super(ApplianceManager, self).setUp()
self.topology_routers = {}
self.topology_networks = {}
self.topology_subnets = {}
self.topology_servers = {}
self.topology_servers_floating_ip = []
self.topology_public_network_id = CONF.network.public_network_id
self.topology_config_drive = CONF.compute_feature_enabled.config_drive
self.topology_keypairs = {}
self.servers_details = {}
def get_internal_ips(self, server, network, device="network"):
internal_ips = [p['fixed_ips'][0]['ip_address'] for p in
self.os_admin.ports_client.list_ports(
tenant_id=server['tenant_id'],
network_id=network['id'])['ports'] if
p['device_owner'].startswith(device)]
return internal_ips
def _verify_empty_security_group_status(self, security_group):
ip_protocols = ["IPV6", "IPV4"]
nsx_fw_section, nsx_fw_section_rules = \
self.nsx_client.get_firewall_section_and_rules(
security_group['name'], security_group['id'])
msg = "Newly created empty security group does not meet criteria !!!"
self.assertEqual(nsx_fw_section["rule_count"], 2, msg)
self.assertEqual(nsx_fw_section_rules[0]["action"], "ALLOW", msg)
self.assertEqual(nsx_fw_section_rules[1]["action"], "ALLOW", msg)
self.assertEqual(nsx_fw_section_rules[0]["direction"], "OUT", msg)
self.assertEqual(nsx_fw_section_rules[1]["direction"], "OUT", msg)
self.assertIn(nsx_fw_section_rules[0]["ip_protocol"], ip_protocols,
msg)
self.assertIn(nsx_fw_section_rules[1]["ip_protocol"], ip_protocols,
msg)
def create_topology_empty_security_group(self, namestart="vmw_"):
security_group = self._create_empty_security_group(namestart=namestart)
self._verify_empty_security_group_status(security_group)
return security_group
def add_security_group_rule(self, security_group, rule):
return self._create_security_group_rule(secgroup=security_group,
**rule)
def get_server_key(self, server):
return self.topology_keypairs[server['key_name']]['private_key']
def create_topology_router(self, router_name, routers_client=None,
**kwargs):
if not routers_client:
routers_client = self.routers_client
router_name_ = constants.APPLIANCE_NAME_STARTS_WITH + router_name
router = self._create_router(namestart=router_name_, **kwargs)
public_network_info = {"external_gateway_info": dict(
network_id=self.topology_public_network_id)}
routers_client.update_router(router['id'], **public_network_info)
self.topology_routers[router_name] = router
return router
def create_topology_network(self, network_name, networks_client=None,
tenant_id=None, port_security_enabled=True, **kwargs):
if not networks_client:
networks_client = self.networks_client
if not tenant_id:
tenant_id = networks_client.tenant_id
network_name_ = constants.APPLIANCE_NAME_STARTS_WITH + network_name
name = data_utils.rand_name(network_name_)
# Neutron disables port security by default so we have to check the
# config before trying to create the network with port_security_enabled
if CONF.network_feature_enabled.port_security:
port_security_enabled = True
result = networks_client.create_network(
name=name, tenant_id=tenant_id,
port_security_enabled=port_security_enabled, **kwargs)
network = result['network']
self.assertEqual(network['name'], name)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
networks_client.delete_network, network['id'])
self.topology_networks[network_name] = network
return network
def create_topology_subnet(
self, subnet_name, network, routers_client=None,
subnets_client=None, router_id=None, ip_version=4, cidr=None,
mask_bits=None, **kwargs):
subnet_name_ = constants.APPLIANCE_NAME_STARTS_WITH + subnet_name
if not subnets_client:
subnets_client = self.subnets_client
if not routers_client:
routers_client = self.routers_client
def cidr_in_use(cidr, tenant_id):
"""Check cidr existence
:returns: True if subnet with cidr already exist in tenant
False else
"""
cidr_in_use = \
self.os_admin.subnets_client.list_subnets(tenant_id=tenant_id,
cidr=cidr)['subnets']
return len(cidr_in_use) != 0
if ip_version == 6:
tenant_cidr = (cidr or netaddr.IPNetwork(
CONF.network.project_network_v6_cidr))
mask_bits = mask_bits or CONF.network.project_network_v6_mask_bits
else:
tenant_cidr = cidr or netaddr.IPNetwork(
CONF.network.project_network_cidr)
mask_bits = mask_bits or CONF.network.project_network_mask_bits
str_cidr = str(tenant_cidr)
if not cidr:
# Repeatedly attempt subnet creation with sequential cidr
# blocks until an unallocated block is found.
for subnet_cidr in tenant_cidr.subnet(mask_bits):
str_cidr = str(subnet_cidr)
if not cidr_in_use(str_cidr, tenant_id=network['tenant_id']):
break
else:
if cidr_in_use(str_cidr, tenant_id=network['tenant_id']):
LOG.error("Specified subnet %r is in use" % str_cidr)
raise
subnet = dict(name=data_utils.rand_name(subnet_name_),
network_id=network['id'], tenant_id=network['tenant_id'],
cidr=str_cidr, ip_version=ip_version, **kwargs)
try:
result = None
result = subnets_client.create_subnet(**subnet)
except lib_exc.Conflict as e:
is_overlapping_cidr = 'overlaps with another subnet' in str(e)
if not is_overlapping_cidr:
raise
self.assertIsNotNone(result, 'Unable to allocate tenant network')
subnet = result['subnet']
self.assertEqual(subnet['cidr'], str_cidr)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
subnets_client.delete_subnet, subnet['id'])
self.topology_subnets[subnet_name] = subnet
if router_id:
if not routers_client:
routers_client = self.routers_client
routers_client.add_router_interface(
router_id, subnet_id=subnet["id"])
self.addCleanup(
test_utils.call_and_ignore_notfound_exc,
routers_client.remove_router_interface, router_id,
subnet_id=subnet["id"])
return subnet
def create_topology_security_group(self, **kwargs):
return self._create_security_group(**kwargs)
def create_topology_instance(
self, server_name, networks, security_groups=None,
config_drive=None, keypair=None, image_id=None,
clients=None, create_floating_ip=True, **kwargs):
# Define security group for server.
if security_groups:
kwargs["security_groups"] = security_groups
else:
_sg = self.create_topology_security_group()
_security_groups = [{'name': _sg['name']}]
kwargs["security_groups"] = _security_groups
# Define config drive for server.
if not config_drive:
kwargs["config_drive"] = self.topology_config_drive
else:
kwargs["config_drive"] = config_drive
if not keypair:
keypair = self.create_keypair()
self.topology_keypairs[keypair['name']] = keypair
kwargs["key_name"] = keypair['name']
else:
kwargs["key_name"] = keypair['name']
# Define image id for server.
if image_id:
kwargs["image_id"] = image_id
server_name_ = constants.APPLIANCE_NAME_STARTS_WITH + server_name
# Collect all the networks for server.
networks_ = []
for net in networks:
net_ = {"uuid": net["id"]}
networks_.append(net_)
# Deploy server with all teh args.
server = self.create_server(
name=server_name_, networks=networks_, clients=clients, **kwargs)
if create_floating_ip:
floating_ip = self.create_floating_ip(server)
server["floating_ip"] = floating_ip
self.topology_servers_floating_ip.append(floating_ip)
else:
floating_ip = None
server_details = self.server_details(server=server,
floating_ip=floating_ip,
networks=networks)
self.servers_details[server_name] = server_details
self.topology_servers[server_name] = server
return server

View File

@ -1,172 +0,0 @@
# 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 import config
from tempest.lib.common.utils import test_utils
from vmware_nsx_tempest._i18n import _
from vmware_nsx_tempest.common import constants
from vmware_nsx_tempest.lib import traffic_manager
from vmware_nsx_tempest.services import nsx_client
from vmware_nsx_tempest.services import openstack_network_clients
LOG = constants.log.getLogger(__name__)
CONF = config.CONF
# It includes feature related function such CRUD Mdproxy, L2GW or QoS
class FeatureManager(traffic_manager.TrafficManager):
@classmethod
def setup_clients(cls):
"""
Create various client connections. Such as NSXv3 and L2 Gateway.
"""
super(FeatureManager, cls).setup_clients()
try:
manager = getattr(cls.os_admin, "manager", cls.os_admin)
net_client = getattr(manager, "networks_client")
_params = manager.default_params_withy_timeout_values.copy()
except AttributeError as attribute_err:
LOG.warning(
"Failed to locate the attribute, Error: %(err_msg)s",
{"err_msg": attribute_err.__str__()})
_params = {}
cls.l2gw_client = openstack_network_clients.L2GatewayClient(
net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
cls.nsx_client = nsx_client.NSXClient(
CONF.network.backend,
CONF.nsxv3.nsx_manager,
CONF.nsxv3.nsx_user,
CONF.nsxv3.nsx_password)
cls.l2gwc_client = openstack_network_clients.L2GatewayConnectionClient(
net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
#
# L2Gateway base class. To get basics of L2GW.
#
def create_l2gw(self, l2gw_name, l2gw_param):
"""
Creates L2GW and returns the response.
:param l2gw_name: name of the L2GW
:param l2gw_param: L2GW parameters
:return: response of L2GW create API
"""
LOG.info("l2gw name: %(name)s, l2gw_param: %(devices)s ",
{"name": l2gw_name, "devices": l2gw_param})
devices = []
for device_dict in l2gw_param:
interface = [{"name": device_dict["iname"],
"segmentation_id": device_dict[
"vlans"]}] if "vlans" in device_dict else [
{"name": device_dict["iname"]}]
device = {"device_name": device_dict["dname"],
"interfaces": interface}
devices.append(device)
l2gw_request_body = {"devices": devices}
LOG.info(" l2gw_request_body: %s", l2gw_request_body)
rsp = self.l2gw_client.create_l2_gateway(
name=l2gw_name, **l2gw_request_body)
LOG.info(" l2gw response: %s", rsp)
self.addCleanup(
test_utils.call_and_ignore_notfound_exc,
self.l2gw_client.delete_l2_gateway, rsp[constants.L2GW]["id"])
return rsp, devices
def delete_l2gw(self, l2gw_id):
"""
Delete L2gw.
:param l2gw_id: L2GW id to delete l2gw.
:return: response of the l2gw delete API.
"""
LOG.info("L2GW id: %(id)s to be deleted.", {"id": l2gw_id})
rsp = self.l2gw_client.delete_l2_gateway(l2gw_id)
LOG.info("response : %(rsp)s", {"rsp": rsp})
return rsp
def update_l2gw(self, l2gw_id, l2gw_new_name, devices):
"""
Update existing L2GW.
:param l2gw_id: L2GW id to update its parameters.
:param l2gw_new_name: name of the L2GW.
:param devices: L2GW parameters.
:return: Response of the L2GW update API.
"""
rsp = self.l2gw_client.update_l2_gateway(l2gw_id,
name=l2gw_new_name, **devices)
return rsp
def nsx_bridge_cluster_info(self):
"""
Collect the device and interface name of the nsx brdige cluster.
:return: nsx bridge id and display name.
"""
response = self.nsx_client.get_bridge_cluster_info()
if len(response) == 0:
raise RuntimeError(_("NSX bridge cluster information is null"))
return [(x.get("id"), x.get("display_name")) for x in response]
def create_l2gw_connection(self, l2gwc_param):
"""
Creates L2GWC and return the response.
:param l2gwc_param: L2GWC parameters.
:return: response of L2GWC create API.
"""
LOG.info("l2gwc param: %(param)s ", {"param": l2gwc_param})
l2gwc_request_body = {"l2_gateway_id": l2gwc_param["l2_gateway_id"],
"network_id": l2gwc_param["network_id"]}
if "segmentation_id" in l2gwc_param:
l2gwc_request_body["segmentation_id"] = l2gwc_param[
"segmentation_id"]
LOG.info("l2gwc_request_body: %s", l2gwc_request_body)
rsp = self.l2gwc_client.create_l2_gateway_connection(
**l2gwc_request_body)
LOG.info("l2gwc response: %s", rsp)
self.addCleanup(
test_utils.call_and_ignore_notfound_exc,
self.l2gwc_client.delete_l2_gateway_connection,
rsp[constants.L2GWC]["id"])
return rsp
def delete_l2gw_connection(self, l2gwc_id):
"""
Delete L2GWC and returns the response.
:param l2gwc_id: L2GWC id to delete L2GWC.
:return: response of the l2gwc delete API.
"""
LOG.info("L2GW connection id: %(id)s to be deleted",
{"id": l2gwc_id})
rsp = self.l2gwc_client.delete_l2_gateway_connection(l2gwc_id)
LOG.info("response : %(rsp)s", {"rsp": rsp})
return rsp

View File

@ -1,65 +0,0 @@
# 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 vmware_nsx_tempest.lib import appliance_manager
class TrafficManager(appliance_manager.ApplianceManager):
def check_server_internal_ips_using_floating_ip(self, floating_ip, server,
address_list, should_connect=True):
ip_address = floating_ip['floating_ip_address']
private_key = self.get_server_key(server)
ssh_source = self.get_remote_client(ip_address,
private_key=private_key)
for remote_ip in address_list:
self.check_remote_connectivity(ssh_source, remote_ip,
should_succeed=should_connect)
def check_network_internal_connectivity(self, network, floating_ip, server,
should_connect=True):
"""via ssh check VM internal connectivity:
- ping internal gateway and DHCP port, implying in-tenant connectivity
pinging both, because L3 and DHCP agents might be on different nodes
"""
# get internal ports' ips:
# get all network ports in the new network
internal_ips = self.get_internal_ips(server, network, device="network")
self.check_server_internal_ips_using_floating_ip(floating_ip, server,
internal_ips, should_connect)
def check_vm_internal_connectivity(self, network, floating_ip, server,
should_connect=True):
# test internal connectivity to the other VM on the same network
compute_ips = self.get_internal_ips(server, network, device="compute")
self.check_server_internal_ips_using_floating_ip(floating_ip, server,
compute_ips, should_connect)
def using_floating_ip_check_server_and_project_network_connectivity(self,
server_details, network=None):
if not network:
network = server_details.networks[0]
floating_ip = server_details.floating_ip
server = server_details.server
self.check_network_internal_connectivity(network, floating_ip, server)
self.check_vm_internal_connectivity(network, floating_ip, server)
def check_cross_network_connectivity(self, network1,
floating_ip_on_network2, server_on_network2, should_connect=False):
# test internal connectivity to the other VM on the same network
remote_ips = self.get_internal_ips(server_on_network2, network1,
device="compute")
self.check_server_internal_ips_using_floating_ip(
floating_ip_on_network2, server_on_network2, remote_ips,
should_connect)

View File

@ -1,60 +0,0 @@
# Copyright 2015 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 os
from tempest import config
from tempest.test_discover import plugins
from vmware_nsx_tempest import config as config_nsx
_opts = [
(config_nsx.scenario_group, config_nsx.ScenarioGroup),
(config_nsx.network_group, config_nsx.NetworkGroup),
(config_nsx.nsxv_group, config_nsx.NSXvGroup),
(config_nsx.l2gw_group, config_nsx.L2gwGroup),
(config_nsx.nsxv3_group, config_nsx.NSXv3Group)
]
class VMwareNsxTempestPlugin(plugins.TempestPlugin):
"""Our addon configuration is defined at vmware_nsx_tempest/config.py
1. register_opts() to register group/opts to Tempest
2. get_opt_lists() to pass config to Tempest
The official plugin is defined at
https://docs.openstack.org/developer/tempest/plugin.html
"""
def load_tests(self):
mydir = os.path.dirname(os.path.abspath(__file__))
base_path = os.path.split(mydir)[0]
test_dir = "vmware_nsx_tempest/tests"
test_fullpath = os.path.join(base_path, test_dir)
return test_fullpath, base_path
def register_opts(self, conf):
conf.register_opt(config_nsx.service_option,
group='service_available')
for group, option in _opts:
config.register_opt_group(conf, group, option)
def get_opt_lists(self):
return [(group.name, option) for group, option in _opts
].append(('service_available', [config_nsx.service_option]))

View File

@ -1,42 +0,0 @@
This folder contains services for managing NSX-v, NSX-v3.
Services provided:
# OpenStack tempest service clients
l2_gateway_client.py
based on tempest BaseNetworkClient implements client APIs to manage
neutron l2-gateway resources
l2_gateway_connection_client.py
based on tempest BaseNetworkClient implements client APIs to manage
neutron l2-gateway-connection resources
lbaas v2 clients: ported from neutron_lbaas to comply with tempest services.
lbaas/load_balancers_client.py
lbaas/listeners_client.py
lbaas/pools_client.py
lbaas/health_monitorys_client.py
lbaas/members_client.py
lbv1_client.py
based on tempest BaseNetworkClient implements client APIs to manage
neutron v1 load-balancer resources
network_client_base.py
due to tempest network services are in the process of migrating to
tempest-lib, some features to be used by tests are not in
BaseNetworkClient. Inherent here and used by all vmware-nsx-tempest
client for now.
# NSX speific services
nsxv_client.py implements API to manage NSX-v components
- Logical switch (Tenant network)
- Edge (Service edge, DHCP edge, and VDR edge)
- DFW firewall rules (Security group)
- SpoofGuard
nsxv3_client.py implements API to manage NSX backend resources:
- logical switch
- firewall section
- nsgroup
- logical router

View File

@ -1,103 +0,0 @@
# Copyright 2016 VMware Inc
# All Rights Reserved.
#
# Copyright 2015 Hewlett-Packard Development Company, L.P.
# Copyright 2015 OpenStack Foundation
#
# 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 import config
from vmware_nsx_tempest.common import constants
LOG = constants.log.getLogger(__name__)
CONF = config.CONF
SEGMENTATION_ID_DELIMITER = "#"
INTERFACE_SEG_ID_DELIMITER = "|"
DEVICE_INTERFACE_DELIMITER = "::"
DEVICE_DELIMITER = ","
INTERFACE_DELIMITER = ";"
"""
Sample for providing input for gateway creation in config is noted below
Options provide flexibility to user to create l2gateway
For single device ,single interface with single vlan
l2gw_switch = device_name1::int_name1|vlan1
For single device multiple interfaces with single or multiple vlans
l2gw_switch = device_name1::int_name1|vlan1#vlan2;int_name2|vlan3
For multiple devices with mutiple interfaces having single or mutiple vlan
l2gw_switch = device_n1::int_n1|vlan1,device_n2::int_n2|vlan2#vlan3
"""
def get_interface(interfaces):
interface_dict = []
for interface in interfaces:
if INTERFACE_SEG_ID_DELIMITER in interface:
int_name = interface.split(INTERFACE_SEG_ID_DELIMITER)[0]
segid = interface.split(INTERFACE_SEG_ID_DELIMITER)[1]
if SEGMENTATION_ID_DELIMITER in segid:
segid = segid.split(SEGMENTATION_ID_DELIMITER)
else:
segid = [segid]
interface_detail = {'name': int_name, 'segmentation_id': segid}
else:
interface_detail = {'name': interface}
interface_dict.append(interface_detail)
return interface_dict
def get_device_interface(device_name, interface):
if INTERFACE_DELIMITER in interface:
interface_dict = interface.split(INTERFACE_DELIMITER)
interfaces = get_interface(interface_dict)
else:
interfaces = get_interface([interface])
device = {'device_name': device_name,
'interfaces': interfaces}
return device
def get_l2gw_body(l2gw_conf):
device_dict = []
devices = l2gw_conf.split(DEVICE_DELIMITER)
for device in devices:
if DEVICE_INTERFACE_DELIMITER in device:
device_name = device.split(DEVICE_INTERFACE_DELIMITER)[0]
interface = device.split(DEVICE_INTERFACE_DELIMITER)[1]
device = get_device_interface(device_name, interface)
device_dict.append(device)
body = {'devices': device_dict}
return body
def form_dict_devices(devices):
seg_ids = []
devices1 = dict()
int_seg = []
for device in devices:
device_name = device['device_name']
interfaces = device['interfaces']
for interface in interfaces:
interface_name = interface['name']
int_seg.append(interface_name)
seg_id = interface['segmentation_id']
if type(seg_id) is list:
for segid in seg_id:
seg_ids.append(segid)
else:
seg_ids.append(seg_id)
int_seg.append(seg_id)
devices1.setdefault(device_name, []).append(int_seg)
int_seg = []
return devices1

View File

@ -1,131 +0,0 @@
# Copyright (c) 2015 Midokura SARL
# 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 import config
from tempest.lib import exceptions as lib_exc
from vmware_nsx_tempest.services import network_client_base as base
CONF = config.CONF
class FWaaSV1Client(base.BaseNetworkClient):
def create_firewall(self, **kwargs):
uri = '/fw/firewalls'
post_data = {'firewall': kwargs}
return self.create_resource(uri, post_data)
def update_firewall(self, firewall_id, **kwargs):
uri = '/fw/firewalls/%s' % firewall_id
post_data = {'firewall': kwargs}
return self.update_resource(uri, post_data)
def show_firewall(self, firewall_id, **fields):
uri = '/fw/firewalls/%s' % firewall_id
return self.show_resource(uri, **fields)
def delete_firewall(self, firewall_id):
uri = '/fw/firewalls/%s' % firewall_id
return self.delete_resource(uri)
def list_firewalls(self, **filters):
uri = '/fw/firewalls'
return self.list_resources(uri, **filters)
def create_firewall_rule(self, **kwargs):
uri = '/fw/firewall_rules'
post_data = {'firewall_rule': kwargs}
return self.create_resource(uri, post_data)
def update_firewall_rule(self, firewall_rule_id, **kwargs):
uri = '/fw/firewall_rules/%s' % firewall_rule_id
post_data = {'firewall_rule': kwargs}
return self.update_resource(uri, post_data)
def show_firewall_rule(self, firewall_rule_id, **fields):
uri = '/fw/firewall_rules/%s' % firewall_rule_id
return self.show_resource(uri, **fields)
def delete_firewall_rule(self, firewall_rule_id):
uri = '/fw/firewall_rules/%s' % firewall_rule_id
return self.delete_resource(uri)
def list_firewall_rules(self, **filters):
uri = '/fw/firewall_rules'
return self.list_resources(uri, **filters)
def is_resource_deleted(self, id):
try:
self.show_firewall(id)
except lib_exc.NotFound:
return True
return False
def create_firewall_policy(self, **kwargs):
uri = '/fw/firewall_policies'
post_data = {'firewall_policy': kwargs}
return self.create_resource(uri, post_data)
def update_firewall_policy(self, firewall_policy_id, **kwargs):
uri = '/fw/firewall_policies/%s' % firewall_policy_id
post_data = {'firewall_policy': kwargs}
return self.update_resource(uri, post_data)
def show_firewall_policy(self, firewall_policy_id, **fields):
uri = '/fw/firewall_policies/%s' % firewall_policy_id
return self.show_resource(uri, **fields)
def delete_firewall_policy(self, firewall_policy_id):
uri = '/fw/firewall_policies/%s' % firewall_policy_id
return self.delete_resource(uri)
def list_firewall_policies(self, **filters):
uri = '/fw/firewall_policies'
return self.list_resources(uri, **filters)
def insert_firewall_rule_in_policy(self, firewall_policy_id,
firewall_rule_id, insert_after='',
insert_before=''):
uri = '/fw/firewall_policies/%s/insert_rule' % firewall_policy_id
data = {
'firewall_rule_id': firewall_rule_id,
'insert_after': insert_after,
'insert_before': insert_before,
}
return self.update_resource(uri, data)
def remove_firewall_rule_from_policy(self, firewall_policy_id,
firewall_rule_id):
uri = '/fw/firewall_policies/%s/remove_rule' % firewall_policy_id
data = {
'firewall_rule_id': firewall_rule_id,
}
return self.update_resource(uri, data)
def get_client(client_mgr):
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = FWaaSV1Client(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,82 +0,0 @@
# 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.
from oslo_log import log
from tempest.lib.services.network import base
from vmware_nsx_tempest.common import constants
LOG = log.getLogger(__name__)
class L2GatewayClient(base.BaseNetworkClient):
"""
Request resources via API for L2GatewayClient
l2 gateway create request
l2 gateway update request
l2 gateway show request
l2 gateway delete request
l2 gateway list all request
"""
def create_l2_gateway(self, **kwargs):
uri = constants.L2_GWS_BASE_URI
post_data = {constants.L2GW: kwargs}
LOG.info("URI : %(uri)s, posting data : %(post_data)s",
{"uri": uri, "post_data": post_data})
return self.create_resource(uri, post_data)
def update_l2_gateway(self, l2_gateway_id, **kwargs):
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
post_data = {constants.L2GW: kwargs}
constants.LOG.info(
"URI : %(uri)s, posting data : %(post_data)s",
{"uri": uri, "post_data": post_data})
return self.update_resource(uri, post_data)
def show_l2_gateway(self, l2_gateway_id, **fields):
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
LOG.info("URI : %(uri)s", {"uri": uri})
return self.show_resource(uri, **fields)
def delete_l2_gateway(self, l2_gateway_id):
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
LOG.info("URI : %(uri)s", {"uri": uri})
return self.delete_resource(uri)
def list_l2_gateways(self, **filters):
uri = constants.L2_GWS_BASE_URI
LOG.info("URI : %(uri)s", {"uri": uri})
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""
Create a l2-gateway client from manager or networks_client
"""
try:
manager = getattr(client_mgr, "manager", client_mgr)
net_client = getattr(manager, "networks_client")
_params = manager.default_params_withy_timeout_values.copy()
except AttributeError as attribute_err:
LOG.warning("Failed to locate the attribute, Error: %(err_msg)s",
{"err_msg": attribute_err.__str__()})
_params = {}
client = L2GatewayClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,69 +0,0 @@
# 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class L2GatewayConnectionClient(base.BaseNetworkClient):
resource = 'l2_gateway_connection'
resource_plural = 'l2_gateway_connections'
path = 'l2-gateway-connections'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
def create_l2_gateway_connection(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_l2_gateway_connection(self, l2_gateway_id, **kwargs):
uri = self.resource_object_path % l2_gateway_id
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_l2_gateway_connection(self, l2_gateway_id, **fields):
uri = self.resource_object_path % l2_gateway_id
return self.show_resource(uri, **fields)
def delete_l2_gateway_connection(self, l2_gateway_id):
uri = self.resource_object_path % l2_gateway_id
return self.delete_resource(uri)
def list_l2_gateway_connections(self, **filters):
uri = self.resource_base_path
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""create a l2-gateway client from manager or networks_client
For itempest user:
from itempest import load_our_solar_system as osn
from vmware_nsx_tempest.services import l2_gateway_connection_client
l2gwc_client = l2_gateway_connection_client.get_client(osn.adm.manager)
For tempest user:
l2gwc_client = l2_gateway_connection_client.get_client(cls.os_adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = L2GatewayConnectionClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,72 +0,0 @@
# Copyright 2014 Rackspace US 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class HealthMonitorsClient(base.BaseNetworkClient):
resource = 'healthmonitor'
resource_plural = 'healthmonitors'
path = 'lbaas/healthmonitors'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
def create_health_monitor(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_health_monitor(self, health_monitor_id, **kwargs):
uri = self.resource_object_path % health_monitor_id
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_health_monitor(self, health_monitor_id, **fields):
uri = self.resource_object_path % health_monitor_id
return self.show_resource(uri, **fields)
def delete_health_monitor(self, health_monitor_id):
uri = self.resource_object_path % health_monitor_id
return self.delete_resource(uri)
def list_health_monitors(self, **filters):
uri = self.resource_base_path
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""create a lbaas health_monitors client from manager or networks_client
For itempest user:
from itempest import load_our_solar_system as osn
from vmware_nsx_tempest.services.lbaas import health_monitors_client
healthmonitors_client = health_monitors_client.get_client(
osn.adm.manager)
For tempest user:
healthmonitors_client = health_monitors_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = HealthMonitorsClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,59 +0,0 @@
# 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class L7PoliciesClient(base.BaseNetworkClient):
resource = 'l7policy'
resource_plural = 'l7policies'
resource_base_path = '/lbaas/l7policies'
resource_object_path = '/lbaas/l7policies/%s'
def create_l7policy(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_l7policy(self, policy_id, **kwargs):
uri = self.resource_object_path % (policy_id)
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_l7policy(self, policy_id, **fields):
uri = self.resource_object_path % (policy_id)
return self.show_resource(uri, **fields)
def delete_l7policy(self, policy_id):
uri = self.resource_object_path % (policy_id)
return self.delete_resource(uri)
def list_l7policies(self, **filters):
uri = self.resource_base_path
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""create a lbaas l7policies client from manager or networks_client"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = L7PoliciesClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,60 +0,0 @@
# 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class L7RulesClient(base.BaseNetworkClient):
resource = 'rule'
resource_plural = 'rules'
resource_base_path = '/lbaas/l7policies/%s/rules'
resource_object_path = '/lbaas/l7policies/%s/rules/%s'
def create_l7rule(self, policy_id, **kwargs):
uri = self.resource_base_path % policy_id
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_l7rule(self, policy_id, rule_id, **kwargs):
uri = self.resource_object_path % (policy_id, rule_id)
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_l7rule(self, policy_id, rule_id, **fields):
uri = self.resource_object_path % (policy_id, rule_id)
return self.show_resource(uri, **fields)
def delete_l7rule(self, policy_id, rule_id):
uri = self.resource_object_path % (policy_id, rule_id)
return self.delete_resource(uri)
def list_l7rules(self, policy_id, **filters):
uri = self.resource_base_path % policy_id
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""create a lbaas l7rules client from manager or networks_client"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = L7RulesClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,71 +0,0 @@
# Copyright 2014 Rackspace US 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class ListenersClient(base.BaseNetworkClient):
resource = 'listener'
resource_plural = 'listeners'
path = 'lbaas/listeners'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
def create_listener(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_listener(self, listener_id, **kwargs):
uri = self.resource_object_path % listener_id
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_listener(self, listener_id, **fields):
uri = self.resource_object_path % listener_id
return self.show_resource(uri, **fields)
def delete_listener(self, listener_id):
uri = self.resource_object_path % listener_id
return self.delete_resource(uri)
def list_listeners(self, **filters):
uri = self.resource_base_path
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""create a lbaas listener client from manager or networks_client
For itempest user:
from itempest import load_our_solar_system as osn
from vmware_nsx_tempest.services.lbaas import pools_client
lbaas_client = pools_client.get_client(osn.adm.manager)
For tempest user:
lbaas_client = pools_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = ListenersClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,141 +0,0 @@
# Copyright 2014 Rackspace US 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 time
from tempest.lib import exceptions
from tempest.lib.services.network import base
from vmware_nsx_tempest._i18n import _
from vmware_nsx_tempest.services import network_client_base as base_client
LB_NOTFOUND = "loadbalancer {lb_id} not found"
class LoadBalancersClient(base.BaseNetworkClient):
resource = 'loadbalancer'
resource_plural = 'loadbalancers'
path = 'lbaas/loadbalancers'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
resource_object_status_path = '/%s/%%s/statuses' % path
resource_object_stats_path = '/%s/%%s/stats' % path
def create_load_balancer(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_load_balancer(self, load_balancer_id, **kwargs):
uri = self.resource_object_path % load_balancer_id
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_load_balancer(self, load_balancer_id, **fields):
uri = self.resource_object_path % load_balancer_id
return self.show_resource(uri, **fields)
def show_load_balancer_status_tree(self, load_balancer_id, **fields):
uri = self.resource_object_status_path % load_balancer_id
return self.show_resource(uri, **fields)
def show_load_balancer_stats(self, load_balancer_id, **fields):
uri = self.resource_object_stats_path % load_balancer_id
return self.show_resource(uri, **fields)
def delete_load_balancer(self, load_balancer_id):
uri = self.resource_object_path % load_balancer_id
return self.delete_resource(uri)
def list_load_balancers(self, **filters):
uri = self.resource_base_path
return self.list_resources(uri, **filters)
def wait_for_load_balancer_status(self, load_balancer_id,
provisioning_status='ACTIVE',
operating_status='ONLINE',
is_delete_op=False):
"""Must have utility method for load-balancer CRUD operation.
This is the method you must call to make sure load_balancer_id is
in provisioning_status=ACTIVE and opration_status=ONLINE status
before manipulating any lbaas resource under load_balancer_id.
"""
interval_time = self.build_interval
timeout = self.build_timeout
end_time = time.time() + timeout
lb = None
while time.time() < end_time:
try:
lb = self.show_load_balancer(load_balancer_id)
if not lb:
if is_delete_op:
break
else:
raise Exception(
LB_NOTFOUND.format(lb_id=load_balancer_id))
lb = lb.get(self.resource, lb)
if (lb.get('provisioning_status') == provisioning_status and
lb.get('operating_status') == operating_status):
break
time.sleep(interval_time)
except exceptions.NotFound as e:
if is_delete_op:
break
else:
raise e
else:
if is_delete_op:
raise exceptions.TimeoutException(
_("Waited for load balancer {lb_id} to be deleted for "
"{timeout} seconds but can still observe that it "
"exists.").format(
lb_id=load_balancer_id,
timeout=timeout))
else:
raise exceptions.TimeoutException(
_("Wait for load balancer ran for {timeout} seconds and "
"did not observe {lb_id} reach {provisioning_status} "
"provisioning status and {operating_status} "
"operating status.").format(
timeout=timeout,
lb_id=load_balancer_id,
provisioning_status=provisioning_status,
operating_status=operating_status))
return lb
def get_client(client_mgr):
"""create a lbaas load-balancers client from manager or networks_client
For itempest user:
from itempest import load_our_solar_system as osn
from vmware_nsx_tempest.services.lbaas import load_balancers_client
lbaas_client = load_balancers_client.get_client(osn.adm.manager)
For tempest user:
lbaas_client = load_balancers_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = LoadBalancersClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,70 +0,0 @@
# Copyright 2014 Rackspace US 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class MembersClient(base.BaseNetworkClient):
resource = 'member'
resource_plural = 'members'
path = 'lbaas/members'
resource_base_path = '/lbaas/pools/%s/members'
resource_object_path = '/lbaas/pools/%s/members/%s'
def create_member(self, pool_id, **kwargs):
uri = self.resource_base_path % pool_id
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_member(self, pool_id, member_id, **kwargs):
uri = self.resource_object_path % (pool_id, member_id)
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_member(self, pool_id, member_id, **fields):
uri = self.resource_object_path % (pool_id, member_id)
return self.show_resource(uri, **fields)
def delete_member(self, pool_id, member_id):
uri = self.resource_object_path % (pool_id, member_id)
return self.delete_resource(uri)
def list_members(self, pool_id, **filters):
uri = self.resource_base_path % pool_id
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""create a lbaas members client from manager or networks_client
For itempest user:
from itempest import load_our_solar_system as osn
from vmware_nsx_tempest.services.lbaas import members_client
members_client = members_client.get_client(osn.adm.manager)
For tempest user:
members_client = members_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = MembersClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,70 +0,0 @@
# Copyright 2014 Rackspace US 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class PoolsClient(base.BaseNetworkClient):
resource = 'pool'
resource_plural = 'pools'
path = 'lbaas/pools'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
def create_pool(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_pool(self, pool_id, **kwargs):
uri = self.resource_object_path % pool_id
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_pool(self, pool_id, **fields):
uri = self.resource_object_path % pool_id
return self.show_resource(uri, **fields)
def delete_pool(self, pool_id):
uri = self.resource_object_path % pool_id
return self.delete_resource(uri)
def list_pools(self, **filters):
uri = self.resource_base_path
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""create a lbaas pools client from manager or networks_client
For itempest user:
from itempest import load_our_solar_system as osn
from vmware_nsx_tempest.services.lbaas import pools_client
pools_client = pools_client.get_client(osn.adm.manager)
For tempest user:
pools_client = pools_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = PoolsClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,320 +0,0 @@
# 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.lib.common.utils import misc as misc_utils
from tempest.lib import exceptions as lib_exc
from tempest import exceptions
from vmware_nsx_tempest._i18n import _
from vmware_nsx_tempest.services import network_client_base as base
POOL_RID = 'pools'
VIP_RID = 'vips'
HEALTHMONITOR_RID = 'health_monitors'
MEMBER_RID = 'members'
class LoadBalancerV1Client(base.BaseNetworkClient):
def _list_lb(self, lb_resource, **filters):
resource_name_s, resource_name_p = _g_resource_namelist(lb_resource)
req_uri = '/lb/%s' % (resource_name_p)
return self.list_resources(req_uri, **filters)
def _show_lb(self, lb_resource, resource_id, **fields):
resource_name_s, resource_name_p = _g_resource_namelist(lb_resource)
req_uri = '/lb/%s/%s' % (resource_name_p, resource_id)
return self.show_resource(req_uri, **fields)
def _delete_lb(self, lb_resource, resource_id):
resource_name_s, resource_name_p = _g_resource_namelist(lb_resource)
req_uri = '/lb/%s/%s' % (resource_name_p, resource_id)
return self.delete_resource(req_uri)
def _create_lb(self, lb_resource, **kwargs):
resource_name_s, resource_name_p = _g_resource_namelist(lb_resource)
req_uri = '/lb/%s' % (resource_name_p)
post_body = {resource_name_s: kwargs}
return self.create_resource(req_uri, post_body)
def _update_lb(self, lb_resource, resource_id, **kwargs):
resource_name_s, resource_name_p = _g_resource_namelist(lb_resource)
req_uri = '/lb/%s/%s' % (resource_name_p, resource_id)
post_body = {resource_name_s: kwargs}
return self.update_resource(req_uri, post_body)
def show_agent_hosting_pool(self, pool_id):
"""Get loadbalancer agent hosting a pool."""
req_uri = "/lb/pools/%s/loadbalancer-agent" % (pool_id)
return self.show_resource(req_uri)
def associate_health_monitor_with_pool(self, health_monitor_id, pool_id):
"""Create a mapping between a health monitor and a pool."""
post_body = {'health_monitor': {'id': health_monitor_id}}
req_uri = '/lb/pools/%s/%s' % (pool_id, HEALTHMONITOR_RID)
return self.create_resource(req_uri, post_body)
def create_health_monitor(self, **kwargs):
"""Create a health monitor."""
create_kwargs = dict(
type=kwargs.pop('type', 'TCP'),
max_retries=kwargs.pop('nax_retries', 3),
timeout=kwargs.pop('timeout', 1),
delay=kwargs.pop('delay', 4),
)
create_kwargs.update(**kwargs)
return self._create_lb(HEALTHMONITOR_RID, **create_kwargs)
def delete_health_monitor(self, health_monitor_id):
"""Delete a given health monitor."""
return self._delete_lb(HEALTHMONITOR_RID, health_monitor_id)
def disassociate_health_monitor_with_pool(self, health_monitor_id,
pool_id):
"""Remove a mapping from a health monitor to a pool."""
req_uri = ('/lb/pools/%s/%s/%s'
% (pool_id, HEALTHMONITOR_RID, health_monitor_id))
return self.delete_resource(req_uri)
def list_health_monitors(self, **filters):
"""List health monitors that belong to a given tenant."""
return self._list_lb(HEALTHMONITOR_RID, **filters)
def show_health_monitor(self, health_monitor_id):
"""Show information of a given health monitor."""
return self._show_lb(HEALTHMONITOR_RID, health_monitor_id)
def update_health_monitor(self, health_monitor_id,
show_then_update=False, **kwargs):
"""Update a given health monitor."""
body = (self.show_health_monitor(health_monitor_id)['health_monitor']
if show_then_update else {})
body.update(**kwargs)
return self._update_lb(HEALTHMONITOR_RID,
health_monitor_id, **body)
# tempest create_member(self,protocol_port, pool, ip_version)
# we use pool_id
def create_member(self, protocol_port, pool_id,
ip_version=4, **kwargs):
"""Create a member."""
create_kwargs = dict(
protocol_port=protocol_port,
pool_id=pool_id,
address=("fd00:abcd" if ip_version == 6 else "10.0.9.46"),
)
create_kwargs.update(**kwargs)
return self._create_lb(MEMBER_RID, **create_kwargs)
def delete_member(self, member_id):
"""Delete a given member."""
return self._delete_lb(MEMBER_RID, member_id)
def list_members(self, **filters):
"""List members that belong to a given tenant."""
return self._list_lb(MEMBER_RID, **filters)
def show_member(self, member_id):
"""Show information of a given member."""
return self._show_lb(MEMBER_RID, member_id)
def update_member(self, member_id,
show_then_update=False, **kwargs):
"""Update a given member."""
body = (self.show_member(member_id)['member']
if show_then_update else {})
body.update(**kwargs)
return self._update_lb(MEMBER_RID, member_id, **body)
def create_pool(self, name, lb_method, protocol, subnet_id,
**kwargs):
"""Create a pool."""
lb_method = lb_method or 'ROUND_ROBIN'
protocol = protocol or 'HTTP'
create_kwargs = dict(
name=name, lb_method=lb_method,
protocol=protocol, subnet_id=subnet_id,
)
create_kwargs.update(kwargs)
return self._create_lb(POOL_RID, **create_kwargs)
def delete_pool(self, pool_id):
"""Delete a given pool."""
return self._delete_lb(POOL_RID, pool_id)
def list_pools(self, **filters):
"""List pools that belong to a given tenant."""
return self._list_lb(POOL_RID, **filters)
def list_lb_pool_stats(self, pool_id, **filters):
"""Retrieve stats for a given pool."""
req_uri = '/lb/pools/%s/stats' % (pool_id)
return self.list_resources(req_uri, **filters)
def list_pool_on_agents(self, **filters):
"""List the pools on a loadbalancer agent."""
pass
def show_pool(self, pool_id):
"""Show information of a given pool."""
return self._show_lb(POOL_RID, pool_id)
def update_pool(self, pool_id, show_then_update=False, **kwargs):
"""Update a given pool."""
body = (self.show_pool(pool_id)['pool']
if show_then_update else {})
body.update(**kwargs)
return self._update_lb(POOL_RID, pool_id, **body)
def create_vip(self, pool_id, **kwargs):
"""Create a vip."""
create_kwargs = dict(
pool_id=pool_id,
protocol=kwargs.pop('protocol', 'HTTP'),
protocol_port=kwargs.pop('protocol_port', 80),
name=kwargs.pop('name', None),
address=kwargs.pop('address', None),
)
for k in create_kwargs.keys():
if create_kwargs[k] is None:
create_kwargs.pop(k)
create_kwargs.update(**kwargs)
# subnet_id needed to create vip
return self._create_lb(VIP_RID, **create_kwargs)
def delete_vip(self, vip_id):
"""Delete a given vip."""
return self._delete_lb(VIP_RID, vip_id)
def list_vips(self, **filters):
"""List vips that belong to a given tenant."""
return self._list_lb(VIP_RID, **filters)
def show_vip(self, vip_id):
"""Show information of a given vip."""
return self._show_lb(VIP_RID, vip_id)
def update_vip(self, vip_id, show_then_update=False, **kwargs):
"""Update a given vip."""
body = (self.show_vip(vip_id)['vip']
if show_then_update else {})
body.update(**kwargs)
return self._update_lb(VIP_RID, vip_id, **body)
# Following 3 methods are specifically to load-balancer V1 client.
# They are being implemented by the pareant tempest.lib.common.rest_client
# with different calling signatures, only id, no resoure_type. Because,
# starting in Liberty release, each resource should have its own client.
# Since V1 is deprecated, we are not going to change it, and
# copy following 2 methods for V1 LB client only.
def wait_for_resource_deletion(self, resource_type, id, client=None):
"""Waits for a resource to be deleted."""
start_time = int(time.time())
while True:
if self.is_resource_deleted(resource_type, id, client=client):
return
if int(time.time()) - start_time >= self.build_timeout:
raise exceptions.TimeoutException
time.sleep(self.build_interval)
def is_resource_deleted(self, resource_type, id, client=None):
if client is None:
client = self
method = 'show_' + resource_type
try:
getattr(client, method)(id)
except AttributeError:
raise Exception(_("Unknown resource type %s ") % resource_type)
except lib_exc.NotFound:
return True
return False
def wait_for_resource_status(self, fetch, status, interval=None,
timeout=None):
"""This has different calling signature then rest_client.
@summary: Waits for a network resource to reach a status
@param fetch: the callable to be used to query the resource status
@type fecth: callable that takes no parameters and returns the resource
@param status: the status that the resource has to reach
@type status: String
@param interval: the number of seconds to wait between each status
query
@type interval: Integer
@param timeout: the maximum number of seconds to wait for the resource
to reach the desired status
@type timeout: Integer
"""
if not interval:
interval = self.build_interval
if not timeout:
timeout = self.build_timeout
start_time = time.time()
while time.time() - start_time <= timeout:
resource = fetch()
if resource['status'] == status:
return
time.sleep(interval)
# At this point, the wait has timed out
message = 'Resource %s' % (str(resource))
message += ' failed to reach status %s' % status
message += ' (current: %s)' % resource['status']
message += ' within the required time %s' % timeout
caller = misc_utils.find_test_caller()
if caller:
message = '(%s) %s' % (caller, message)
raise exceptions.TimeoutException(message)
def _g_resource_namelist(lb_resource):
if lb_resource[-1] == 's':
return (lb_resource[:-1], lb_resource)
return (lb_resource, lb_resource + "s")
def destroy_tenant_lb(lbv1_client):
for o in lbv1_client.list_members():
lbv1_client.delete_member(o['id'])
for o in lbv1_client.list_health_monitors():
lbv1_client.delete_health_monitor(o['id'])
for o in lbv1_client.list_vips():
lbv1_client.delete_vip(o['id'])
for o in lbv1_client.list_pools():
lbv1_client.delete_pool(o['id'])
def get_client(client_mgr):
"""create a v1 load balancer client
For itempest user:
from itempest import load_our_solar_system as osn
from vmware_nsx_tempest.services import load_balancer_v1_client
lbv1 = load_balancer_v1_client.get_client(osn.adm.manager)
For tempest user:
lbv1 = load_balancer_v1_client.get_client(cls.os_adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = LoadBalancerV1Client(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
return client

View File

@ -1,52 +0,0 @@
# 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 import config
from tempest.lib.services.network import base
CONF = config.CONF
# netowrk/json/base.py does not include thoese method in network_client
class BaseNetworkClient(base.BaseNetworkClient):
def __init__(self, auth_provider, service, region,
endpoint_type=None, build_interval=None, build_timeout=None,
disable_ssl_certificate_validation=None, ca_certs=None,
trace_requests=None, **kwargs):
dsca = disable_ssl_certificate_validation
super(base.BaseNetworkClient, self).__init__(
auth_provider, service, region,
endpoint_type=endpoint_type,
build_interval=build_interval,
build_timeout=build_timeout,
disable_ssl_certificate_validation=dsca,
ca_certs=ca_certs,
trace_requests=trace_requests)
default_params = {
'disable_ssl_certificate_validation': True,
'ca_certs': None,
'trace_requests': ''}
default_params_2 = {
'catalog_type': 'network',
'region': 'nova',
'endpoint_type': 'publicURL',
'build_timeout': 300,
'build_interval': 1}
default_params_3 = config.service_client_config()
default_params_with_timeout_values = {
'build_interval': CONF.network.build_interval,
'build_timeout': CONF.network.build_timeout
}
default_params_with_timeout_values.update(default_params_3)

View File

@ -1,46 +0,0 @@
# 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 oslo_log import log as logging
from vmware_nsx_tempest.services import nsxv3_client
LOG = logging.getLogger(__name__)
class NSXClient(object):
"""Base NSX REST client"""
def __init__(self, backend, host, username, password, *args, **kwargs):
self.backend = backend.lower()
self.host = host
self.username = username
self.password = password
if backend.lower() == "nsxv3":
self.nsx = nsxv3_client.NSXV3Client(host, username, password)
def get_firewall_section_and_rules(self, *args, **kwargs):
if self.backend == "nsxv3":
firewall_section = self.nsx.get_firewall_section(
*args, **kwargs)
firewall_section_rules = self.nsx.get_firewall_section_rules(
firewall_section)
return firewall_section, firewall_section_rules
else:
#TODO(ddoshi) define else for nsxv
pass
def get_bridge_cluster_info(self, *args, **kwargs):
if self.backend == "nsxv3":
return self.nsx.get_bridge_cluster_info(
*args, **kwargs)

View File

@ -1,560 +0,0 @@
# 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 base64
from copy import deepcopy
import time
import requests
import six.moves.urllib.parse as urlparse
from oslo_log import log as logging
from oslo_serialization import jsonutils
from vmware_nsx_tempest.common import constants
requests.packages.urllib3.disable_warnings()
LOG = logging.getLogger(__name__)
class NSXV3Client(object):
"""Base NSXv3 REST client"""
API_VERSION = "v1"
def __init__(self, host, username, password, *args, **kwargs):
self.host = host
self.username = username
self.password = password
self.version = None
self.endpoint = None
self.content_type = "application/json"
self.accept_type = "application/json"
self.verify = False
self.secure = True
self.interface = "json"
self.url = None
self.headers_non_super_admin = self.__set_headers()
self.headers = deepcopy(self.headers_non_super_admin)
self.headers_super_admin = self.__set_headers(super_admin=True)
self.api_version = NSXV3Client.API_VERSION
def __set_endpoint(self, endpoint):
self.endpoint = endpoint
def get_endpoint(self):
return self.endpoint
def __set_content_type(self, content_type):
self.content_type = content_type
def get_content_type(self):
return self.content_type
def __set_accept_type(self, accept_type):
self.accept_type = accept_type
def get_accept_type(self):
return self.accept_type
def __set_api_version(self, api_version):
self.api_version = api_version
def get_api_version(self):
return self.api_version
def __set_url(self, api=None, secure=None, host=None, endpoint=None):
api = self.api_version if api is None else api
secure = self.secure if secure is None else secure
host = self.host if host is None else host
endpoint = self.endpoint if endpoint is None else endpoint
http_type = 'https' if secure else 'http'
self.url = '%s://%s/api/%s%s' % (http_type, host, api, endpoint)
def get_url(self):
return self.url
def __set_headers(self, content=None, accept=None, super_admin=False):
content_type = self.content_type if content is None else content
accept_type = self.accept_type if accept is None else accept
auth_cred = self.username + ":" + self.password
auth = base64.b64encode(auth_cred)
headers = {}
headers['Authorization'] = "Basic %s" % auth
headers['Content-Type'] = content_type
headers['Accept'] = accept_type
if super_admin:
headers['X-Allow-Overwrite'] = 'true'
return headers
def get(self, endpoint=None, params=None, cursor=None):
"""
Basic query method for json API request
"""
self.__set_url(endpoint=endpoint)
if cursor:
op = "&" if urlparse.urlparse(self.url).query else "?"
self.url += op + "cursor=" + cursor
response = requests.get(self.url, headers=self.headers,
verify=self.verify, params=params)
return response
def put(self, endpoint=None, body=None):
"""
Basic put API method on endpoint
"""
self.__set_url(endpoint=endpoint)
response = requests.put(self.url, headers=self.headers,
verify=self.verify, data=jsonutils.dumps(body))
return response
def ca_put_request(self, component, comp_id, body):
"""
NSX-T API Put request for certificate Management
"""
endpoint = ("/%s/%s" % (component, comp_id))
response = self.put(endpoint=endpoint, body=body)
return response
def delete(self, endpoint=None, params=None):
"""
Basic delete API method on endpoint
"""
self.__set_url(endpoint=endpoint)
response = requests.delete(self.url, headers=self.headers,
verify=self.verify, params=params)
return response
def ca_delete_request(self, component=None, comp_id=None):
"""
NSX-T API delete request for certificate Management
"""
endpoint = ("/%s/%s" % (component, comp_id))
response = self.delete(endpoint=endpoint)
return response
def delete_super_admin(self, endpoint=None, params=None):
"""
Basic delete API method for NSX super admin on endpoint
"""
self.__set_url(endpoint=endpoint)
response = requests.delete(self.url, headers=self.headers_super_admin,
verify=self.verify, params=params)
return response
def post(self, endpoint=None, body=None):
"""
Basic post API method on endpoint
"""
self.__set_url(endpoint=endpoint)
response = requests.post(self.url, headers=self.headers,
verify=self.verify,
data=jsonutils.dumps(body))
return response
def get_logical_resources(self, endpoint):
"""
Get logical resources based on the endpoint
Getting the logical resource based on the end point. Parse the response
for the cursor. If cursor is present, query url for multiple pages to
get all the logical resources.
"""
results = []
response = self.get(endpoint=endpoint)
res_json = response.json()
cursor = res_json.get("cursor")
if res_json.get("results"):
results.extend(res_json["results"])
while cursor:
page = self.get(endpoint=endpoint, cursor=cursor).json()
results.extend(page.get("results", []))
cursor = page.get("cursor")
return results
def get_transport_zones(self):
"""
Retrieve all transport zones
"""
return self.get_logical_resources("/transport-zones")
def get_logical_ports(self):
"""
Retrieve all logical ports on NSX backend
"""
return self.get_logical_resources("/logical-ports")
def get_logical_port(self, os_name):
"""
Get the logical port based on the os_name provided.
The name of the logical port shoud match the os_name.
Return the logical port if found, otherwise return None.
"""
if not os_name:
LOG.error("Name of OS port should be present "
"in order to query backend logical port created")
return None
lports = self.get_logical_ports()
return self.get_nsx_resource_by_name(lports, os_name)
def get_logical_port_info(self, lport):
"""
Retrieve attributes of a given logical port
"""
lport_uri = "/logical-ports/%s" % lport
response = self.get(endpoint=lport_uri)
res_json = response.json()
return res_json
def get_switching_profile(self, switch_profile):
"""
Retrieve attributes of a given nsx switching profile
"""
sw_profile_uri = "/switching-profiles/%s" % switch_profile
response = self.get(endpoint=sw_profile_uri)
res_json = response.json()
return res_json
def get_os_logical_ports(self):
"""
Retrieve all logical ports created from OpenStack
"""
lports = self.get_logical_ports()
return self.get_os_resources(lports)
def update_logical_port_attachment(self, lports):
"""
Update the logical port attachment
In order to delete logical ports, we need to detach
the VIF attachment on the ports first.
"""
for p in lports:
p['attachment'] = None
endpoint = "/logical-ports/%s" % p['id']
response = self.put(endpoint=endpoint, body=p)
if response.status_code != requests.codes.ok:
LOG.error("Failed to update lport %s", p['id'])
def cleanup_os_logical_ports(self):
"""
Delete all logical ports created by OpenStack
"""
lports = self.get_logical_ports()
os_lports = self.get_os_resources(lports)
LOG.info("Number of OS Logical Ports to be deleted: %s",
len(os_lports))
# logical port vif detachment
self.update_logical_port_attachment(os_lports)
for p in os_lports:
endpoint = '/logical-ports/%s' % p['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
LOG.info("Successfully deleted logical port %s", p['id'])
else:
LOG.error("Failed to delete lport %(port_id)s, response "
"code %(code)s",
{'port_id': p['id'], 'code': response.status_code})
def get_os_resources(self, resources):
"""
Get all logical resources created by OpenStack
"""
os_resources = [r for r in resources if 'tags' in r
for tag in r['tags']
if 'os-project-id' in tag.values()]
return os_resources
def get_nsx_resource_by_name(self, nsx_resources, nsx_name):
"""
Get the NSX component created from OpenStack by name.
The name should be converted from os_name to nsx_name.
If found exact one match return it, otherwise report error.
"""
nsx_resource = [n for n in nsx_resources if
n['display_name'] == nsx_name]
if len(nsx_resource) == 0:
LOG.warning("Backend nsx resource %s NOT found!", nsx_name)
return None
if len(nsx_resource) > 1:
LOG.error("More than 1 nsx resources found: %s!",
nsx_resource)
return None
else:
LOG.info("Found nsgroup: %s", nsx_resource[0])
return nsx_resource[0]
def get_logical_switches(self):
"""
Retrieve all logical switches on NSX backend
"""
return self.get_logical_resources("/logical-switches")
def get_logical_switch_profiles(self):
"""
Retrieve all switching profiles on NSX backend
"""
return self.get_logical_resources("/switching-profiles")
def get_switching_profiles(self):
"""
Retrieve all switching profiles on NSX backend
"""
return self.get_logical_resources("/switching-profiles")
def get_bridge_cluster_info(self):
"""
Get bridge cluster information.
:return: returns bridge cluster id and bridge cluster name.
"""
return self.get_logical_resources("/bridge-clusters")
def get_logical_switch(self, os_name, os_uuid):
"""
Get the logical switch based on the name and uuid provided.
The name of the logical switch should follow
<os_network_name>_<first 5 os uuid>...<last 5 os uuid>
Return logical switch if found, otherwise return None
"""
if not os_name or not os_uuid:
LOG.error("Name and uuid of OpenStack L2 network need to be "
"present in order to query backend logical switch!")
return None
nsx_name = os_name + "_" + os_uuid[:5] + "..." + os_uuid[-5:]
lswitches = self.get_logical_switches()
return self.get_nsx_resource_by_name(lswitches, nsx_name)
def get_lswitch_ports(self, ls_id):
"""
Return all the logical ports that belong to this lswitch
"""
lports = self.get_logical_ports()
return [p for p in lports if p['logical_switch_id'] is ls_id]
def get_firewall_sections(self):
"""
Retrieve all firewall sections
"""
return self.get_logical_resources("/firewall/sections")
def get_firewall_section(self, os_name, os_uuid):
"""
Get the firewall section by os_name and os_uuid
"""
if not os_name or not os_uuid:
LOG.error("Name and uuid of OS security group should be "
"present in order to query backend FW section "
"created")
return None
nsx_name = os_name + " - " + os_uuid
nsx_firewall_time_counter = 0
nsx_dfw_section = None
# wait till timeout or till dfw section
while nsx_firewall_time_counter < \
constants.NSX_FIREWALL_REALIZED_TIMEOUT and \
not nsx_dfw_section:
nsx_firewall_time_counter += 1
fw_sections = self.get_firewall_sections()
nsx_dfw_section = self.get_nsx_resource_by_name(fw_sections,
nsx_name)
time.sleep(constants.ONE_SEC)
return nsx_dfw_section
def get_firewall_section_rules(self, fw_section):
"""
Retrieve all fw rules for a given fw section
"""
endpoint = "/firewall/sections/%s/rules" % fw_section['id']
return self.get_logical_resources(endpoint)
def get_firewall_section_rule(self, fw_section, os_uuid):
"""
Get the firewall section rule based on the name
"""
fw_rules = self.get_firewall_section_rules(fw_section)
nsx_name = os_uuid
return self.get_nsx_resource_by_name(fw_rules, nsx_name)
def get_ns_groups(self):
"""
Retrieve all NSGroups on NSX backend
"""
return self.get_logical_resources("/ns-groups")
def get_neutron_ns_group_id(self):
"""
Retrieve NSGroup Id
"""
nsx_nsgroup = self.get_ns_groups()
for group in nsx_nsgroup:
if group['display_name'] == 'neutron_excluded_port_nsgroup':
nsgroup_id = group['id']
return nsgroup_id
def get_ns_group_port_members(self, ns_group_id):
"""
Retrieve NSGroup port members
"""
endpoint = "/ns-groups/%s/effective-logical-port-members" % ns_group_id
response = self.get(endpoint=endpoint)
res_json = response.json()
return res_json
def get_ns_group(self, os_name, os_uuid):
"""
Get the NSGroup based on the name provided.
The name of the nsgroup should follow
<os_sg_name> - <os_sg_uuid>
Return nsgroup if found, otherwise return None
"""
if not os_name or not os_uuid:
LOG.error("Name and uuid of OS security group should be "
"present in order to query backend nsgroup created")
return None
nsx_name = os_name + " - " + os_uuid
nsgroups = self.get_ns_groups()
return self.get_nsx_resource_by_name(nsgroups, nsx_name)
def get_logical_routers(self, tier=None):
"""
Retrieve all the logical routers based on router type. If tier
is None, it will return all logical routers.
"""
if tier:
endpoint = "/logical-routers?router_type=%s" % tier
else:
endpoint = "/logical-routers"
return self.get_logical_resources(endpoint)
def get_logical_router(self, os_name, os_uuid):
"""
Get the logical router based on the os_name and os_uuid provided.
The name of the logical router shoud follow
<os_router_name>_<starting_5_uuid>...<trailing_5_uuid>
Return the logical router if found, otherwise return None.
"""
if not os_name or not os_uuid:
LOG.error("Name and uuid of OS router should be present "
"in order to query backend logical router created")
return None
nsx_name = os_name + "_" + os_uuid[:5] + "..." + os_uuid[-5:]
lrouters = self.get_logical_routers()
return self.get_nsx_resource_by_name(lrouters, nsx_name)
def get_logical_router_ports(self, lrouter):
"""
Get all logical ports attached to lrouter
"""
endpoint = "/logical-router-ports?logical_router_id=%s" % lrouter['id']
return self.get_logical_resources(endpoint)
def get_logical_router_nat_rules(self, lrouter):
"""
Get all user defined NAT rules of the specific logical router
"""
if not lrouter:
LOG.error("Logical router needs to be present in order "
"to get the NAT rules")
return None
endpoint = "/logical-routers/%s/nat/rules" % lrouter['id']
return self.get_logical_resources(endpoint)
def get_logical_router_advertisement(self, lrouter):
"""Get logical router advertisement"""
if not lrouter:
LOG.error("Logical router needs to be present in order "
"to get router advertisement!")
return None
endpoint = "/logical-routers/%s/routing/advertisement" % lrouter['id']
response = self.get(endpoint)
return response.json()
def get_logical_dhcp_servers(self):
"""
Get all logical DHCP servers on NSX backend
"""
return self.get_logical_resources("/dhcp/servers")
def get_logical_dhcp_server(self, os_name, os_uuid):
"""
Get the logical dhcp server based on the name and uuid provided.
The name of the logical dhcp server should follow
<os_network_name>_<first 5 os uuid>...<last 5 os uuid>
Return logical dhcp server if found, otherwise return None
"""
if not os_name or not os_uuid:
LOG.error("Name and uuid of OpenStack L2 network need to be "
"present in order to query backend logical dhcp "
"server!")
return None
nsx_name = os_name + "_" + os_uuid[:5] + "..." + os_uuid[-5:]
dhcp_servers = self.get_logical_dhcp_servers()
return self.get_nsx_resource_by_name(dhcp_servers, nsx_name)
def get_dhcp_server_static_bindings(self, dhcp_server):
"""
Get all DHCP static bindings of a logical DHCP server
"""
endpoint = "/dhcp/servers/%s/static-bindings" % dhcp_server
return self.get_logical_resources(endpoint)
def get_md_proxies(self):
"""
Get md proxies.
:return: returns list of md proxies information.
"""
return self.get_logical_resources("/md-proxies")
def get_nsx_certificate(self):
"""
Get all certificates registered with backend
"""
endpoint = "/trust-management/certificates/"
response = self.get(endpoint)
return response.json()
def get_openstack_client_certificate(self):
"""
Get self signed openstack client certificate
"""
cert_response = self.get_nsx_certificate()
for cert in cert_response['results']:
if (cert["_create_user"] == "admin" and cert[
"resource_type"] == "certificate_self_signed" and cert[
"display_name"] != "NSX MP Client Certificate for Key "
"Manager"):
LOG.info('Client certificate created')
return cert
LOG.error("Client Certificate not created")
return None
def delete_md_proxy(self, uuid):
"""
Delete md proxies.
"""
return self.delete_logical_resources("/md-proxies/%s" % uuid)
def delete_logical_resources(self, endpoint):
"""
Delete logical resources based on the endpoint.
"""
response = self.delete(endpoint=endpoint)
return response.json()

View File

@ -1,347 +0,0 @@
# 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 base64
import re
from oslo_log import log as logging
from oslo_serialization import jsonutils
import requests
from tempest import config
import vmware_nsx_tempest.services.utils as utils
requests.packages.urllib3.disable_warnings()
CONF = config.CONF
LOG = logging.getLogger(__name__)
class VSMClient(object):
"""NSX-v client.
The client provides the API operations on its components.
The purpose of this rest client is to query backend components after
issuing corresponding API calls from OpenStack. This is to make sure
the API calls has been realized on the NSX-v backend.
"""
API_VERSION = "2.0"
def __init__(self, host, username, password, *args, **kwargs):
self.force = True if 'force' in kwargs else False
self.host = host
self.username = username
self.password = password
self.version = None
self.endpoint = None
self.content_type = "application/json"
self.accept_type = "application/json"
self.verify = False
self.secure = True
self.interface = "json"
self.url = None
self.headers = None
self.api_version = VSMClient.API_VERSION
self.default_scope_id = None
self.__set_headers()
self._version = self.get_vsm_version()
def __set_endpoint(self, endpoint):
self.endpoint = endpoint
def get_endpoint(self):
return self.endpoint
def __set_content_type(self, content_type):
self.content_type = content_type
def get_content_type(self):
return self.content_type
def __set_accept_type(self, accept_type):
self.accept_type = accept_type
def get_accept_type(self):
return self.accept_type
def __set_api_version(self, api_version):
self.api_version = api_version
def get_api_version(self):
return self.api_version
def __set_url(self, version=None, secure=None, host=None, endpoint=None):
version = self.api_version if version is None else version
secure = self.secure if secure is None else secure
host = self.host if host is None else host
endpoint = self.endpoint if endpoint is None else endpoint
http_type = 'https' if secure else 'http'
self.url = '%s://%s/api/%s%s' % (http_type, host, version, endpoint)
def get_url(self):
return self.url
def __set_headers(self, content=None, accept=None):
content_type = self.content_type if content is None else content
accept_type = self.accept_type if accept is None else accept
auth_cred = self.username + ":" + self.password
auth = base64.b64encode(auth_cred)
headers = {}
headers['Authorization'] = "Basic %s" % auth
headers['Content-Type'] = content_type
headers['Accept'] = accept_type
self.headers = headers
def get(self, endpoint=None, params=None):
"""Basic query GET method for json API request."""
self.__set_url(endpoint=endpoint)
response = requests.get(self.url, headers=self.headers,
verify=self.verify, params=params)
return response
def delete(self, endpoint=None, params=None):
"""Basic delete API method on endpoint."""
self.__set_url(endpoint=endpoint)
response = requests.delete(self.url, headers=self.headers,
verify=self.verify, params=params)
return response
def post(self, endpoint=None, body=None):
"""Basic post API method on endpoint."""
self.__set_url(endpoint=endpoint)
response = requests.post(self.url, headers=self.headers,
verify=self.verify,
data=jsonutils.dumps(body))
return response
def get_all_vdn_scopes(self):
"""Retrieve existing network scopes"""
self.__set_api_version('2.0')
self.__set_endpoint("/vdn/scopes")
response = self.get()
return response.json()['allScopes']
# return the vdn_scope_id for the priamry Transport Zone
def get_vdn_scope_id(self):
"""Retrieve existing network scope id."""
scopes = self.get_all_vdn_scopes()
if len(scopes) == 0:
return scopes[0]['objectId']
return CONF.nsxv.vdn_scope_id
def get_vdn_scope_by_id(self, scope_id):
"""Retrieve existing network scopes id"""
self.__set_api_version('2.0')
self.__set_endpoint("/vdn/scopes/%s" % scope_id)
return self.get().json()
def get_vdn_scope_by_name(self, name):
"""Retrieve network scope id of existing scope name:
nsxv_client.get_vdn_scope_id_by_name('TZ1')
"""
scopes = self.get_all_vdn_scopes()
if name is None:
for scope in scopes:
if scope['objectId'] == CONF.nsxv.vdn_scope_id:
return scope
else:
for scope in scopes:
if scope['name'] == name:
return scope
return None
def get_all_logical_switches(self, vdn_scope_id=None):
lswitches = []
self.__set_api_version('2.0')
vdn_scope_id = vdn_scope_id or self.get_vdn_scope_id()
endpoint = "/vdn/scopes/%s/virtualwires" % (vdn_scope_id)
self.__set_endpoint(endpoint)
response = self.get()
paging_info = response.json()['dataPage']['pagingInfo']
page_size = int(paging_info['pageSize'])
total_count = int(paging_info['totalCount'])
msg = ("There are total %s logical switches and page size is %s"
% (total_count, page_size))
LOG.debug(msg)
pages = utils.ceil(total_count, page_size)
LOG.debug("Total pages: %s" % pages)
for i in range(pages):
start_index = page_size * i
params = {'startindex': start_index}
response = self.get(params=params)
lswitches += response.json()['dataPage']['data']
return lswitches
def get_logical_switch(self, name):
"""Get the logical switch based on the name.
The uuid of the OpenStack L2 network. Return ls if found,
otherwise return None.
"""
lswitches = self.get_all_logical_switches()
lswitch = [ls for ls in lswitches if ls['name'] == name]
if len(lswitch) == 0:
LOG.debug('logical switch %s NOT found!' % name)
lswitch = None
else:
ls = lswitch[0]
LOG.debug('Found lswitch: %s' % ls)
return ls
def delete_logical_switch(self, name):
"""Delete logical switch based on name.
The name of the logical switch on NSX-v is the uuid
of the openstack l2 network.
"""
ls = self.get_logical_switch(name)
if ls is not None:
endpoint = '/vdn/virtualwires/%s' % ls['objectId']
response = self.delete(endpoint=endpoint)
if response.status_code == 200:
LOG.debug('Successfully deleted logical switch %s' % name)
else:
LOG.debug('ERROR @delete ls=%s failed with response code %s' %
(name, response.status_code))
def get_all_edges(self):
"""Get all edges on NSX-v backend."""
self.__set_api_version('4.0')
self.__set_endpoint('/edges')
edges = []
response = self.get()
paging_info = response.json()['edgePage']['pagingInfo']
page_size = int(paging_info['pageSize'])
total_count = int(paging_info['totalCount'])
msg = "There are total %s edges and page size is %s" % (total_count,
page_size)
LOG.debug(msg)
pages = utils.ceil(total_count, page_size)
for i in range(pages):
start_index = page_size * i
params = {'startindex': start_index}
response = self.get(params=params)
edges += response.json()['edgePage']['data']
return edges
def get_edge_firewall_rules(self, edge_Id):
"""Get nsx-edge firewall info based on edge_id.
Return firewall rules if found ,else return None.
"""
self.__set_api_version('4.0')
self.__set_endpoint('/edges/%s/firewall/config ' % edge_Id)
response = self.get()
rules = response.json()['firewallRules']['firewallRules']
if len(rules) == 0:
rules = None
return rules
def get_firewall(self):
"""Get all firewall on NSX-v beckend.
Return firewalls if found, else return None.
"""
self.__set_api_version('4.0')
self.__set_endpoint('/firewall/globalroot-0/config')
response = self.get()
paging_info = response.json()
if len(paging_info) == 0:
paging_info = None
return paging_info
def get_edge(self, name):
"""Get edge based on the name, which is OpenStack router.
Return edge if found, else return None.
"""
edges = self.get_all_edges()
edge = [e for e in edges if e['name'] == name]
if len(edge) == 0:
LOG.debug('Edge %s NOT found!' % name)
edge = None
else:
edge = edge[0]
LOG.debug('Found edge: %s' % edge)
return edge
def get_dhcp_edge_config(self, edge_id):
"""Get dhcp edge config.
Return edge information.
"""
self.__set_api_version('4.0')
self.__set_endpoint('/edges/%s/dhcp/config' % edge_id)
response = self.get()
return response
def get_excluded_vm_name_list(self):
"""Get excluded vm's list info from beckend.
After disabling port security of vm port, vm will get added
in exclude list.This method returns the list of vm's present
in exclude list.
Returns exclude list of vm's name.
"""
self.__set_api_version('2.1')
self.__set_endpoint('/app/excludelist')
response = self.get()
response_list = []
exclude_list = []
response_list = response.json()[
'excludeListConfigurationDto']['excludeMembers']
exclude_list = [member['member']['name'] for member in response_list
if member['member']['name']]
return exclude_list
def get_dhcp_edge_info(self):
"""Get dhcp edge info.
Return edge if found, else return None.
"""
edges = self.get_all_edges()
edge_list = []
for e in edges:
if (not e['edgeStatus'] == 'GREY'
and not e['state'] == 'undeployed'):
p = re.compile(r'dhcp*')
if (p.match(e['name'])):
edge_list.append(e['recentJobInfo']['edgeId'])
count = 0
result_edge = {}
for edge_id in edge_list:
response = self.get_dhcp_edge_config(edge_id)
paging_info = response.json()
if (paging_info['staticBindings']['staticBindings']):
result_edge[count] = paging_info
count += 1
else:
LOG.debug('Host Routes are not avilable for %s ' % edge_id)
if (count > 0):
edge = result_edge[0]
else:
edge = None
return edge
def get_vsm_version(self):
"""Get the VSM client version including major, minor, patch, & build#.
Build number, e.g. 6.2.0.2986609
return: vsm version
"""
self.__set_api_version('1.0')
self.__set_endpoint('/appliance-management/global/info')
response = self.get()
json_ver = response.json()['versionInfo']
return '.'.join([json_ver['majorVersion'], json_ver['minorVersion'],
json_ver['patchVersion'], json_ver['buildNumber']])

View File

@ -1,100 +0,0 @@
# 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 oslo_log import log
from tempest.lib.services.network import base
from vmware_nsx_tempest.common import constants
LOG = log.getLogger(__name__)
class L2GatewayClient(base.BaseNetworkClient):
"""
Request resources via API for L2GatewayClient
l2 gateway create request
l2 gateway update request
l2 gateway show request
l2 gateway delete request
l2 gateway list all request
"""
def create_l2_gateway(self, **kwargs):
uri = constants.L2_GWS_BASE_URI
post_data = {constants.L2GW: kwargs}
LOG.info("URI : %(uri)s, posting data : %(post_data)s",
{"uri": uri, "post_data": post_data})
return self.create_resource(uri, post_data)
def update_l2_gateway(self, l2_gateway_id, **kwargs):
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
post_data = {constants.L2GW: kwargs}
constants.LOG.info(
"URI : %(uri)s, posting data : %(post_data)s",
{"uri": uri, "post_data": post_data})
return self.update_resource(uri, post_data)
def show_l2_gateway(self, l2_gateway_id, **fields):
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
LOG.info("URI : %(uri)s", {"uri": uri})
return self.show_resource(uri, **fields)
def delete_l2_gateway(self, l2_gateway_id):
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
LOG.info("URI : %(uri)s", {"uri": uri})
return self.delete_resource(uri)
def list_l2_gateways(self, **filters):
uri = constants.L2_GWS_BASE_URI
LOG.info("URI : %(uri)s", {"uri": uri})
return self.list_resources(uri, **filters)
class L2GatewayConnectionClient(base.BaseNetworkClient):
"""
Request resources via API for L2GatewayClient
l2 gateway connection create request
l2 gateway connection update request
l2 gateway connection show request
l2 gateway connection delete request
l2 gateway connection list all request
"""
resource = 'l2_gateway_connection'
resource_plural = 'l2_gateway_connections'
path = 'l2-gateway-connections'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
def create_l2_gateway_connection(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_l2_gateway_connection(self, l2_gateway_id, **kwargs):
uri = self.resource_object_path % l2_gateway_id
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_l2_gateway_connection(self, l2_gateway_id, **fields):
uri = self.resource_object_path % l2_gateway_id
return self.show_resource(uri, **fields)
def delete_l2_gateway_connection(self, l2_gateway_id):
uri = self.resource_object_path % l2_gateway_id
return self.delete_resource(uri)
def list_l2_gateway_connections(self, **filters):
uri = self.resource_base_path
return self.list_resources(uri, **filters)

View File

@ -1,68 +0,0 @@
# 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class BandwidthLimitRulesClient(base.BaseNetworkClient):
resource = 'bandwidth_limit_rule'
resource_plural = 'bandwidth_limit_rules'
path = 'qos/policies'
resource_base_path = '/%s/%%s/bandwidth_limit_rules' % path
resource_object_path = '/%s/%%s/bandwidth_limit_rules/%%s' % path
def create_bandwidth_limit_rule(self, policy_id, **kwargs):
uri = self.resource_base_path % policy_id
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_bandwidth_limit_rule(self, rule_id, policy_id, **kwargs):
uri = self.resource_object_path % (policy_id, rule_id)
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_bandwidth_limit_rule(self, rule_id, policy_id, **fields):
uri = self.resource_object_path % (policy_id, rule_id)
return self.show_resource(uri, **fields)
def delete_bandwidth_limit_rule(self, rule_id, policy_id):
uri = self.resource_object_path % (policy_id, rule_id)
return self.delete_resource(uri)
def list_bandwidth_limit_rules(self, policy_id, **filters):
uri = self.resource_base_path % policy_id
return self.list_resources(uri, **filters)
def get_client(client_mgr,
set_property=False,
with_name="qos_bandwidth_limit_rules_client"):
"""create a qos bandwidth limit rules client
For tempest user:
client = bandwidth_limit_rules_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = BandwidthLimitRulesClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
if set_property:
setattr(manager, with_name, client)
return client

View File

@ -1,147 +0,0 @@
# 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 vmware_nsx_tempest.services.qos import (
bandwidth_limit_rules_client as bandwidth_limit_rules_client)
from vmware_nsx_tempest.services.qos import (
dscp_marking_rules_client as dscp_marking_rules_client)
from vmware_nsx_tempest.services.qos import (
policies_client as policies_client)
from vmware_nsx_tempest.services.qos import (
rule_types_client as rule_types_client)
RULE_TYPE_BANDWIDTH_LIMIT = "bandwidth_limit"
RULE_TYPE_DSCP_MARK = "dscp_marking"
VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT, RULE_TYPE_DSCP_MARK]
QOS_POLICY_ID = 'qos_policy_id'
class BaseQosClient(object):
def __init__(self, manager, set_property=True):
self.policies_client = policies_client.get_client(
manager, set_property)
self.bandwidths_client = (
bandwidth_limit_rules_client.get_client(
manager, set_property))
self.dscps_client = dscp_marking_rules_client.get_client(
manager, set_property)
self.types_client = rule_types_client.get_client(manager, True)
def resp_body(self, result, item):
return result.get(item, result)
def create_policy(self, name, description, shared, **kwargs):
result = self.policies_client.create_policy(
name=name,
description=description,
shared=shared,
**kwargs
)
return self.resp_body(result, 'policy')
def delete_policy(self, policy_id_or_name):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.policies_client.delete_policy(policy_id)
return self.resp_body(result, 'policy')
def list_policies(self, **filters):
result = self.policies_client.list_policies(**filters)
return self.resp_body(result, 'policies')
def update_policy(self, policy_id_or_name, **kwargs):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.policies_client.update_policy(policy_id, **kwargs)
return self.resp_body(result, 'policy')
def show_policy(self, policy_id_or_name, **fields):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.policies_client.show_policy(policy_id, **fields)
return self.resp_body(result, 'policy')
def create_bandwidth_limit_rule(self, policy_id_or_name,
max_kbps, max_burst_kbps,
**kwargs):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.bandwidths_client.create_bandwidth_limit_rule(
policy_id,
max_kbps=max_kbps, max_burst_kbps=max_burst_kbps,
**kwargs)
return self.resp_body(result, 'bandwidth_limit_rule')
def delete_bandwidth_limit_rule(self, rule_id, policy_id_or_name):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.bandwidths_client.delete_bandwidth_limit_rule(
rule_id, policy_id)
return self.resp_body(result, 'bandwidth_limit_rule')
def update_bandwidth_limit_rule(self, rule_id, policy_id_or_name,
**kwargs):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.bandwidths_client.update_bandwidth_limit_rule(
rule_id, policy_id, **kwargs)
return self.resp_body(result, 'bandwidth_limit_rule')
def list_bandwidth_limit_rules(self, policy_id_or_name, **filters):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.bandwidths_client.list_bandwidth_limit_rules(
policy_id, **filters)
return self.resp_body(result, 'bandwidth_limit_rules')
def show_bandwidth_limit_rule(self, rule_id, policy_id_or_name,
**fields):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.bandwidths_client.show_bandwidth_limit_rule(
rule_id, policy_id)
return self.resp_body(result, 'bandwidth_limit_rule')
def create_dscp_marking_rule(self, policy_id_or_name, dscp_mark,
**kwargs):
policy_id = self.get_policy_id(policy_id_or_name)
kwargs['dscp_mark'] = dscp_mark
result = self.dscps_client.create_dscp_marking_rule(
policy_id, **kwargs)
return self.resp_body(result, 'dscp_marking_rule')
def delete_dscp_marking_rule(self, rule_id, policy_id_or_name):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.dscps_client.delete_dscp_marking_rule(rule_id,
policy_id)
return self.resp_body(result, 'dscp_marking_rule')
def update_dscp_marking_rule(self, rule_id, policy_id_or_name,
**kwargs):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.dscps_client.update_dscp_marking_rule(
rule_id, policy_id, **kwargs)
return self.resp_body(result, 'dscp_marking_rule')
def list_dscp_marking_rules(self, policy_id_or_name, **filters):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.dscps_client.list_dscp_marking_rules(
policy_id, **filters)
return self.resp_body(result, 'dscp_marking_rules')
def show_dscp_marking_rule(self, rule_id, policy_id_or_name, **fields):
policy_id = self.get_policy_id(policy_id_or_name)
result = self.dscps_client.show_dscp_marking_rule(
rule_id, policy_id, **fields)
return self.resp_body(result, 'dscp_marking_rule')
def list_rule_types(self):
result = self.types_client.list_rule_types()
return self.resp_body(result, 'rule_types')
def available_rule_types(self):
return self.list_rule_types()
def get_policy_id(self, policy_id_or_name):
return self.policies_client.get_policy_id(policy_id_or_name)

View File

@ -1,68 +0,0 @@
# 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class DscpMarkingRulesClient(base.BaseNetworkClient):
resource = 'dscp_marking_rule'
resource_plural = 'dscp_marking_rules'
path = 'qos/policies'
resource_base_path = '/%s/%%s/dscp_marking_rules' % path
resource_object_path = '/%s/%%s/dscp_marking_rules/%%s' % path
def create_dscp_marking_rule(self, policy_id, **kwargs):
uri = self.resource_base_path % policy_id
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_dscp_marking_rule(self, rule_id, policy_id, **kwargs):
uri = self.resource_object_path % (policy_id, rule_id)
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_dscp_marking_rule(self, rule_id, policy_id, **fields):
uri = self.resource_object_path % (policy_id, rule_id)
return self.show_resource(uri, **fields)
def delete_dscp_marking_rule(self, rule_id, policy_id):
uri = self.resource_object_path % (policy_id, rule_id)
return self.delete_resource(uri)
def list_dscp_marking_rules(self, policy_id, **filters):
uri = self.resource_base_path % policy_id
return self.list_resources(uri, **filters)
def get_client(client_mgr,
set_property=False,
with_name="qos_dscp_marking_rules_client"):
"""create a qos dscp marking rules client
For tempest user:
client = dscp_marking_rules_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = DscpMarkingRulesClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
if set_property:
setattr(manager, with_name, client)
return client

View File

@ -1,76 +0,0 @@
# 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class PoliciesClient(base.BaseNetworkClient):
resource = 'policy'
resource_plural = 'policies'
path = 'qos/policies'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
def create_policy(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
return self.create_resource(uri, post_data)
def update_policy(self, policy_id, **kwargs):
uri = self.resource_object_path % policy_id
post_data = {self.resource: kwargs}
return self.update_resource(uri, post_data)
def show_policy(self, policy_id, **fields):
uri = self.resource_object_path % policy_id
return self.show_resource(uri, **fields)
def delete_policy(self, policy_id):
uri = self.resource_object_path % policy_id
return self.delete_resource(uri)
def list_policies(self, **filters):
uri = self.resource_base_path
return self.list_resources(uri, **filters)
# utility
def get_policy_id(self, policy_id_or_name):
policies = self.list_policies(name=policy_id_or_name)
policy_list = policies[self.resource_plural]
if len(policy_list) > 0:
return policy_list[0]['id']
return policy_id_or_name
def get_client(client_mgr,
set_property=False,
with_name="qos_policies_client"):
"""create a qos policies client from manager or networks_client
For tempest user:
client = policies_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = PoliciesClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
if set_property:
setattr(manager, with_name, client)
return client

View File

@ -1,50 +0,0 @@
# 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.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class RuleTypesClient(base.BaseNetworkClient):
resource = 'rule_type'
resource_plural = 'rule_types'
path = 'qos/rule-types'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
def list_rule_types(self):
uri = self.resource_base_path
return self.list_resources(uri)
def get_client(client_mgr,
set_property=False,
with_name="qos_rule_types_client"):
"""create a qos rule_types client from manager or networks_client
For tempest user:
client = rule_types_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = RuleTypesClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
if set_property:
setattr(manager, with_name, client)
return client

View File

@ -1,137 +0,0 @@
# 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.
from oslo_serialization import jsonutils
from tempest.lib.services.network import base
from vmware_nsx_tempest.services import network_client_base as base_client
class BaseTagsClient(base.BaseNetworkClient):
"""Why base client for tags_client:
https://bugs.launchpad.net/neutron/+bug/1606659
tag-add is a CREATE operation; then expected resp_code is 201
however it is using http PUT operation to accomplish it.
"""
def update_resource(self, uri, post_data, resp_code=None):
"""allow different response code."""
if resp_code:
req_uri = self.uri_prefix + uri
req_post_data = jsonutils.dumps(post_data)
resp, body = self.put(req_uri, req_post_data)
body = jsonutils.loads(body)
self.expected_success(resp_code, resp.status)
return base.rest_client.ResponseBody(
resp, body)
else:
return super(BaseTagsClient, self).update_resource(
uri, post_data)
class TagsClient(BaseTagsClient):
resource_base_path = '/{resource_type}/{resource_id}/tags'
resource_object_path = '/{resource_type}/{resource_id}/tags/{tag}'
def add_tag(self, **kwargs):
"""add a tag to network resource.
neutron tag-add
--resource resource
--resource-type network --tag TAG
"""
uri = self.resource_object_path.format(
**self._fix_args(**kwargs))
# https://bugs.launchpad.net/neutron/+bug/1606659
return self.update_resource(uri, None, 201)
def remove_tag(self, **kwargs):
"""remove a tag from network resource.
neutron tag-remove
--resource resource
--resource-type network --tag TAG
"""
if 'all' in kwargs:
return self.remove_all_tags(**kwargs)
uri = self.resource_object_path.format(
**self._fix_args(**kwargs))
return self.delete_resource(uri)
def remove_all_tags(self, **kwargs):
"""remove all tags from network resource.
neutron tag-remove
--resource resource
--resource-type network --all
"""
uri = self.resource_base_path.format(
**self._fix_args(**kwargs))
return self.delete_resource(uri)
def replace_tag(self, **kwargs):
"""replace network resource's tag with list of tags.
neutron tag-replace
--resource resource
--resource-type network --tag TAG
"""
tag_list = kwargs.pop('tags', None)
kwargs = self._fix_args(**kwargs)
if 'tag' in kwargs:
uri = self.resource_object_path.format(**kwargs)
else:
uri = self.resource_base_path.format(**kwargs)
update_body = None if tag_list is None else {"tags": tag_list}
return self.update_resource(uri, update_body)
def _fix_args(self, **kwargs):
"""Fix key-value of input fields.
resource can be name, to simplify the design, only ID accepted.
"""
if 'resource' in kwargs and 'resource_id' not in kwargs:
kwargs['resource_id'] = kwargs['resource']
if 'resource_type' in kwargs:
if kwargs['resource_type'][-1] != 's':
kwargs['resource_type'] += "s"
else:
kwargs['resource_type'] = 'networks'
return kwargs
def get_client(client_mgr,
set_property=False, with_name="tags_client"):
"""create tags_client from networks_client.
Create network tags_client from manager or networks_client.
client = tags_client.get_client(manager)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
try:
_params = base_client.default_params_with_timeout_values.copy()
except Exception:
_params = {}
client = TagsClient(net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
if set_property:
setattr(manager, with_name, client)
return client

View File

@ -1,21 +0,0 @@
# Copyright 2015 OpenStack Foundation
#
# 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.
def ceil(a, b):
if b == 0:
return 0
div = a / b
mod = 0 if a % b is 0 else 1
return div + mod

View File

@ -1,446 +0,0 @@
# 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.
from oslo_log import log as logging
from tempest.api.network import base
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
from tempest import test
from vmware_nsx_tempest._i18n import _
from vmware_nsx_tempest.services import tags_client
CONF = config.CONF
LOG = logging.getLogger(__name__)
MAX_TAG_LEN = 60
class BaseTagsTest(base.BaseNetworkTest):
"""Base class for Tags Test."""
@classmethod
def skip_checks(cls):
"""skip tests if the tags feauture is not enabled."""
super(BaseTagsTest, cls).skip_checks()
if not test.is_extension_enabled('tag', 'network'):
msg = "network tag extension not enabled."
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
"""setup resources."""
super(BaseTagsTest, cls).resource_setup()
cls.primary_mgr = cls.get_client_manager()
cls.tags_client = tags_client.get_client(cls.primary_mgr)
@classmethod
def resource_cleanup(cls):
"""cleanup resources before handing over to framework."""
super(BaseTagsTest, cls).resource_cleanup()
@classmethod
def list_networks(cls, **filters):
nets = cls.networks_client.list_networks(**filters)
return nets.get('networks')
@classmethod
def tag_add(cls, network_id, tag, resource_type='network'):
cls.tags_client.add_tag(resource_type=resource_type,
resource_id=network_id,
tag=tag)
network = cls.networks_client.show_network(network_id)
return network.get('network')
@classmethod
def tag_remove(cls, network_id, tag, resource_type='network'):
cls.tags_client.remove_tag(resource_type=resource_type,
resource_id=network_id,
tag=tag)
network = cls.networks_client.show_network(network_id)
return network.get('network')
@classmethod
def tag_replace(cls, network_id, tags, resource_type='network'):
req_body = dict(resource_type=resource_type, resource_id=network_id)
if type(tags) in (list, tuple, set):
req_body['tags'] = tags
else:
req_body['tags'] = [tags]
cls.tags_client.replace_tag(**req_body)
network = cls.networks_client.show_network(network_id)
return network.get('network')
def network_add_tag(self, network_id, tag):
network = self.tag_add(network_id, tag, 'network')
self.assertIn(tag, network['tags'])
return network
def network_remove_tag(self, network_id, tag):
network = self.tag_remove(network_id, tag, 'network')
self.assertNotIn(tag, network['tags'])
return network
def network_replace_tags(self, network_id, tags=None):
if tags is None:
tags = ['a', 'ab', 'abc']
network = self.tag_replace(network_id, tags, 'network')
self.assertEqual(len(tags), len(network['tags']))
for tag in tags:
self.assertIn(tag, network['tags'])
return network
class NetworkTagAddTest(BaseTagsTest):
"""neutron tag-add test."""
@classmethod
def resource_setup(cls):
"""setup resources."""
super(NetworkTagAddTest, cls).resource_setup()
cls.net = cls.create_network()
@decorators.idempotent_id('0e37a579-aff3-47ba-9f1f-3ac4482fce16')
def test_add_tags(self):
"""neutron tag-add operations."""
tags = ['a', 'gold', 'T' * MAX_TAG_LEN]
network_id = self.net.get('id')
# check we can add tag one at time
for tag in tags:
network = self.network_add_tag(network_id, tag)
# and all added tags exist.
for tag in tags:
self.assertIn(tag, network['tags'])
@decorators.idempotent_id('eb52eac3-5e79-4183-803a-a3d97ceb171d')
@decorators.attr(type='negative')
def test_add_tag_one_char_too_long(self):
tag_too_long = 'a' * (MAX_TAG_LEN + 1)
network_id = self.net.get('id')
self.assertRaises(exceptions.BadRequest,
self.network_add_tag,
network_id, tag_too_long)
@decorators.idempotent_id('d08f3fbe-dc6f-4f3c-b9b2-4d9957884edf')
@decorators.attr(type='negative')
def test_add_tag_empty_one(self):
network_id = self.net.get('id')
self.assertRaises(exceptions.NotFound,
self.network_add_tag,
network_id, '')
class NetworkTagRemoveTest(BaseTagsTest):
"""neutron tag-remove test."""
@classmethod
def resource_setup(cls):
"""setup resources."""
super(NetworkTagRemoveTest, cls).resource_setup()
cls.net = cls.create_network()
@decorators.idempotent_id('178fbd96-900f-4c3d-8cd1-5525f4cf2b81')
def test_remove_tags(self):
"""neutron tag-remove operations."""
network_id = self.net.get('id')
tag = 'spinning-tail'
self.network_add_tag(network_id, tag)
self.network_remove_tag(network_id, tag)
@decorators.idempotent_id('1fe5a8b2-ff5d-4250-b930-21b1a3b48055')
@decorators.attr(type='negative')
def test_remove_all_tags(self):
network_id = self.net.get('id')
self.network_replace_tags(network_id)
req_body = dict(resource_type='network',
resource_id=network_id, all=True)
self.tags_client.remove_tag(**req_body)
network = self.networks_client.show_network(network_id)['network']
self.assertEqual(len(network['tags']), 0)
@decorators.idempotent_id('591337b0-a2e6-4d72-984c-e5b6a6ec12d2')
@decorators.attr(type='negative')
def test_remove_not_exist_tag(self):
"""neutron tag-remove operations."""
network_id = self.net.get('id')
tag_not_tagged = 'talking-head'
self.assertRaises(exceptions.NotFound,
self.network_remove_tag,
network_id, tag_not_tagged)
class NetworkTagReplaceTest(BaseTagsTest):
"""neutron tag-replace test."""
@classmethod
def resource_setup(cls):
"""setup resources."""
super(NetworkTagReplaceTest, cls).resource_setup()
cls.net = cls.create_network()
@decorators.idempotent_id('7d4fb288-2f2d-4f47-84af-be3175b057b5')
def test_replace_tags(self):
"""neutron tag-replace operations."""
network_id = self.net.get('id')
tags = ['east', 'south', 'west', 'north']
self.network_replace_tags(network_id, tags)
new_tags = ['BIG', 'small']
self.network_replace_tags(network_id, new_tags)
# EQ to remove all
empty_tags = []
self.network_replace_tags(network_id, empty_tags)
@decorators.idempotent_id('20a05e9e-0b25-4085-b89f-fd5f0c57d2fa')
@decorators.attr(type='negative')
def test_replace_tags_one_char_too_long(self):
tags_too_long = ['aaa', 'z' * (MAX_TAG_LEN + 1)]
network_id = self.net.get('id')
self.assertRaises(exceptions.BadRequest,
self.network_replace_tags,
network_id, tags_too_long)
class NetworkTagFilterTest(BaseTagsTest):
"""searching networks using tags querying params.
Four query parameters are supported:
Q-param Q-procedure
------------ -----------
tags x_and_y
tags-any x_or_y
not-tags not_x_and_y
not-tags-any not_x_or_y
"""
@classmethod
def resource_setup(cls):
"""setup default values for filtering tests."""
super(NetworkTagFilterTest, cls).resource_setup()
cls.a_b_c = ['a', 'ab', 'abc']
cls.not_tagged_tags = ['talking-head', 'spinning-tail']
cls._tags = (['east', 'gold', 'production'],
['west', 'silver', 'development'],
['north', 'brown', 'development', 'abc'],
['south', 'brown', 'testing', 'a'],
['west', 'gold', 'production', 'ab'],
['east', 'silver', 'testing'],
['north', 'gold', 'production'],
['south', 'silver', 'testing'])
cls.QQ = {'router:external': False}
cls.GG = {}
for ix in range(0, len(cls._tags)):
net = cls.create_network()
tags = cls._tags[ix]
net = cls.tag_replace(net['id'], tags=tags)
if not (set(net['tags']) == set(cls._tags[ix])):
raise Exception(
_("tags[%s] are not tag-replace successfully.") % tags)
net_id = net['id']
cls.GG[net_id] = set(net['tags'])
def check_matched_search_list(self, matched_nets, m_net_list, title):
LOG.info(_("Expected_nets[{0}]: {1}").format(title, m_net_list))
LOG.info(_("Number of matched_nets: {0}").format(len(matched_nets)))
self.assertEqual(len(matched_nets), len(m_net_list))
for net in matched_nets:
self.assertIn(net['id'], m_net_list)
@decorators.idempotent_id('9646af99-7e04-4724-ac54-4a938de764f1')
def test_tags_only_one_network(self):
"""each tag in self.a_b_c only tag one network."""
for tag in self.a_b_c:
filters = {'tags': tag}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.assertEqual(len(nets), 1)
@decorators.idempotent_id('5632b745-651a-444f-922d-6434e060991a')
def test_tags_any_only_one_network(self):
"""each tag in self.a_b_c only tag one network."""
for tag in self.a_b_c:
filters = {'tags-any': tag}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.assertEqual(len(nets), 1)
@decorators.idempotent_id('a0d8c21b-1ec0-4c6d-b5d8-72baebabde26')
def test_tags_not_tagged(self):
"""search with tags for tags not being tagged."""
for tag in self.not_tagged_tags:
filters = {'tags': tag}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.assertEqual(len(nets), 0)
@decorators.idempotent_id('1049eac1-028b-4664-aeb7-c7656240622d')
def test_tags_any_not_tagged(self):
"""search with tags-any for tags not being tagged."""
for tag in self.not_tagged_tags:
filters = {'tags-any': tag}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.assertEqual(len(nets), 0)
@decorators.idempotent_id('a9b42503-5dd1-490d-b0c6-673951cc86a1')
def test_tags(self):
"""find networks having tags (and operation)"""
tags = ['gold', 'production']
m_net_list = x_and_y(tags, self.GG)
filters = {'tags': tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list, 'tags')
@decorators.idempotent_id('c38e788d-749e-401a-8bbb-26e36a7b573f')
def test_tags_any(self):
"""find networks having tags-any (or operation)"""
tags = ['gold', 'production']
m_net_list = x_or_y(tags, self.GG)
filters = {'tags-any': tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list, 'tags-any')
@decorators.idempotent_id('e7bb1cea-3271-418c-bfe2-038fff6187e6')
def test_not_tags(self):
"""find networks not having not-tags (and operation)"""
tags = ['gold', 'production']
m_net_list = not_x_and_y(tags, self.GG)
filters = {'not-tags': tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list, 'not-tags')
@decorators.idempotent_id('c36a1d00-c131-4297-86c1-a3fc06c61629')
def test_not_tags_any(self):
"""find networks not having not-tags-any (or operation)"""
tags = ['gold', 'production']
m_net_list = not_x_or_y(tags, self.GG)
filters = {'not-tags-any': tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list, 'not-tags-any')
@decorators.idempotent_id('4345e944-6b2b-4106-a208-ce07cefe764f')
def test_tags_any_not_tags(self):
"""find networks having tags-any and not-tags."""
tags = ['gold', 'production']
not_tags = ['west']
m_net_list = not_x_and_y(not_tags, self.GG,
x_or_y(tags, self.GG))
filters = {'tags-any': tags, 'not-tags': not_tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list,
'tags-any & not-tags')
@decorators.idempotent_id('0d635ba7-5c94-4a24-b7a8-d3b413d1ec83')
@decorators.skip_because(bug="1611054")
def test_tags_tags_any(self):
"""finding networks using tags and tags-any."""
tags = ['production']
tags_any = ['east', 'west']
m_net_list = x_or_y(tags_any, self.GG,
x_and_y(tags, self.GG))
filters = {'tags': tags, 'tags-any': tags_any}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list,
'tags & tags-any')
@decorators.idempotent_id('2067a8fc-2d7b-4085-a6c2-7e454f6f26f3')
def test_tags_not_tags_any(self):
"""finding networks using tags and not-tags-any."""
tags = ['gold', 'production']
not_tags = ['east', 'west', 'silver']
m_net_list = not_x_or_y(not_tags, self.GG,
x_and_y(tags, self.GG))
filters = {'tags': tags, 'not-tags-any': not_tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list,
'tags & not-tags-any')
@decorators.idempotent_id('f2bbf51c-e32e-4664-a0db-59eed493c3d1')
def test_tags_not_tags_any2(self):
"""finding networks using tags and not-tags-any."""
tags = ['gold', 'production']
not_tags = ['west', 'east']
m_net_list = not_x_or_y(not_tags, self.GG,
x_and_y(tags, self.GG))
filters = {'tags': tags, 'not-tags-any': not_tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list,
'tags & not-tags-any2')
@decorators.idempotent_id('7b17dfa8-f7ac-47c2-b814-35c5ed1c325b')
def test_tags_not_tags(self):
"""finding networks using tags and not-tags."""
tags = ['gold', 'production']
not_tags = ['west']
m_net_list = not_x_and_y(not_tags, self.GG,
x_and_y(tags, self.GG))
filters = {'tags': tags, 'not-tags': not_tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.check_matched_search_list(nets, m_net_list,
'tags & not-tags')
@decorators.idempotent_id('f723f717-660b-4d8e-ae9f-014f0a3f812d')
def test_tags_not_tags_itself(self):
""""tags and not-tags itself is always an empty set."""
tags = ['gold', 'production']
not_x_and_y(tags, self.GG, x_and_y(tags, self.GG))
filters = {'tags': tags, 'not-tags': tags}
filters.update(self.QQ)
nets = self.list_networks(**filters)
self.assertEqual(0, len(nets))
# search/filter methods
# K_sets: Dict of sets
def x_and_y(x_and_y, K_sets, on_keys=None):
"""tags=x_and_y"""
s_xy = set(x_and_y)
xy_s = [k for k, S in K_sets.items()
if (on_keys is None or k in on_keys) and s_xy.issubset(S)]
return xy_s
def not_x_and_y(x_and_y, K_sets, on_keys=None):
"""not-tags=x_and_y"""
s_xy = set(x_and_y)
xy_s = [k for k, S in K_sets.items()
if (on_keys is None or k in on_keys) and not s_xy.issubset(S)]
return xy_s
def x_or_y(x_or_y, K_sets, on_keys=None):
"""tags-any=x_or_y"""
s_xy = set(x_or_y)
xy_s = [k for k, S in K_sets.items()
if (on_keys is None or k in on_keys) and len(S & s_xy) > 0]
return xy_s
def not_x_or_y(x_or_y, K_sets, on_keys=None):
"""not tags-any=x_or_y"""
s_xy = set(x_or_y)
xy_s = [k for k, S in K_sets.items()
if (on_keys is None or k in on_keys) and len(S & s_xy) == 0]
return xy_s

View File

@ -1,856 +0,0 @@
# 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.
import testtools
from tempest.api.network import base
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.lib import exceptions
from tempest import test
from vmware_nsx_tempest.services.qos import base_qos
CONF = config.CONF
class BaseQosTest(base.BaseAdminNetworkTest):
"""Base class for Qos Test.
1. Setup QoS clients for admin and primary users.
2. Manages qos resources creation and deletion.
3. Manages network/port creation and deletion as network cannot be
deleted if ports are associated which test framework won't handle.
"""
@classmethod
def skip_checks(cls):
"""skip tests if qos is not enabled."""
super(BaseQosTest, cls).skip_checks()
if not test.is_extension_enabled('qos', 'network'):
msg = "q-qos extension not enabled."
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
"""setup resources."""
super(BaseQosTest, cls).resource_setup()
cls.admin_mgr = cls.get_client_manager(credential_type='admin')
cls.primary_mgr = cls.get_client_manager()
cls.adm_qos_client = base_qos.BaseQosClient(cls.admin_mgr)
cls.pri_qos_client = base_qos.BaseQosClient(cls.primary_mgr)
cls.qos_available_rule_types = (
cls.adm_qos_client.available_rule_types())
cls.policies_created = []
@classmethod
def resource_cleanup(cls):
"""cleanup resources before handing over to framework."""
for network in cls.networks:
# network cannot be deleted if its ports have policy associated.
port_list = cls.admin_mgr.ports_client.list_ports(
network_id=network['id'])['ports']
for port in port_list:
test_utils.call_and_ignore_notfound_exc(
cls.delete_port, port['id'])
test_utils.call_and_ignore_notfound_exc(
cls.delete_network, network['id'])
for policy in cls.policies_created:
test_utils.call_and_ignore_notfound_exc(
cls.adm_qos_client.delete_policy, policy['id'])
super(BaseQosTest, cls).resource_cleanup()
@classmethod
def create_port(cls, network, client_mgr=None, **kwargs):
"""create port."""
client_mgr = client_mgr if client_mgr else cls.admin_mgr
body = client_mgr.ports_client.create_port(
network_id=network['id'], **kwargs)
port = body.get('port', body)
cls.ports.append(port)
return port
@classmethod
def update_port(cls, port_id, client_mgr=None, **kwargs):
"""update port."""
client_mgr = client_mgr if client_mgr else cls.admin_mgr
body = client_mgr.ports_client.update_port(
port_id, **kwargs)
return body.get('port', body)
@classmethod
def show_port(cls, port_id, client_mgr=None):
"""show port."""
client_mgr = client_mgr if client_mgr else cls.admin_mgr
body = client_mgr.ports_client.show_port(port_id)
return body.get('port', body)
@classmethod
def delete_port(cls, port_id, client_mgr=None, **kwargs):
"""delete port."""
client_mgr = client_mgr if client_mgr else cls.admin_mgr
body = client_mgr.ports_client.delete_port(port_id)
return body.get('port', body)
@classmethod
def create_network(cls, network_name=None, client_mgr=None, **kwargs):
"""create network."""
network_name = network_name or data_utils.rand_name('qos-net')
client_mgr = client_mgr if client_mgr else cls.admin_mgr
body = client_mgr.networks_client.create_network(
name=network_name, **kwargs)
network = body['network']
cls.networks.append(network)
return network
@classmethod
def create_shared_network(cls, network_name=None, client_mgr=None,
**kwargs):
"""create shared network."""
return cls.create_network(network_name, client_mgr,
shared=True, **kwargs)
@classmethod
def show_network(cls, network_id, client_mgr=None):
"""show network."""
client_mgr = client_mgr if client_mgr else cls.admin_mgr
network = client_mgr.networks_client.show_network(network_id)
return network.get('network', network)
@classmethod
def update_network(cls, network_id, client_mgr=None, **kwargs):
"""update network."""
client_mgr = client_mgr if client_mgr else cls.admin_mgr
network = client_mgr.networks_client.update_network(
network_id, **kwargs)
return network.get('network', network)
@classmethod
def delete_network(cls, network_id, client_mgr=None):
"""delete network."""
client_mgr = client_mgr if client_mgr else cls.admin_mgr
network = client_mgr.networks_client.delete_network(network_id)
return network.get('network', network)
@classmethod
def create_qos_policy(cls, name='test-policy',
description='test policy desc',
shared=False,
qos_client=None, **kwargs):
"""create qos policy."""
qos_client = qos_client if qos_client else cls.adm_qos_client
policy = qos_client.create_policy(
name=name, description=description,
shared=shared, **kwargs)
cls.policies_created.append(policy)
return policy
@classmethod
def create_qos_bandwidth_limit_rule(cls, policy_id,
qos_client=None, **kwargs):
"""create qos-bandwidth-limit-rule."""
qos_client = qos_client if qos_client else cls.adm_qos_client
rule = qos_client.create_bandwidth_limit_rule(policy_id, **kwargs)
return rule
@classmethod
def create_qos_dscp_marking_rule(cls, policy_id, dscp_mark,
qos_client=None, **kwargs):
"""create qos-dscp-marking-rule."""
qos_client = qos_client if qos_client else cls.adm_qos_client
rule = qos_client.create_dscp_marking_rule(
policy_id, dscp_mark, **kwargs)
return rule
class QosPolicyTest(BaseQosTest):
"""QoS Policy CURD operations.
test qos policies and network/port association and disassociation.
"""
@decorators.idempotent_id('108fbdf7-3463-4e47-9871-d07f3dcf5bbb')
def test_create_policy(self):
"""qos-policy-create: create policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy desc1',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
# Test 'show policy'
retrieved_policy = self.adm_qos_client.show_policy(policy['id'])
self.assertEqual('test-policy', retrieved_policy['name'])
self.assertEqual('test policy desc1',
retrieved_policy['description'])
self.assertFalse(retrieved_policy['shared'])
# Test 'list policies'
policies = self.adm_qos_client.list_policies()
policies_ids = [p['id'] for p in policies]
self.assertIn(policy['id'], policies_ids)
@decorators.idempotent_id('f8d20e92-f06d-4805-b54f-230f77715815')
def test_list_policy_filter_by_name(self):
"""qos-policy-list --name=<name>: list policies."""
name1 = data_utils.rand_name('test-policy')
name2 = name1 + "0"
policy_name1 = self.create_qos_policy(
name=name1, description='test policy', shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy_name1['id'])
policy_name2 = self.create_qos_policy(
name=name2, description='test policy', shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy_name2['id'])
policies = self.adm_qos_client.list_policies(name=name1)
self.assertEqual(1, len(policies))
retrieved_policy = policies[0]
self.assertEqual(name1, retrieved_policy['name'])
@decorators.idempotent_id('8e88a54b-f0b2-4b7d-b061-a15d93c2c7d6')
def test_policy_update(self):
"""qos-policy-update POLICY_ID."""
policy = self.create_qos_policy(name='test-policy',
description='',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
self.adm_qos_client.update_policy(policy['id'],
description='test policy desc2',
shared=True)
retrieved_policy = self.adm_qos_client.show_policy(policy['id'])
self.assertEqual('test policy desc2',
retrieved_policy['description'])
self.assertTrue(retrieved_policy['shared'])
self.assertEmpty(retrieved_policy['rules'])
@decorators.idempotent_id('1cb42653-54bd-4a9a-b888-c55e18199201')
def test_delete_policy(self):
"""qos-policy-delete POLICY_ID."""
policy = self.create_qos_policy(
'test-policy', 'desc', True)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
retrieved_policy = self.adm_qos_client.show_policy(policy['id'])
self.assertEqual('test-policy', retrieved_policy['name'])
self.adm_qos_client.delete_policy(policy['id'])
self.assertRaises(exceptions.NotFound,
self.adm_qos_client.show_policy, policy['id'])
def _test_list_admin_rule_types(self):
"""qos-available-rule-types: available rule type from admin view."""
self._test_list_rule_types(self.adm_qos_client)
def _test_list_regular_rule_types(self):
"""qos-available-rule-types: available rule type from project view."""
self._test_list_rule_types(self.pri_qos_client)
def _test_list_rule_types(self, client):
# List supported rule types
# TODO(QoS): since in gate we run both ovs and linuxbridge ml2 drivers,
# and since Linux Bridge ml2 driver does not have QoS support yet, ml2
# plugin reports no rule types are supported. Once linuxbridge will
# receive support for QoS, the list of expected rule types will change.
#
# In theory, we could make the test conditional on which ml2 drivers
# are enabled in gate (or more specifically, on which supported qos
# rules are claimed by core plugin), but that option doesn't seem to be
# available thru tempest.lib framework
expected_rule_types = []
expected_rule_details = ['type']
rule_types = client.available_rule_types()
actual_rule_types = [rule['type'] for rule in rule_types]
# TODO(akang): seems not correct
# Verify that only required fields present in rule details
for rule in actual_rule_types:
self.assertEqual(tuple(rule.keys()), tuple(expected_rule_details))
# Verify if expected rules are present in the actual rules list
for rule in expected_rule_types:
self.assertIn(rule, actual_rule_types)
def _disassociate_network(self, network_id, client_mgr=None):
self.update_network(network_id, client_mgr=client_mgr,
qos_policy_id=None)
updated_network = self.show_network(network_id,
client_mgr=client_mgr)
self.assertIsNone(updated_network['qos_policy_id'])
@decorators.idempotent_id('65b9ef75-1911-406a-bbdb-ca1d68d528b0')
def test_policy_association_with_admin_network(self):
"""admin can create network with non-shared policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_shared_network('test network',
qos_policy_id=policy['id'])
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
retrieved_network = self.show_network(network['id'])
self.assertEqual(
policy['id'], retrieved_network['qos_policy_id'])
self._disassociate_network(network['id'], self.admin_mgr)
@decorators.idempotent_id('1738de5d-0476-4163-9022-5e1b548c208e')
def test_policy_association_with_tenant_network(self):
"""project/tenant can create network with shared policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=True)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_network('test network',
client_mgr=self.primary_mgr,
qos_policy_id=policy['id'])
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
retrieved_network = self.show_network(network['id'],
client_mgr=self.primary_mgr)
self.assertEqual(
policy['id'], retrieved_network['qos_policy_id'])
self._disassociate_network(network['id'], self.primary_mgr)
@decorators.attr(type='negative')
@decorators.idempotent_id('9efe63d0-836f-4cc2-b00c-468e63aa614e')
def test_policy_association_with_network_nonexistent_policy(self):
"""Can not attach network to a nonexist policy."""
network = self.create_network(
'test network',
qos_policy_id='9efe63d0-836f-4cc2-b00c-468e63aa614e')
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
retrieved_network = self.show_network(network['id'])
# check if network is not attached to the policy
self.assertIsNone(retrieved_network['qos_policy_id'],
'Error: Network is attached to non-existent policy')
@decorators.attr(type='negative')
@decorators.idempotent_id('1aa55a79-324f-47d9-a076-894a8fc2448b')
def test_policy_association_with_network_non_shared_policy(self):
"""tenant/project can not attach network with not-shared policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_network(
'test network',
qos_policy_id=policy['id'],
client_mgr=self.primary_mgr)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
retrieved_network = self.show_network(network['id'],
client_mgr=self.primary_mgr)
# check if network is not attached to the policy
self.assertIsNone(retrieved_network['qos_policy_id'],
'Error: Network is attached to QoS policy')
@decorators.idempotent_id('10a9392c-1359-4cbb-989f-fb768e5834a8')
def test_policy_update_association_with_admin_network(self):
"""admin can create associate non-shared policy to network."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_shared_network('test network')
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
retrieved_network = self.show_network(network['id'])
self.assertIsNone(retrieved_network['qos_policy_id'])
self.update_network(
network['id'], qos_policy_id=policy['id'])
retrieved_network = self.show_network(network['id'])
self.assertEqual(
policy['id'], retrieved_network['qos_policy_id'])
self._disassociate_network(network['id'], self.admin_mgr)
def _disassociate_port(self, port_id, client_mgr=None):
client_mgr = client_mgr if client_mgr else self.admin_mgr
self.update_port(port_id, qos_policy_id=None,
client_mgr=client_mgr)
updated_port = self.show_port(port_id, client_mgr=client_mgr)
self.assertIsNone(updated_port['qos_policy_id'])
@decorators.attr(type='nsxv3')
@decorators.attr(type='negative')
@decorators.idempotent_id('98fcd95e-84cf-4746-860e-44692e674f2e')
def test_policy_association_with_port_shared_policy(self):
"""test port can associate shared policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=True)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_shared_network('test network')
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
port = self.create_port(network, qos_policy_id=policy['id'],
client_mgr=self.primary_mgr)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, port['id'])
retrieved_port = self.show_port(port['id'],
client_mgr=self.primary_mgr)
self.assertEqual(
policy['id'], retrieved_port['qos_policy_id'])
self._disassociate_port(port['id'], client_mgr=self.primary_mgr)
@decorators.attr(type='negative')
@decorators.attr(type='nsxv3')
@decorators.idempotent_id('49e02f5a-e1dd-41d5-9855-cfa37f2d195e')
def test_policy_association_with_port_nonexistent_policy(self):
"""test port cannot be created with nonexist policy."""
network = self.create_shared_network('test network')
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
self.assertRaises(
exceptions.NotFound,
self.create_port,
network,
qos_policy_id='49e02f5a-e1dd-41d5-9855-cfa37f2d195e')
@decorators.attr(type='negative')
@decorators.attr(type='nsxv3')
@decorators.idempotent_id('f53d961c-9fe5-4422-8b66-7add972c6031')
def test_policy_association_with_port_non_shared_policy(self):
"""project/tenant can not associate port with non-shared policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_shared_network('test network')
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
port = self.create_port(network, qos_policy_id=policy['id'],
client_mgr=self.primary_mgr)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, port['id'])
retrieved_port = self.show_port(port['id'],
client_mgr=self.primary_mgr)
# check if port is not attached to the policy
self.assertIsNone(retrieved_port['qos_policy_id'],
'Error:Port is attached to qos policy')
@decorators.attr(type='nsxv3')
@decorators.idempotent_id('f8163237-fba9-4db5-9526-bad6d2343c76')
def test_policy_update_association_with_port_shared_policy(self):
"""project/tenant can update port with shared policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=True)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_shared_network('test network')
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
port = self.create_port(network, client_mgr=self.primary_mgr)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, port['id'])
retrieved_port = self.show_port(port['id'],
client_mgr=self.primary_mgr)
self.assertIsNone(retrieved_port['qos_policy_id'])
self.update_port(port['id'], qos_policy_id=policy['id'],
client_mgr=self.primary_mgr)
retrieved_port = self.show_port(port['id'],
client_mgr=self.primary_mgr)
self.assertEqual(
policy['id'], retrieved_port['qos_policy_id'])
self._disassociate_port(port['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('18163237-8ba9-4db5-9525-bad6d2343c75')
def test_delete_not_allowed_if_policy_in_use_by_network(self):
"""can not delete policy if used by network."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=True)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_shared_network(
'test network', qos_policy_id=policy['id'])
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
self.assertRaises(
exceptions.Conflict,
self.adm_qos_client.delete_policy, policy['id'])
self._disassociate_network(network['id'], self.admin_mgr)
self.adm_qos_client.delete_policy(policy['id'])
@decorators.attr(type='negative')
@decorators.attr(type='nsxv3')
@decorators.idempotent_id('24153230-84a9-4dd5-9525-bad6d2343c75')
def test_delete_not_allowed_if_policy_in_use_by_port(self):
"""can not delete policy if used by port."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=True)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
network = self.create_shared_network('test network')
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
port = self.create_port(network, qos_policy_id=policy['id'],
client_mgr=self.primary_mgr)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, port['id'])
self.assertRaises(
exceptions.Conflict,
self.adm_qos_client.delete_policy, policy['id'])
self._disassociate_port(port['id'], client_mgr=self.primary_mgr)
self.adm_qos_client.delete_policy(policy['id'])
@decorators.idempotent_id('a2a5849b-dd06-4b18-9664-0b6828a1fc27')
def test_qos_policy_delete_with_rules(self):
"""Policy with rules attached can be deleted."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
self.adm_qos_client.create_bandwidth_limit_rule(
policy['id'], 200, 1337)
self.adm_qos_client.delete_policy(policy['id'])
with testtools.ExpectedException(exceptions.NotFound):
self.adm_qos_client.show_policy(policy['id'])
class QosBandwidthLimitRuleTest(BaseQosTest):
"""QoS Bandwidth limit rule CURD operations."""
@decorators.idempotent_id('8a59b00b-3e9c-4787-92f8-93a5cdf5e378')
def test_rule_create(self):
"""qos-bandwidth-limit-rule-create POLICY_ID."""
qos_client = self.adm_qos_client
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
rule = self.create_qos_bandwidth_limit_rule(
policy_id=policy['id'], max_kbps=200, max_burst_kbps=1337)
# Test 'show rule'
retrieved_rule = qos_client.show_bandwidth_limit_rule(
rule['id'], policy['id'])
self.assertEqual(rule['id'], retrieved_rule['id'])
self.assertEqual(200, retrieved_rule['max_kbps'])
self.assertEqual(1337, retrieved_rule['max_burst_kbps'])
# Test 'list rules'
rules = qos_client.list_bandwidth_limit_rules(policy['id'])
rules_ids = [r['id'] for r in rules]
self.assertIn(rule['id'], rules_ids)
# Test 'show policy'
retrieved_policy = qos_client.show_policy(policy['id'])
policy_rules = retrieved_policy['rules']
self.assertEqual(1, len(policy_rules))
self.assertEqual(rule['id'], policy_rules[0]['id'])
self.assertEqual(base_qos.RULE_TYPE_BANDWIDTH_LIMIT,
policy_rules[0]['type'])
@decorators.attr(type='negative')
@decorators.idempotent_id('8a59b00b-ab01-4787-92f8-93a5cdf5e378')
def test_rule_create_fail_for_the_same_type(self):
"""One bandwidth limit rule per policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
self.create_qos_bandwidth_limit_rule(
policy_id=policy['id'], max_kbps=200, max_burst_kbps=1337)
self.assertRaises(exceptions.Conflict,
self.create_qos_bandwidth_limit_rule,
policy_id=policy['id'],
max_kbps=201, max_burst_kbps=1338)
@decorators.idempotent_id('149a6988-2568-47d2-931e-2dbc858943b3')
def test_rule_update(self):
"""qos-bandwidth-limit-rule-update RULE-ID POLICY_ID."""
qos_client = self.adm_qos_client
max_kbps = 200
max_burst_kbps = 1337
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
rule = self.create_qos_bandwidth_limit_rule(
policy_id=policy['id'], max_kbps=1, max_burst_kbps=1)
qos_client.update_bandwidth_limit_rule(
rule['id'], policy['id'],
max_kbps=max_kbps, max_burst_kbps=max_burst_kbps)
retrieved_rule = qos_client.show_bandwidth_limit_rule(
rule['id'], policy['id'])
self.assertEqual(max_kbps, retrieved_rule['max_kbps'])
self.assertEqual(max_burst_kbps, retrieved_rule['max_burst_kbps'])
@decorators.idempotent_id('67ee6efd-7b33-4a68-927d-275b4f8ba958')
def test_rule_delete(self):
"""qos-bandwidth-limit-rule-delete RULE-ID POLICY_ID."""
qos_client = self.adm_qos_client
max_kbps = 200
max_burst_kbps = 1337
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
rule = self.create_qos_bandwidth_limit_rule(
policy['id'],
max_kbps=max_kbps, max_burst_kbps=max_burst_kbps)
retrieved_rule = qos_client.show_bandwidth_limit_rule(
rule['id'], policy['id'])
self.assertEqual(rule['id'], retrieved_rule['id'])
qos_client.delete_bandwidth_limit_rule(
rule['id'], policy['id'])
self.assertRaises(exceptions.NotFound,
qos_client.show_bandwidth_limit_rule,
rule['id'], policy['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('f211222c-5808-46cb-a961-983bbab6b852')
def test_rule_create_rule_nonexistent_policy(self):
"""Cannot create rule with nonexist policy."""
self.assertRaises(
exceptions.NotFound,
self.create_qos_bandwidth_limit_rule,
'policy', max_kbps=200, max_burst_kbps=1337)
@decorators.attr(type='negative')
@decorators.idempotent_id('eed8e2a6-22da-421b-89b9-935a2c1a1b50')
def test_policy_create_forbidden_for_regular_tenants(self):
"""project/tenant cannot create policy."""
self.assertRaises(
exceptions.Forbidden,
self.create_qos_policy,
'test-policy', 'test policy', False,
qos_client=self.pri_qos_client)
@decorators.attr(type='negative')
@decorators.idempotent_id('a4a2e7ad-786f-4927-a85a-e545a93bd274')
def test_rule_create_forbidden_for_regular_tenants(self):
"""project/tenant cannot create rule."""
self.assertRaises(
exceptions.Forbidden,
self.create_qos_bandwidth_limit_rule,
'policy', max_kbps=1, max_burst_kbps=2,
qos_client=self.pri_qos_client)
@decorators.idempotent_id('ce0bd0c2-54d9-4e29-85f1-cfb36ac3ebe2')
def test_get_rules_by_policy(self):
"""qos-bandwidth-limit-rule-list POLICY_ID."""
policy1 = self.create_qos_policy(name='test-policy1',
description='test policy1',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy1['id'])
rule1 = self.create_qos_bandwidth_limit_rule(
policy_id=policy1['id'], max_kbps=200, max_burst_kbps=1337)
policy2 = self.create_qos_policy(name='test-policy2',
description='test policy2',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy2['id'])
rule2 = self.create_qos_bandwidth_limit_rule(
policy_id=policy2['id'], max_kbps=5000, max_burst_kbps=2523)
# Test 'list rules'
rules = self.adm_qos_client.list_bandwidth_limit_rules(policy1['id'])
rules_ids = [r['id'] for r in rules]
self.assertIn(rule1['id'], rules_ids)
self.assertNotIn(rule2['id'], rules_ids)
class QosDscpMarkingRuleTest(BaseQosTest):
"""QoS Dscp Marking Rule CRUD operation."""
VALID_DSCP_MARK1 = 56
VALID_DSCP_MARK2 = 48
@decorators.idempotent_id('8a59b40b-3e9c-4787-92f8-93a5cdf5e378')
def test_rule_create(self):
"""qos-dscp-marking-rule-create POLICY_ID."""
qos_client = self.adm_qos_client
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
rule = self.create_qos_dscp_marking_rule(
policy['id'], self.VALID_DSCP_MARK1)
# Test 'show rule'
retrieved_rule = qos_client.show_dscp_marking_rule(
rule['id'], policy['id'])
self.assertEqual(rule['id'], retrieved_rule['id'])
self.assertEqual(self.VALID_DSCP_MARK1, retrieved_rule['dscp_mark'])
# Test 'list rules'
rules = qos_client.list_dscp_marking_rules(policy['id'])
rules_ids = [r['id'] for r in rules]
self.assertIn(rule['id'], rules_ids)
# Test 'show policy'
retrieved_policy = qos_client.show_policy(policy['id'])
policy_rules = retrieved_policy['rules']
self.assertEqual(1, len(policy_rules))
self.assertEqual(rule['id'], policy_rules[0]['id'])
self.assertEqual(base_qos.RULE_TYPE_DSCP_MARK,
policy_rules[0]['type'])
@decorators.attr(type='negative')
@decorators.idempotent_id('8b59b10b-ab01-4787-92f8-93a5cdf5e378')
def test_rule_create_fail_for_the_same_type(self):
"""One dscp marking rule per policy."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
self.create_qos_dscp_marking_rule(
policy['id'], self.VALID_DSCP_MARK1)
self.assertRaises(exceptions.Conflict,
self.create_qos_dscp_marking_rule,
policy_id=policy['id'],
dscp_mark=self.VALID_DSCP_MARK2)
@decorators.idempotent_id('249a6988-2568-47d2-931e-2dbc858943b3')
def test_rule_update(self):
"""qos-dscp-marking-rule-create POLICY_ID."""
qos_client = self.adm_qos_client
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
rule = self.create_qos_dscp_marking_rule(
policy['id'], self.VALID_DSCP_MARK1)
qos_client.update_dscp_marking_rule(
rule['id'], policy['id'], dscp_mark=self.VALID_DSCP_MARK2)
retrieved_rule = qos_client.show_dscp_marking_rule(
rule['id'], policy['id'])
self.assertEqual(self.VALID_DSCP_MARK2, retrieved_rule['dscp_mark'])
@decorators.idempotent_id('67ed6efd-7b33-4a68-927d-275b4f8ba958')
def test_rule_delete(self):
"""qos-dscp-marking-rule-delete POLICY_ID."""
qos_client = self.adm_qos_client
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
rule = self.create_qos_dscp_marking_rule(
policy['id'], self.VALID_DSCP_MARK1)
retrieved_rule = qos_client.show_dscp_marking_rule(
rule['id'], policy['id'])
self.assertEqual(rule['id'], retrieved_rule['id'])
qos_client.delete_dscp_marking_rule(rule['id'], policy['id'])
self.assertRaises(exceptions.NotFound,
qos_client.show_dscp_marking_rule,
rule['id'], policy['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('f215222c-5808-46cb-a961-983bbab6b852')
def test_rule_create_rule_nonexistent_policy(self):
"""can not create dscp marking rule with nonexist policy."""
self.assertRaises(
exceptions.NotFound,
self.create_qos_dscp_marking_rule,
'policy', self.VALID_DSCP_MARK1)
@decorators.attr(type='negative')
@decorators.idempotent_id('a4a2e3ad-786f-4927-a85a-e545a93bd274')
def test_rule_create_forbidden_for_regular_tenants(self):
"""project/tenant can not create dscp marking rule."""
self.assertRaises(
exceptions.Forbidden,
self.create_qos_dscp_marking_rule,
'policy', self.VALID_DSCP_MARK1,
qos_client=self.pri_qos_client)
@decorators.attr(type='negative')
@decorators.idempotent_id('32646b08-4f05-4493-a48a-bde768a18533')
def test_invalid_rule_create(self):
"""Can not create rule with invalid dscp_mark value."""
policy = self.create_qos_policy(name='test-policy',
description='test policy',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy['id'])
self.assertRaises(
exceptions.BadRequest,
self.create_qos_dscp_marking_rule,
policy['id'], 58)
@decorators.idempotent_id('cf0bd0c2-54d9-4e29-85f1-cfb36ac3ebe2')
def test_get_rules_by_policy(self):
"""qos-dscp-marking-rule-list POLICY_ID."""
policy1 = self.create_qos_policy(name='test-policy1',
description='test policy1',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy1['id'])
rule1 = self.create_qos_dscp_marking_rule(
policy1['id'], self.VALID_DSCP_MARK1)
policy2 = self.create_qos_policy(name='test-policy2',
description='test policy2',
shared=False)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.adm_qos_client.delete_policy, policy2['id'])
rule2 = self.create_qos_dscp_marking_rule(
policy2['id'], self.VALID_DSCP_MARK2)
# Test 'list rules'
rules = self.adm_qos_client.list_dscp_marking_rules(policy1['id'])
rules_ids = [r['id'] for r in rules]
self.assertIn(rule1['id'], rules_ids)
self.assertNotIn(rule2['id'], rules_ids)

View File

@ -1,23 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2010-2011 OpenStack Foundation
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# 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 base
class TestCase(base.BaseTestCase):
"""Test case base class for all unit tests."""

View File

@ -1,6 +0,0 @@
Placeholder for dvs plugin specific automated tests
directory:
dvs/
api/
scenario/

View File

@ -1,157 +0,0 @@
# 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 netaddr
from tempest.api.network import base
from tempest import config
from tempest import exceptions
from tempest.lib.common.utils import data_utils
import tempest.test
CONF = config.CONF
class BaseDvsAdminNetworkTest(base.BaseAdminNetworkTest):
@classmethod
def resource_cleanup(cls):
for port in cls.ports:
cls.admin_ports_client.delete_port(port['id'])
for subnet in cls.subnets:
cls.admin_subnets_client.delete_subnet(subnet['id'])
for network in cls.networks:
cls.admin_networks_client.delete_network(network['id'])
# clean up ports, subnets and networks
cls.ports = []
cls.subnets = []
cls.networks = []
@classmethod
def create_network(cls, **kwargs):
"""Wrapper utility that returns a test admin provider network."""
network_name = (kwargs.get('net_name')
or data_utils.rand_name('test-adm-net-'))
net_type = kwargs.get('net_type', "flat")
if tempest.test.is_extension_enabled('provider', 'network'):
body = {'name': network_name}
body.update({'provider:network_type': net_type,
'provider:physical_network': 'dvs'})
if net_type == 'vlan':
_vlanid = kwargs.get('seg_id')
body.update({'provider:segmentation_id': _vlanid})
body = cls.admin_networks_client.create_network(**body)
network = body['network']
cls.networks.append(network)
return network
@classmethod
def create_subnet(cls, network):
"""Wrapper utility that returns a test subnet."""
# The cidr and mask_bits depend on the ip version.
if cls._ip_version == 4:
cidr = netaddr.IPNetwork(CONF.network.project_network_cidr
or "192.168.101.0/24")
mask_bits = CONF.network.project_network_mask_bits or 24
elif cls._ip_version == 6:
cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
mask_bits = CONF.network.project_network_v6_mask_bits
# Find a cidr that is not in use yet and create a subnet with it
for subnet_cidr in cidr.subnet(mask_bits):
try:
body = cls.admin_subnets_client.create_subnet(
network_id=network['id'],
cidr=str(subnet_cidr),
ip_version=cls._ip_version)
break
except exceptions.BadRequest as e:
is_overlapping_cidr = 'overlaps with another subnet' in str(e)
if not is_overlapping_cidr:
raise
else:
message = 'Available CIDR for subnet creation could not be found'
raise exceptions.BuildErrorException(message)
subnet = body['subnet']
cls.subnets.append(subnet)
return subnet
@classmethod
def create_port(cls, network_id, **kwargs):
"""Wrapper utility that returns a test port."""
body = cls.admin_ports_client.create_port(network_id=network_id,
**kwargs)
port = body['port']
cls.ports.append(port)
return port
@classmethod
def update_network(cls, network_id, client=None, **kwargs):
net_client = client if client else cls.admin_networks_client
return net_client.update_network(network_id, **kwargs)
@classmethod
def delete_network(cls, network_id, client=None):
net_client = client if client else cls.admin_networks_client
return net_client.delete_network(network_id)
@classmethod
def show_network(cls, network_id, client=None, **kwargs):
net_client = client if client else cls.admin_networks_client
return net_client.show_network(network_id, **kwargs)
@classmethod
def list_networks(cls, client=None, **kwargs):
net_client = client if client else cls.admin_networks_client
return net_client.list_networks(**kwargs)
@classmethod
def update_subnet(cls, subnet_id, client=None, **kwargs):
net_client = client if client else cls.admin_subnets_client
return net_client.update_subnet(subnet_id, **kwargs)
@classmethod
def delete_subnet(cls, subnet_id, client=None):
net_client = client if client else cls.admin_subnets_client
return net_client.delete_subnet(subnet_id)
@classmethod
def show_subnet(cls, subnet_id, client=None, **kwargs):
net_client = client if client else cls.admin_subnets_client
return net_client.show_subnet(subnet_id, **kwargs)
@classmethod
def list_subnets(cls, client=None, **kwargs):
net_client = client if client else cls.admin_subnets_client
return net_client.list_subnets(**kwargs)
@classmethod
def delete_port(cls, port_id, client=None):
net_client = client if client else cls.admin_ports_client
return net_client.delete_port(port_id)
@classmethod
def show_port(cls, port_id, client=None, **kwargs):
net_client = client if client else cls.admin_ports_client
return net_client.show_port(port_id, **kwargs)
@classmethod
def list_ports(cls, client=None, **kwargs):
net_client = client if client else cls.admin_ports_client
return net_client.list_ports(**kwargs)
@classmethod
def update_port(cls, port_id, client=None, **kwargs):
net_client = client if client else cls.admin_ports_client
return net_client.update_port(port_id, **kwargs)

View File

@ -1,122 +0,0 @@
# Copyright 2014 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 base_dvs as base
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
class AdminNetworksTestJSON(base.BaseDvsAdminNetworkTest):
_interface = 'json'
"""
Test admin actions for networks, subnets.
create/update/delete an admin network
create/update/delete an admin subnets
"""
@classmethod
def resource_setup(cls):
super(AdminNetworksTestJSON, cls).resource_setup()
name = data_utils.rand_name('admin-network-')
cls.network = cls.create_network(net_name=name)
cls.name = cls.network['name']
cls.subnet = cls.create_subnet(cls.network)
cls.cidr = cls.subnet['cidr']
@decorators.attr(type='smoke')
@decorators.idempotent_id('1dcead1d-d773-4da1-9534-0b984ca684b3')
def test_create_update_delete_flat_network_subnet(self):
# Create an admin network
name = data_utils.rand_name('admin-network-')
network = self.create_network(net_name=name, net_type='flat')
net_id = network['id']
# Verify an exception thrown when updating network
new_name = "New_network"
# create a subnet and verify it is an admin tenant subnet
subnet = self.create_subnet(network)
subnet_id = subnet['id']
self.assertEqual(network['tenant_id'], subnet['tenant_id'])
# Verify subnet update
new_name = "New_subnet"
body = self.update_subnet(subnet_id, name=new_name)
updated_subnet = body['subnet']
self.assertEqual(updated_subnet['name'], new_name)
# Delete subnet and network
body = self.delete_subnet(subnet_id)
# Remove subnet from cleanup list
self.subnets.pop()
body = self.delete_network(net_id)
self.networks.pop()
@decorators.attr(type='smoke')
@decorators.idempotent_id('15d3d53c-3328-401f-b8f5-3a29aee2ea3a')
def test_create_update_delete_vlan_network_subnet(self):
# Create an admin network
name = data_utils.rand_name('admin-network-')
network = self.create_network(net_name=name,
net_type='vlan',
seg_id=1000)
net_id = network['id']
# Verify an exception thrown when updating network
new_name = "New_network"
# create a subnet and verify it is an admin tenant subnet
subnet = self.create_subnet(network)
subnet_id = subnet['id']
self.assertEqual(network['tenant_id'], subnet['tenant_id'])
# Verify subnet update
new_name = "New_subnet"
body = self.update_subnet(subnet_id, name=new_name)
updated_subnet = body['subnet']
self.assertEqual(updated_subnet['name'], new_name)
# Delete subnet and network
body = self.delete_subnet(subnet_id)
# Remove subnet from cleanup list
self.subnets.pop()
body = self.delete_network(net_id)
self.networks.pop()
@decorators.attr(type='smoke')
@decorators.idempotent_id('838aee5f-92f2-47b9-86c6-629a04aa6269')
def test_show_network(self):
# Verify the details of a network
body = self.show_network(self.network['id'])
network = body['network']
for key in ['id', 'name', 'provider:network_type',
'provider:physical_network']:
self.assertEqual(network[key], self.network[key])
@decorators.attr(type='smoke')
@decorators.idempotent_id('b86d50ef-39a7-4136-8c89-e5e534fe92aa')
def test_list_networks(self):
# Verify the network exists in the list of all networks
body = self.list_networks()
networks = [network['id'] for network in body['networks']
if network['id'] == self.network['id']]
self.assertNotEmpty(networks, "Created network not found in the list")
@decorators.attr(type='smoke')
@decorators.idempotent_id('ee3f8b79-da3f-4394-9bea-012488202257')
def test_show_subnet(self):
# Verify the details of a subnet
body = self.show_subnet(self.subnet['id'])
subnet = body['subnet']
self.assertNotEmpty(subnet, "Subnet returned has no fields")
for key in ['id', 'cidr']:
self.assertIn(key, subnet)
self.assertEqual(subnet[key], self.subnet[key])

View File

@ -1,98 +0,0 @@
# Copyright 2014 OpenStack Foundation
# 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 base_dvs as base
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
class AdminPortsTestJSON(base.BaseDvsAdminNetworkTest):
_interface = 'json'
"""
Test the following operations for ports:
port create
port delete
port list
port show
port update
"""
@classmethod
def resource_setup(cls):
super(AdminPortsTestJSON, cls).resource_setup()
name = data_utils.rand_name('admin-ports-')
cls.network = cls.create_network(net_name=name)
cls.port = cls.create_port(cls.network['id'])
@decorators.idempotent_id('c3f751d4-e358-44b9-bfd2-3d563c4a2d04')
def test_create_update_delete_port(self):
# Verify port creation
network_id = self.network['id']
port = self.create_port(network_id)
self.assertTrue(port['admin_state_up'])
# Verify port update
new_name = "New_Port"
body = self.update_port(
port['id'],
name=new_name,
admin_state_up=False)
updated_port = body['port']
self.assertEqual(updated_port['name'], new_name)
self.assertFalse(updated_port['admin_state_up'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('d3dcd23b-7d5a-4720-8d88-473fb154d609')
def test_show_port(self):
# Verify the details of port
body = self.show_port(self.port['id'])
port = body['port']
self.assertIn('id', port)
self.assertEqual(port['id'], self.port['id'])
self.assertEqual(self.port['admin_state_up'], port['admin_state_up'])
self.assertEqual(self.port['device_id'], port['device_id'])
self.assertEqual(self.port['device_owner'], port['device_owner'])
self.assertEqual(self.port['mac_address'], port['mac_address'])
self.assertEqual(self.port['name'], port['name'])
self.assertEqual(self.port['security_groups'],
port['security_groups'])
self.assertEqual(self.port['network_id'], port['network_id'])
self.assertEqual(self.port['security_groups'],
port['security_groups'])
self.assertEqual(port['fixed_ips'], [])
@decorators.attr(type='smoke')
@decorators.idempotent_id('c5f74042-c512-4569-b9b9-bc2bf46e77e1')
def test_list_ports(self):
# Verify the port exists in the list of all ports
body = self.list_ports()
ports = [port['id'] for port in body['ports']
if port['id'] == self.port['id']]
self.assertNotEmpty(ports, "Created port not found in the list")
@decorators.idempotent_id('2775f96c-a09b-49e1-a5a4-adb83a3e91c7')
@decorators.attr(type='smoke')
def test_list_ports_fields(self):
# Verify specific fields of ports
fields = ['binding:vif_type', 'id', 'mac_address']
body = self.list_ports(fields=fields)
ports = body['ports']
self.assertNotEmpty(ports, "Port list returned is empty")
# Asserting the fields returned are correct
# Verify binding:vif_type is dvs
for port in ports:
self.assertEqual(sorted(fields), sorted(port.keys()))
self.assertEqual(port.get(fields[0]), 'dvs')

View File

@ -1,193 +0,0 @@
# 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 netaddr
from oslo_log import log as logging
from tempest import config
from tempest import exceptions
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest import test
from vmware_nsx_tempest.tests.scenario import manager
CONF = config.CONF
LOG = logging.getLogger(__name__)
class TestDvsNetworkBasicOps(manager.NetworkScenarioTest):
"""
This smoke test suite assumes that Nova has been configured to
boot VM's with Neutron-managed VDS networking, and attempts to
verify network connectivity as follows:
"""
def setUp(self):
super(TestDvsNetworkBasicOps, self).setUp()
self._ip_version = 4
self.keypairs = {}
self.servers = []
self.admin_net_client = self.admin_manager.networks_client
self.admin_subnet_client = self.admin_manager.subnets_client
def _setup_network(self):
self.network = self._create_network()
self.subnet = self._create_subnet(self.network)
def _list_ports(self, *args, **kwargs):
"""List ports using admin creds """
ports_list = self.admin_manager.ports_client.list_ports(
*args, **kwargs)
return ports_list['ports']
def _create_network(self, network_name=None):
"""Wrapper utility that returns a test admin provider network."""
network_name = network_name or data_utils.rand_name('test-adm-net-')
if test.is_extension_enabled('provider', 'network'):
body = {'name': network_name}
body.update({'provider:network_type': 'flat',
'provider:physical_network': 'dvs',
'shared': True})
body = self.admin_net_client.create_network(**body)
self.addCleanup(self.admin_net_client.delete_network,
body['network']['id'])
return body['network']
def _create_subnet(self, network):
# The cidr and mask_bits depend on the ip version.
if self._ip_version == 4:
cidr = netaddr.IPNetwork(CONF.network.project_network_cidr
or "192.168.101.0/24")
mask_bits = CONF.network.project_network_mask_bits or 24
elif self._ip_version == 6:
cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
mask_bits = CONF.network.project_network_v6_mask_bits
# Find a cidr that is not in use yet and create a subnet with it
for subnet_cidr in cidr.subnet(mask_bits):
try:
body = self.admin_subnet_client.create_subnet(
network_id=network['id'],
cidr=str(subnet_cidr),
ip_version=self._ip_version)
break
except exceptions.BadRequest as e:
is_overlapping_cidr = 'overlaps with another subnet' in str(e)
if not is_overlapping_cidr:
raise
else:
message = ('Available CIDR for subnet creation '
'could not be found')
raise exceptions.BuildErrorException(message)
return body['subnet']
def _check_networks(self):
"""
Checks that we see the newly created network/subnet via
checking the result of list_[networks,subnets]
"""
seen_nets = self.admin_manager.networks_client.list_networks()
seen_names = [n['name'] for n in seen_nets['networks']]
seen_ids = [n['id'] for n in seen_nets['networks']]
self.assertIn(self.network['name'], seen_names)
self.assertIn(self.network['id'], seen_ids)
seen_subnets = self.admin_manager.subnets_client.list_subnets()
seen_net_ids = [n['network_id'] for n in seen_subnets['subnets']]
seen_subnet_ids = [n['id'] for n in seen_subnets['subnets']]
self.assertIn(self.network['id'], seen_net_ids)
self.assertIn(self.subnet['id'], seen_subnet_ids)
def _create_server(self):
keypair = self.create_keypair()
self.keypairs[keypair['name']] = keypair
networks = [{'uuid': self.network['id']}]
name = data_utils.rand_name('server-smoke')
server = self.create_server(name=name,
networks=networks,
key_name=keypair['name'],
wait_until='ACTIVE')
self.servers.append(server)
return server
def _get_server_key(self, server):
return self.keypairs[server['key_name']]['private_key']
def _check_server_connectivity(self, address_list,
should_connect=True):
private_key = self._get_server_key(self.servers[0])
ip_address = address_list[0]
ssh_source = self.get_remote_client(ip_address,
private_key=private_key)
for remote_ip in address_list:
if should_connect:
msg = "Timed out waiting for "
"%s to become reachable" % remote_ip
else:
msg = "ip address %s is reachable" % remote_ip
try:
self.assertTrue(self._check_remote_connectivity
(ssh_source, remote_ip, should_connect),
msg)
except Exception:
LOG.exception("Unable to access {dest} via ping to "
"fix-ip {src}".format(dest=remote_ip,
src=ip_address))
raise
def _check_network_internal_connectivity(self, network,
should_connect=True):
"""
via ssh check VM internal connectivity:
- ping internal gateway and DHCP port, implying in-tenant connectivity
pinging both, because L3 and DHCP agents might be on different nodes
"""
server = self.servers[0]
# get internal ports' ips:
# get all network ports in the new network
internal_ips = ([p['fixed_ips'][0]['ip_address'] for p in
self._list_ports(tenant_id=server['tenant_id'],
network_id=network['id'])
if p['device_owner'].startswith('compute')])
self._check_server_connectivity(internal_ips,
should_connect)
@decorators.attr(type='smoke')
@test.services('compute', 'network')
@decorators.idempotent_id('b977dce6-6527-4676-9b66-862b22058f0f')
def test_network_basic_ops(self):
"""
For a freshly-booted VM with an IP address ("port") on a given
network:
- the Tempest host can ping the IP address. This implies, but
does not guarantee (see the ssh check that follows), that the
VM has been assigned the correct IP address and has
connectivity to the Tempest host.
- the Tempest host can perform key-based authentication to an
ssh server hosted at the IP address. This check guarantees
that the IP address is associated with the target VM.
- the Tempest host can ssh into the VM via the IP address and
successfully execute the following:
"""
self._setup_network()
self._check_networks()
self._create_server()
self._check_network_internal_connectivity(self.network)

View File

@ -1,6 +0,0 @@
Placeholder for NSX-v plugin specific automated tests
directory:
nsxv/
api/
scenario/
scale/

View File

@ -1 +0,0 @@
Placeholder for nsxv neutron plugin specific API tests.

View File

@ -1,215 +0,0 @@
# Copyright 2015 OpenStack Foundation
# 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 netaddr
from tempest.api.network import base
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions
from tempest import test
CONF = config.CONF
class BaseAdminNetworkTest(base.BaseAdminNetworkTest):
# NOTE(akang): This class inherits from BaseAdminNetworkTest.
# By default client is cls.client, but for provider network,
# the client is admin_client. The test class should pass
# client=self.admin_client, if it wants to create provider
# network/subnet.
@classmethod
def skip_checks(cls):
super(BaseAdminNetworkTest, cls).skip_checks()
if not test.is_extension_enabled('provider', 'network'):
msg = "Network Provider Extension not enabled."
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
super(BaseAdminNetworkTest, cls).resource_setup()
cls.admin_netwk_info = []
cls.admin_port_info = []
@classmethod
def resource_cleanup(cls):
if CONF.service_available.neutron:
for netwk_info in cls.admin_netwk_info:
net_client, network = netwk_info
try:
test_utils.call_and_ignore_notfound_exc(
net_client.delete_network, network['id'])
except Exception:
pass
for port_info in cls.admin_port_info:
port_client, port = port_info
try:
test_utils.call_and_ignore_notfound_exc(
port_client.delete_port, port['id'])
except Exception:
pass
super(BaseAdminNetworkTest, cls).resource_cleanup()
@classmethod
def create_network(cls, network_name=None, client=None,
**kwargs):
net_client = client if client else cls.admin_networks_client
network_name = network_name or data_utils.rand_name('ADM-network-')
post_body = {'name': network_name}
post_body.update(kwargs)
body = net_client.create_network(**post_body)
network = body['network']
cls.admin_netwk_info.append([net_client, network])
return body
@classmethod
def update_network(cls, network_id, client=None, **kwargs):
net_client = client if client else cls.admin_networks_client
return net_client.update_network(network_id, **kwargs)
@classmethod
def delete_network(cls, network_id, client=None):
net_client = client if client else cls.admin_networks_client
return net_client.delete_network(network_id)
@classmethod
def show_network(cls, network_id, client=None, **kwargs):
net_client = client if client else cls.admin_networks_client
return net_client.show_network(network_id, **kwargs)
@classmethod
def list_networks(cls, client=None, **kwargs):
net_client = client if client else cls.admin_networks_client
return net_client.list_networks(**kwargs)
@classmethod
def create_subnet(cls, network, client=None,
gateway='', cidr=None, mask_bits=None,
ip_version=None, cidr_offset=0, **kwargs):
ip_version = (ip_version if ip_version is not None
else cls._ip_version)
net_client = client if client else cls.admin_subnets_client
post_body = get_subnet_create_options(
network['id'], ip_version,
gateway=gateway, cidr=cidr, cidr_offset=cidr_offset,
mask_bits=mask_bits, **kwargs)
return net_client.create_subnet(**post_body)
@classmethod
def update_subnet(cls, subnet_id, client=None, **kwargs):
net_client = client if client else cls.admin_subnets_client
return net_client.update_subnet(subnet_id, **kwargs)
@classmethod
def delete_subnet(cls, subnet_id, client=None):
net_client = client if client else cls.admin_subnets_client
return net_client.delete_subnet(subnet_id)
@classmethod
def show_subnet(cls, subnet_id, client=None, **kwargs):
net_client = client if client else cls.admin_subnets_client
return net_client.show_subnet(subnet_id, **kwargs)
@classmethod
def list_subnets(cls, client=None, **kwargs):
net_client = client if client else cls.admin_subnets_client
return net_client.list_subnets(**kwargs)
@classmethod
def create_port(cls, network_id, port_name=None, client=None, **kwargs):
port_client = client if client else cls.admin_ports_client
port_name = port_name or data_utils.rand_name('ADM-port-')
post_body = {'name': port_name,
'network_id': network_id}
post_body.update(kwargs)
body = port_client.create_port(**post_body)
port = body['port']
cls.admin_port_info.append([port_client, port])
return body
@classmethod
def update_port(cls, port_id, client=None, **kwargs):
port_client = client if client else cls.admin_ports_client
return port_client.update_port(port_id, **kwargs)
@classmethod
def delete_port(cls, port_id, client=None):
port_client = client if client else cls.admin_ports_client
return port_client.delete_port(port_id)
@classmethod
def list_ports(cls, client=None, **kwargs):
port_client = client if client else cls.admin_ports_client
return port_client.list_ports(**kwargs)
# add other create methods, i.e. security-group, port, floatingip
# if needed.
def get_subnet_create_options(network_id, ip_version=4,
gateway='', cidr=None, mask_bits=None,
num_subnet=1, gateway_offset=1, cidr_offset=0,
**kwargs):
"""When cidr_offset>0 it request only one subnet-options:
subnet = get_subnet_create_options('abcdefg', 4, num_subnet=4)[3]
subnet = get_subnet_create_options('abcdefg', 4, cidr_offset=3)
"""
gateway_not_set = (gateway == '')
if ip_version == 4:
cidr = cidr or netaddr.IPNetwork(CONF.network.project_network_cidr)
mask_bits = mask_bits or CONF.network.project_network_mask_bits
elif ip_version == 6:
cidr = (
cidr or netaddr.IPNetwork(CONF.network.project_network_v6_cidr))
mask_bits = mask_bits or CONF.network.project_network_v6_mask_bits
# Find a cidr that is not in use yet and create a subnet with it
subnet_list = []
if cidr_offset > 0:
num_subnet = cidr_offset + 1
for subnet_cidr in cidr.subnet(mask_bits):
if gateway_not_set:
gateway_ip = gateway or (
str(netaddr.IPAddress(subnet_cidr) + gateway_offset))
else:
gateway_ip = gateway
try:
subnet_body = dict(
network_id=network_id,
cidr=str(subnet_cidr),
ip_version=ip_version,
gateway_ip=gateway_ip,
**kwargs)
if num_subnet <= 1:
return subnet_body
subnet_list.append(subnet_body)
if len(subnet_list) >= num_subnet:
if cidr_offset > 0:
# user request the 'cidr_offset'th of cidr
return subnet_list[cidr_offset]
# user request list of cidr
return subnet_list
except exceptions.BadRequest as e:
is_overlapping_cidr = 'overlaps with another subnet' in str(e)
if not is_overlapping_cidr:
raise
else:
message = 'Available CIDR for subnet creation could not be found'
raise exceptions.BuildErrorException(message)
return {}

View File

@ -1,516 +0,0 @@
# 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.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
if not CONF.nsxv.manager_uri:
router_cfg = dict(router_name=router_name)
else:
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(('Starting: {0}').format(cls._testMethodName))
super(BaseTestCase, cls).setUp()
def tearDown(cls):
super(BaseTestCase, cls).tearDown()
cls.LOG.info(('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()

View File

@ -1,101 +0,0 @@
# 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 oslo_log import log as logging
from oslo_utils import uuidutils
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as ex
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
LOG = logging.getLogger(__name__)
class TestHealthMonitors(base.BaseAdminTestCase):
"""Tests the following operations in the Neutron-LBaaS API
using the REST client for Health Monitors with ADMIN role:
create health monitor with missing tenant_id
create health monitor with empty tenant id
create health monitor with another tenant_id
"""
@classmethod
def resource_setup(cls):
super(TestHealthMonitors, cls).resource_setup()
cls.load_balancer = cls._create_load_balancer(
tenant_id=cls.subnet.get('tenant_id'),
vip_subnet_id=cls.subnet.get('id'))
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
cls.pool = cls._create_pool(
protocol='HTTP', lb_algorithm='ROUND_ROBIN',
listener_id=cls.listener.get('id'))
@classmethod
def resource_cleanup(cls):
super(TestHealthMonitors, cls).resource_cleanup()
@decorators.attr(type='smoke')
@decorators.idempotent_id('24cf7da4-b829-4df5-a133-b6cef97ec560')
def test_create_health_monitor_missing_tenant_id_field(self):
"""Test if admin user can
create health monitor with a missing tenant id field.
"""
hm = self._create_health_monitor(type='HTTP', delay=3, max_retries=10,
timeout=5,
pool_id=self.pool.get('id'))
admin_hm = self._show_health_monitor(hm.get('id'))
admin_tenant_id = admin_hm.get('tenant_id')
hm_tenant_id = hm.get('tenant_id')
self.assertEqual(admin_tenant_id, hm_tenant_id)
@decorators.attr(type='negative')
@decorators.idempotent_id('acbff982-15d6-43c5-a015-e72b7df30998')
def test_create_health_monitor_empty_tenant_id_field(self):
"""Test with admin user
creating health monitor with an empty tenant id field should fail.
Kilo: @decorators.skip_because(bug="1638148")
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10,
timeout=5,
pool_id=self.pool.get('id'),
tenant_id="")
@decorators.attr(type='smoke')
@decorators.idempotent_id('a318d351-a72e-46dc-a094-8a751e4fa7aa')
def test_create_health_monitor_for_another_tenant_id_field(self):
"""Test with admin user
create health Monitors for another tenant id.
"""
tenantid = uuidutils.generate_uuid()
hm = self._create_health_monitor(type='HTTP', delay=3, max_retries=10,
timeout=5,
pool_id=self.pool.get('id'),
tenant_id=tenantid)
self.assertEqual(hm.get('tenant_id'), tenantid)
self.assertNotEqual(hm.get('tenant_id'),
self.subnet.get('tenant_id'))

View File

@ -1,687 +0,0 @@
# 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 tempest.lib import exceptions as ex
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
class TestHealthMonitors(base.BaseTestCase):
"""Tests the following operations in the Neutron-LBaaS API
using the REST client for Health Monitors:
list pools
create pool
get pool
update pool
delete pool
"""
@classmethod
def resource_setup(cls):
super(TestHealthMonitors, cls).resource_setup()
cls.load_balancer = cls._create_load_balancer(
tenant_id=cls.subnet.get('tenant_id'),
vip_subnet_id=cls.subnet.get('id'))
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
cls.pool = cls._create_pool(
protocol='HTTP', lb_algorithm='ROUND_ROBIN',
listener_id=cls.listener.get('id'))
cls.create_basic_hm_kwargs = {'type': 'HTTP', 'delay': 3,
'max_retries': 10, 'timeout': 5,
'pool_id': cls.pool.get('id')}
# possible cause is bug#1638601: can not delete health monitor
# temparary solution
def remove_existing_health_monitors(self):
"""remove all existing hm because one pool can only one hm
During testing, because bug#163860 and
one pool can only have one health_monitor,
we delete hm before testing -- acutally not very effective.
hm_list = self._list_health_monitors()
for hm in hm_list:
test_utils.call_and_igonre_not_found_exc(
self._delete_health_monitor,
hm.get('id'))
"""
return None
@decorators.attr(type='smoke')
@decorators.idempotent_id('3c223a4d-3733-4daa-a6e3-69a31f9e7304')
def test_list_health_monitors_empty(self):
hm_list = self._list_health_monitors()
self.assertEmpty(hm_list)
@decorators.attr(type='smoke')
@decorators.idempotent_id('76880edd-b01c-4b80-ba4d-1d10f35aaeb7')
def test_list_health_monitors_one(self):
hm = self._create_health_monitor(**self.create_basic_hm_kwargs)
hm_list = self._list_health_monitors()
self.assertIn(hm, hm_list)
@decorators.attr(type='smoke')
@decorators.idempotent_id('22b984d5-8284-4f7c-90c4-407d0e872ea8')
def test_list_health_monitors_two(self):
hm1 = self._create_health_monitor(**self.create_basic_hm_kwargs)
new_listener = self._create_listener(
loadbalancer_id=self.load_balancer.get('id'),
protocol='HTTP', protocol_port=88)
self.addCleanup(self._delete_listener, new_listener.get('id'))
new_pool = self._create_pool(
protocol='HTTP', lb_algorithm='ROUND_ROBIN',
listener_id=new_listener.get('id'))
self.addCleanup(self._delete_pool, new_pool.get('id'))
hm2 = self._create_health_monitor(
type='HTTP', max_retries=10, delay=3, timeout=5,
pool_id=new_pool.get('id'))
hm_list = self._list_health_monitors()
self.assertEqual(2, len(hm_list))
self.assertIn(hm1, hm_list)
self.assertIn(hm2, hm_list)
@decorators.attr(type='smoke')
@decorators.idempotent_id('ca49b640-259c-49ee-be9c-b425a4bbd2cf')
def test_get_health_monitor(self):
hm = self._create_health_monitor(**self.create_basic_hm_kwargs)
hm_test = self._show_health_monitor(hm.get('id'))
self.assertEqual(hm, hm_test)
@decorators.attr(type='smoke')
@decorators.idempotent_id('80ded4c2-2277-4e19-8280-3519b22a999e')
def test_create_health_monitor(self):
new_hm = self._create_health_monitor(**self.create_basic_hm_kwargs)
hm = self._show_health_monitor(new_hm.get('id'))
self.assertEqual(new_hm, hm)
@decorators.attr(type='smoke')
@decorators.idempotent_id('387f669b-7a02-4ab3-880d-719dd79ff853')
def test_create_health_monitor_missing_attribute(self):
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10,
pool_id=self.pool.get('id'))
@decorators.attr(type=['smoke', 'negative'])
@decorators.idempotent_id('bf2ec88e-91d3-48f5-b9f2-be3dab21445c')
def test_create_health_monitor_missing_required_field_type(self):
"""Test if a non_admin user can
create a health monitor with type missing
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
@decorators.attr(type=['smoke', 'negative'])
@decorators.idempotent_id('85110a81-d905-40f1-92c0-7dafb1617915')
def test_create_health_monitor_missing_required_field_delay(self):
"""Test if a non_admin user can
create a health monitor with delay missing
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
@decorators.attr(type=['smoke', 'negative'])
@decorators.idempotent_id('10ed9396-271a-4edd-948d-93ad44df2713')
def test_create_health_monitor_missing_required_field_timeout(self):
"""Test if a non_admin user can
create a health monitor with timeout missing
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10,
pool_id=self.pool.get('id'))
@decorators.attr(type=['smoke', 'negative'])
@decorators.idempotent_id('69614cb5-9078-4b93-8dfa-45d59ac240f8')
def test_create_health_monitor_missing_required_field_max_retries(self):
"""Test if a non_admin user
can create a health monitor with max_retries missing
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, timeout=5,
pool_id=self.pool.get('id'))
@decorators.attr(type=['smoke', 'negative'])
@decorators.idempotent_id('543d1f68-1b3a-49c8-bc6c-3eb8123b6e9a')
def test_create_health_monitor_missing_required_field_pool_id(self):
"""Test if a non_admin user
can create a health monitor with pool_id missing
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5)
@decorators.attr(type='smoke')
@decorators.idempotent_id('4f8d17d2-3e52-4e34-83c7-4398b328c559')
def test_create_health_monitor_missing_admin_state_up(self):
"""Test if a non_admin user
can create a health monitor with admin_state_up missing
"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
hm_test = self._show_health_monitor(hm.get('id'))
self.assertEqual(hm, hm_test)
self.assertEqual(True, hm_test.get('admin_state_up'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('6e1066d3-f358-446e-a574-5d4ceaf0b51d')
def test_create_health_monitor_missing_http_method(self):
"""Test if a non_admin user
can create a health monitor with http_method missing
"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
hm_test = self._show_health_monitor(hm.get('id'))
self.assertEqual(hm, hm_test)
self.assertEqual('GET', hm_test.get('http_method'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('9b25196f-7476-4ed7-9542-1f22a76b79f8')
def test_create_health_monitor_missing_url_path(self):
"""Test if a non_admin user
can create a health monitor with url_path missing
"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
hm_test = self._show_health_monitor(hm.get('id'))
self.assertEqual(hm, hm_test)
self.assertEqual('/', hm_test.get('url_path'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('c69da922-1c46-4b9b-8b8b-2e700d506a9c')
def test_create_health_monitor_missing_expected_codes(self):
"""Test if a non_admin user
can create a health monitor with expected_codes missing
"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
hm_test = self._show_health_monitor(hm.get('id'))
self.assertEqual(hm, hm_test)
self.assertEqual('200', hm_test.get('expected_codes'))
@decorators.attr(type='negative')
@decorators.idempotent_id('a00cb8e0-cd0b-44d0-85b0-5935a0297e37')
def test_create_health_monitor_invalid_tenant_id(self):
"""Test create health monitor with invalid tenant_id"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
tenant_id='blah',
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('fcd93a6d-1fec-4031-9c18-611f4f3b270e')
def test_create_health_monitor_invalid_type(self):
"""Test create health monitor with invalid type"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='blah', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('3c2829d9-5d51-4bcc-b83e-f28f6e6d0bc3')
def test_create_health_monitor_invalid_delay(self):
"""Test create health monitor with invalid delay"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay='blah', max_retries=10,
timeout=5, pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('7155e366-72a2-47a0-9fcf-25e38a3ef7f7')
def test_create_health_monitor_invalid_max_retries(self):
"""Test create health monitor with invalid max_retries"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries='blah',
timeout=5, pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('fb5d0016-5ea6-4697-8049-e80473e67880')
def test_create_health_monitor_invalid_timeout(self):
"""Test create health monitor with invalid timeout"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10,
timeout='blah', pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('7f3e6e95-3eac-4a46-983a-ba1fd3b0afdf')
def test_create_health_monitor_invalid_pool_id(self):
"""Test create health monitor with invalid pool id"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('f5aacc27-3573-4749-9cb9-3261fcabf1e9')
def test_create_health_monitor_invalid_admin_state_up(self):
"""Test if a non_admin user
can create a health monitor with invalid admin_state_up
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'),
admin_state_up='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('0f9f2488-aefb-44c9-a08b-67b715e63091')
def test_create_health_monitor_invalid_expected_codes(self):
"""Test if a non_admin user
can create a health monitor with invalid expected_codes
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'),
expected_codes='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('0d637b7f-52ea-429f-8f97-584a5a9118aa')
def test_create_health_monitor_invalid_url_path(self):
"""Test if a non_admin user
can create a health monitor with invalid url_path
Kilo: @decorators.skip_because(bug="1641652")
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'), url_path='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('7d4061c4-1fbc-43c3-81b5-2d099a120297')
def test_create_health_monitor_invalid_http_method(self):
"""Test if a non_admin user
can create a health monitor with invalid http_method
Kilo: @decorators.skip_because(bug="1641643")
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'), http_method='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('b655cee7-df0d-4531-bd98-a4918d2e752a')
def test_create_health_monitor_empty_type(self):
"""Test create health monitor with empty type"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('d843c9f4-507e-462f-8f2b-319af23029db')
def test_create_health_monitor_empty_delay(self):
"""Test create health monitor with empty delay"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay='', max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('bb9cb2b0-2684-4f4d-b344-6e7b0c58b019')
def test_create_health_monitor_empty_timeout(self):
"""Test create health monitor with empty timeout"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout='',
pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('3b52441d-5e8a-4d17-b772-bd261d0c2656')
def test_create_health_monitor_empty_max_retries(self):
"""Test create health monitor with empty max_retries"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries='', timeout=5,
pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('397aa201-25c1-4828-8c60-9cee5c4d89ab')
# NSX-v does reject empty pool_id
def test_create_health_monitor_empty_max_pool_id(self):
"""Test create health monitor with empty pool_id"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id='')
@decorators.attr(type='negative')
@decorators.idempotent_id('e806c916-877c-41dc-bacb-aabd9684a540')
# NSX-v does reject empty admin_state_up
def test_create_health_monitor_empty_max_admin_state_up(self):
"""Test create health monitor with empty admin_state_up"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'), admin_state_up='')
@decorators.attr(type='negative')
@decorators.idempotent_id('9c8e8fe8-a3a2-481b-9ac8-eb9ecccd8330')
def test_create_health_monitor_empty_max_http_method(self):
"""Test create health monitor with empty http_method
Kilo: @decorators.skip_because(bug="1639340")
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'), http_method='')
@decorators.attr(type='negative')
@decorators.idempotent_id('9016c846-fc7c-4063-9f01-61fad37c435d')
def test_create_health_monitor_empty_max_url_path(self):
"""Test create health monitor with empty url_path
Kilo: @decorators.skip_because(bug="1639340")
"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'), url_path='')
@decorators.attr(type='negative')
@decorators.idempotent_id('5df60d27-55ec-42a9-96cd-3affa611c8b1')
# NSX-v does reject empty expected_codes
def test_create_health_monitor_empty_expected_codes(self):
"""Test create health monitor with empty expected_codes"""
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10, timeout=5,
pool_id=self.pool.get('id'), expected_codes='')
@decorators.attr(type='negative')
@decorators.idempotent_id('da63bd3a-89d5-40dd-b920-420263cbfd93')
def test_create_health_monitor_invalid_attribute(self):
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries='twenty one',
pool_id=self.pool.get('id'))
@decorators.attr(type='negative')
@decorators.idempotent_id('2005ded4-7d26-4946-8d22-e05bf026bd44')
def test_create_health_monitor_extra_attribute(self):
self.assertRaises(ex.BadRequest, self._create_health_monitor,
type='HTTP', delay=3, max_retries=10,
pool_id=self.pool.get('id'), subnet_id=10)
@decorators.attr(type='smoke')
@decorators.idempotent_id('79b4a4f9-1d2d-4df0-a11b-dd97f973dff2')
def test_update_health_monitor(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
max_retries = 1
new_hm = self._update_health_monitor(
hm.get('id'), max_retries=max_retries)
self.assertEqual(max_retries, new_hm.get('max_retries'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('9496ba1f-e917-4972-883b-432e44f3cf19')
def test_update_health_monitor_missing_admin_state_up(self):
"""Test update health monitor with missing admin state field"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
new_hm = self._update_health_monitor(hm.get('id'))
self.assertEqual(True, new_hm.get('admin_state_up'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('88570f22-cb68-47b4-a020-52b75af818d3')
def test_update_health_monitor_missing_delay(self):
"""Test update health monitor with missing delay field"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
new_hm = self._update_health_monitor(hm.get('id'))
self.assertEqual(hm.get('delay'), new_hm.get('delay'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('45ace70d-28a5-405d-95cd-b2c92ccaa593')
def test_update_health_monitor_missing_timeout(self):
"""Test update health monitor with missing timeout field"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
new_hm = self._update_health_monitor(hm.get('id'))
self.assertEqual(hm.get('timeout'), new_hm.get('timeout'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('269af536-2352-4772-bf35-268df9f4542c')
def test_update_health_monitor_missing_max_retries(self):
"""Test update health monitor with missing max retries field"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
new_hm = self._update_health_monitor(hm.get('id'))
self.assertEqual(hm.get('max_retries'), new_hm.get('max_retries'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('318d972f-9cd1-42ef-9b8b-2f91ba785ac7')
def test_update_health_monitor_missing_http_method(self):
"""Test update health monitor with missing http_method field"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
new_hm = self._update_health_monitor(hm.get('id'))
self.assertEqual(hm.get('http_method'), new_hm.get('http_method'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('4b97ab67-889d-480c-bedc-f06d86479bb5')
def test_update_health_monitor_missing_url_path(self):
"""Test update health monitor with missing url_path field"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
new_hm = self._update_health_monitor(hm.get('id'))
self.assertEqual(hm.get('url_path'), new_hm.get('url_path'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('095cdb91-0937-4ae1-8b46-5edd10f00a1e')
def test_update_health_monitor_missing_expected_codes(self):
"""Test update health monitor with missing expected_codes field"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
new_hm = self._update_health_monitor(hm.get('id'))
self.assertEqual(hm.get('expected_codes'),
new_hm.get('expected_codes'))
@decorators.attr(type='negative')
@decorators.idempotent_id('646d74ed-9afe-4710-a677-c36f85482731')
def test_update_health_monitor_invalid_attribute(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), max_retries='blue')
@decorators.attr(type='negative')
@decorators.idempotent_id('9d717551-82ab-4073-a269-8b05b67d8306')
def test_update_health_monitor_invalid_admin_state_up(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), admin_state_up='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('b865dc8a-695b-4f15-891c-e73b7402ddeb')
def test_update_health_monitor_invalid_delay(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), delay='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('813c8bc1-7ba6-4ae5-96f3-1fdb10ae7be3')
def test_update_health_monitor_invalid_timeout(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), timeout='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('05456473-5014-43ae-97a2-3790e4987526')
def test_update_health_monitor_invalid_max_retries(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), max_retries='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('1e2fb718-de77-46a3-8897-6f5aff6cab5e')
def test_update_health_monitor_invalid_http_method(self):
"""Kilo: @decorators.skip_because(bug="1641643")"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), http_method='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('07d62a55-18b3-4b74-acb2-b73a0b5e4364')
def test_update_health_monitor_invalid_url_path(self):
"""Kilo: @decorators.skip_because(bug="1641652")"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), url_path='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('47c96e10-4863-4635-8bc6-371d460f61bc')
def test_update_health_monitor_invalid_expected_codes(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), expected_codes='blah')
@decorators.attr(type='negative')
@decorators.idempotent_id('8594b3a3-70e8-4dfa-8928-18bc1cc7ab4a')
def test_update_health_monitor_empty_admin_state_up(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), admin_state_up='')
@decorators.attr(type='negative')
@decorators.idempotent_id('1e1b761d-5114-4931-935d-1069d66e2bb1')
def test_update_health_monitor_empty_delay(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), empty_delay='')
@decorators.attr(type='negative')
@decorators.idempotent_id('e6e4a6b7-50b4-465d-be02-44fd5f258bb6')
def test_update_health_monitor_empty_timeout(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), timeout='')
@decorators.attr(type='negative')
@decorators.idempotent_id('65d05adf-a399-4457-bd83-92c43c1eca01')
def test_update_health_monitor_empty_max_retries(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), max_retries='')
@decorators.attr(type='negative')
@decorators.idempotent_id('0c464bb3-ff84-4816-9237-4583e4da9881')
def test_update_health_monitor_empty_empty_http_method(self):
"""Kilo: @decorators.skip_because(bug="1639340")"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), http_method='')
@decorators.attr(type='negative')
@decorators.idempotent_id('3e87c0a8-ef15-457c-a58f-270de8c5c76c')
def test_update_health_monitor_empty_url_path(self):
"""Kilo: @decorators.skip_because(bug="1639340")"""
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), url_path='')
@decorators.attr(type='negative')
@decorators.idempotent_id('d45189e6-db9f-44d1-b5ad-8b7691e781ee')
def test_update_health_monitor_empty_expected_codes(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), expected_codes='')
@decorators.attr(type=['smoke', 'negative'])
@decorators.idempotent_id('cf70e44e-8060-494a-b577-d656726ba3d8')
def test_update_health_monitor_extra_attribute(self):
hm = self._create_health_monitor(type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self.assertRaises(ex.BadRequest,
self._update_health_monitor,
hm.get('id'), protocol='UDP')
@decorators.attr(type=['smoke', 'negative'])
@decorators.idempotent_id('fe44e0d9-957b-44cf-806b-af7819444864')
def test_delete_health_monitor(self):
"""Kilo: @decorators.skip_because(bug="1639340")"""
hm = self._create_health_monitor(cleanup=False, type='HTTP', delay=3,
max_retries=10, timeout=5,
pool_id=self.pool.get('id'))
self._delete_health_monitor(hm.get('id'))
self.assertRaises(ex.NotFound,
self._show_health_monitor,
hm.get('id'))

View File

@ -1,157 +0,0 @@
# 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 import config
from tempest.lib import decorators
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
PROTOCOL_PORT = 80
class TestL7Policies(base.BaseTestCase):
@classmethod
def skip_checks(cls):
super(TestL7Policies, cls).skip_checks()
if '1739510' in CONF.nsxv.bugs_to_resolve:
msg = ("skip lbaas_l7_switching_ops because bug=1739150"
" -- l7 switching is not supported")
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
super(TestL7Policies, cls).resource_setup()
cls.load_balancer = cls._create_load_balancer(
tenant_id=cls.subnet.get('tenant_id'),
vip_subnet_id=cls.subnet.get('id'),
wait=True)
cls.loadbalancer_id = cls.load_balancer.get('id')
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
cls.listener_id = cls.listener.get('id')
cls.pool = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
listener_id=cls.listener_id)
cls.pool_id = cls.pool.get('id')
cls.pool7 = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
loadbalancer_id=cls.loadbalancer_id)
cls.pool7_id = cls.pool7.get('id')
@classmethod
def resource_cleanup(cls):
super(TestL7Policies, cls).resource_cleanup()
def remove_all_policies(self):
policies = self._list_l7policies()
for policy in policies:
self._delete_l7policy(policy.get('id'))
policies = self._list_l7policies()
self.assertEmpty(policies)
def create_to_pool_policy(self, to_position=None, name='policy-pool'):
policy_kwargs = dict(
action='REDIRECT_TO_POOL', name=name,
redirect_pool_id=self.pool7_id,
listener_id=self.listener_id)
if to_position:
policy_kwargs['position'] = to_position
policy = self._create_l7policy(**policy_kwargs)
self.assertEqual(policy.get('name'), name)
self.assertEqual(policy.get('listener_id'), self.listener_id)
self.assertEqual(policy.get('redirect_pool_id'), self.pool7_id)
return policy
def create_to_url_policy(self, redirect_url=None, to_position=None,
name='policy-url'):
policy_kwargs = dict(
action='REDIRECT_TO_URL', name=name,
redirect_url=redirect_url,
redirect_pool_id=self.pool7_id,
listener_id=self.listener_id)
if to_position:
policy_kwargs['position'] = to_position
policy = self._create_l7policy(**policy_kwargs)
self.assertEqual(policy.get('name'), name)
self.assertEqual(policy.get('listener_id'), self.listener_id)
self.assertEqual(policy.get('redirect_pool_id'), self.pool7_id)
return policy
def create_reject_policy(self, to_position=1, name='policy-reject'):
policy_kwargs = dict(
action='REJECT', name=name,
redirect_pool_id=self.pool7_id,
listener_id=self.listener_id)
if to_position:
policy_kwargs['position'] = to_position
policy = self._create_l7policy(**policy_kwargs)
self.assertEqual(policy.get('name'), name)
self.assertEqual(policy.get('listener_id'), self.listener_id)
self.assertEqual(policy.get('redirect_pool_id'), self.pool7_id)
return policy
@decorators.idempotent_id('465c9bea-53de-4a1f-ae00-fa2ee52d250b')
def test_l7policies_crud_ops(self):
policy = self.create_to_pool_policy()
# update
new_policy_name = policy.get('name') + "-update"
policy2 = self._update_l7policy(policy.get('id'),
name=new_policy_name)
self.assertEqual(policy2.get('name'), new_policy_name)
# show
s_policy = self._show_l7policy(policy.get('id'))
self.assertEqual(policy2.get('name'), s_policy.get('name'))
# list
policies = self._list_l7policies()
policy_id_list = [x.get('id') for x in policies]
self.assertIn(policy.get('id'), policy_id_list)
# delete
self._delete_l7policy(policy.get('id'))
policies = self._list_l7policies()
policy_id_list = [x.get('id') for x in policies]
self.assertNotIn(policy.get('id'), policy_id_list)
@decorators.idempotent_id('726588f4-970a-4f32-8253-95766ddaa7b4')
def test_policy_position(self):
self.remove_all_policies()
policy1 = self.create_to_pool_policy()
self.assertEqual(policy1.get('position'), 1)
# create reject_policy at position=1
policy2 = self.create_reject_policy(to_position=1)
self.assertEqual(policy2.get('position'), 1)
policy1A = self._show_l7policy(policy1.get('id'))
self.assertEqual(policy1A.get('position'), 2)
# create to_url_policy at position=2
policy3 = self.create_to_url_policy(to_position=2)
self.assertEqual(policy3.get('position'), 2)
policy2A = self._show_l7policy(policy2.get('id'))
self.assertEqual(policy2A.get('position'), 1)
policy1A = self._show_l7policy(policy1.get('id'))
self.assertEqual(policy1A.get('position'), 3)
# delete policy3, policy1 position==2
self._delete_l7policy(policy3.get('id'))
policy1A = self._show_l7policy(policy1.get('id'))
self.assertEqual(policy1A.get('position'), 2)
policy2A = self._show_l7policy(policy2.get('id'))
self.assertEqual(policy2A.get('position'), 1)
self._delete_l7policy(policy2.get('id'))
policies = self._list_l7policies()
self.assertEqual(len(policies), 1)
self.assertEqual(policy1.get('id'), policies[0].get('id'))
self._delete_l7policy(policy1.get('id'))
policies = self._list_l7policies()
self.assertEmpty(policies)

View File

@ -1,89 +0,0 @@
# 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 import config
from tempest.lib import decorators
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
PROTOCOL_PORT = 80
class TestL7Rules(base.BaseTestCase):
@classmethod
def skip_checks(cls):
super(TestL7Rules, cls).skip_checks()
if '1739510' in CONF.nsxv.bugs_to_resolve:
msg = ("skip lbaas_l7_switching_ops because bug=1739150"
" -- l7 switching is not supported")
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
super(TestL7Rules, cls).resource_setup()
cls.load_balancer = cls._create_load_balancer(
tenant_id=cls.subnet.get('tenant_id'),
vip_subnet_id=cls.subnet.get('id'),
wait=True)
cls.loadbalancer_id = cls.load_balancer.get('id')
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
cls.listener_id = cls.listener.get('id')
cls.pool = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
listener_id=cls.listener_id)
cls.pool_id = cls.pool.get('id')
cls.pool7 = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
loadbalancer_id=cls.loadbalancer_id)
cls.pool7_id = cls.pool7.get('id')
cls.policy7 = cls._create_l7policy(action='REDIRECT_TO_POOL',
name='policy1',
redirect_pool_id=cls.pool7_id,
listener_id=cls.listener_id)
cls.policy7_id = cls.policy7.get('id')
@classmethod
def resource_cleanup(cls):
super(TestL7Rules, cls).resource_cleanup()
@decorators.idempotent_id('27e8a3a1-bd3a-40e5-902d-fe9bc79ebf1f')
def test_l7rules_crud_ops(self):
rule = self._create_l7rule(self.policy7_id,
type='PATH',
compare_type='STARTS_WITH',
value='/api')
self.assertEqual(rule.get('compare_type'), 'STARTS_WITH')
self.assertEqual(rule.get('value'), '/api')
self.assertEqual(rule.get('type'), 'PATH')
# update
new_value = '/v2/api'
rule2 = self._update_l7rule(self.policy7_id, rule.get('id'),
value=new_value)
self.assertEqual(rule2.get('value'), new_value)
# show
s_rule = self._show_l7rule(self.policy7_id, rule.get('id'))
self.assertEqual(s_rule.get('value'), new_value)
# list
rules = self._list_l7rules(self.policy7_id)
rule_id_list = [x.get('id') for x in rules]
self.assertIn(rule.get('id'), rule_id_list)
# delete
self._delete_l7rule(self.policy7_id, rule.get('id'))
rules = self._list_l7rules(self.policy7_id)
rule_id_list = [x.get('id') for x in rules]
self.assertNotIn(rule.get('id'), rule_id_list)

View File

@ -1,110 +0,0 @@
# 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 oslo_log import log as logging
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as ex
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
LOG = logging.getLogger(__name__)
class ListenersTest(base.BaseAdminTestCase):
"""Tests the listener creation operation in admin scope
in the Neutron-LBaaS API using the REST client for Listeners:
"""
@classmethod
def resource_setup(cls):
super(ListenersTest, cls).resource_setup()
cls.create_lb_kwargs = {'tenant_id': cls.subnet['tenant_id'],
'vip_subnet_id': cls.subnet['id']}
cls.load_balancer = cls._create_active_load_balancer(
**cls.create_lb_kwargs)
cls.protocol = 'HTTP'
cls.port = 80
cls.load_balancer_id = cls.load_balancer['id']
cls.create_listener_kwargs = {'loadbalancer_id': cls.load_balancer_id,
'protocol': cls.protocol,
'protocol_port': cls.port}
cls.listener = cls._create_listener(
**cls.create_listener_kwargs)
cls.listener_id = cls.listener['id']
@classmethod
def resource_cleanup(cls):
super(ListenersTest, cls).resource_cleanup()
@decorators.attr(type='negative')
@decorators.idempotent_id('f84bfb35-7f73-4576-b2ca-26193850d2bf')
def test_create_listener_empty_tenant_id(self):
"""Test create listener with an empty tenant id should fail
Kilo: @decorators.skip_because(bug="1638738")
"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8081
create_new_listener_kwargs['tenant_id'] = ""
self.assertRaises(ex.BadRequest,
self._create_listener,
**create_new_listener_kwargs)
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('71ebb8d6-ff2a-410d-a089-b086f195609d')
def test_create_listener_invalid_tenant_id(self):
"""Test create listener with an invalid tenant id"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8082
create_new_listener_kwargs['tenant_id'] = "&^%123"
new_listener = self._create_listener(
**create_new_listener_kwargs)
new_listener_id = new_listener['id']
self.addCleanup(self._delete_listener, new_listener_id)
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id, new_listener_id])
listener = self._show_listener(new_listener_id)
self.assertEqual(new_listener, listener)
@decorators.attr(type='smoke')
@decorators.idempotent_id('55eaeab9-a21e-470c-8861-5af1ded9d64a')
def test_create_listener_missing_tenant_id(self):
"""Test create listener with an missing tenant id.
Verify that creating a listener in admin scope with
a missing tenant_id creates the listener with admin
tenant_id.
"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8083
admin_listener = self._create_listener(
**create_new_listener_kwargs)
admin_listener_id = admin_listener['id']
self.addCleanup(self._delete_listener, admin_listener_id)
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id, admin_listener_id])
listener = self._show_listener(admin_listener_id)
self.assertEqual(admin_listener, listener)
self.assertEqual(admin_listener.get('tenant_id'),
listener.get('tenant_id'))

View File

@ -1,603 +0,0 @@
# 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 oslo_log import log as logging
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
LOG = logging.getLogger(__name__)
class ListenersTest(base.BaseTestCase):
"""Tests the following operations in the Neutron-LBaaS API
using the REST client for Listeners:
list listeners
create listener
get listener
update listener
delete listener
"""
@classmethod
def resource_setup(cls):
super(ListenersTest, cls).resource_setup()
cls.create_lb_kwargs = {'tenant_id': cls.subnet['tenant_id'],
'vip_subnet_id': cls.subnet['id']}
cls.load_balancer = cls._create_active_load_balancer(
**cls.create_lb_kwargs)
cls.protocol = 'HTTP'
cls.port = 80
cls.load_balancer_id = cls.load_balancer['id']
cls.create_listener_kwargs = {'loadbalancer_id': cls.load_balancer_id,
'protocol': cls.protocol,
'protocol_port': cls.port}
cls.listener = cls._create_listener(**cls.create_listener_kwargs)
cls.listener_id = cls.listener['id']
@decorators.attr(type='smoke')
@decorators.idempotent_id('32ae6156-d809-49fc-a45b-55269660651c')
def test_get_listener(self):
"""Test get listener"""
listener = self._show_listener(self.listener_id)
self.assertEqual(self.listener, listener)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('4013ab83-924a-4c53-982e-83388d7ad4d9')
def test_list_listeners(self):
"""Test get listeners with one listener"""
listeners = self._list_listeners()
self.assertEqual(len(listeners), 1)
self.assertIn(self.listener, listeners)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('04f58729-3f93-4616-bb9d-8baaff3542b2')
def test_list_listeners_two(self):
"""Test get listeners with two listeners"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8080
new_listener = self._create_listener(
**create_new_listener_kwargs)
new_listener_id = new_listener['id']
self.addCleanup(self._delete_listener, new_listener_id)
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id, new_listener_id])
listeners = self._list_listeners()
self.assertEqual(len(listeners), 2)
self.assertIn(self.listener, listeners)
self.assertIn(new_listener, listeners)
self.assertNotEqual(self.listener, new_listener)
@decorators.attr(type='smoke')
@decorators.idempotent_id('7989096b-95c2-4b26-86b1-5aec0a2d8386')
def test_create_listener(self):
"""Test create listener"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8081
new_listener = self._create_listener(
**create_new_listener_kwargs)
new_listener_id = new_listener['id']
self.addCleanup(self._delete_listener, new_listener_id)
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id, new_listener_id])
listener = self._show_listener(new_listener_id)
self.assertEqual(new_listener, listener)
self.assertNotEqual(self.listener, new_listener)
@decorators.attr(type='negative')
@decorators.idempotent_id('f7ef7f56-b791-48e8-9bbe-838a3ed94519')
def test_create_listener_missing_field_loadbalancer(self):
"""Test create listener with a missing required field loadbalancer"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
protocol_port=self.port,
protocol=self.protocol)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('c392301c-3d9a-4123-85c3-124e4e3253f6')
def test_create_listener_missing_field_protocol(self):
"""Test create listener with a missing required field protocol"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('12c1c5b5-81a9-4384-811e-7131f65f3b1b')
def test_create_listener_missing_field_protocol_port(self):
"""Test create listener with a missing required field protocol_port"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol=self.protocol)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('214a7acc-eacb-4828-ad27-b7f4774947cf')
def test_create_listener_missing_admin_state_up(self):
"""Test create listener with a missing admin_state_up field"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8083
new_listener = self._create_listener(
**create_new_listener_kwargs)
new_listener_id = new_listener['id']
self.addCleanup(self._delete_listener, new_listener_id)
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id, new_listener_id])
listener = self._show_listener(new_listener_id)
self.assertEqual(new_listener, listener)
self.assertTrue(new_listener['admin_state_up'])
@decorators.attr(type='negative')
@decorators.idempotent_id('86d892dd-9025-4051-a160-8bf1bbb8c64d')
def test_create_listener_invalid_load_balancer_id(self):
"""Test create listener with an invalid load_balancer_id"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id="234*",
protocol_port=self.port,
protocol=self.protocol)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('fb430d68-e68d-4bd0-b43d-f1175ad5a819')
def test_create_listener_invalid_protocol(self):
"""Test create listener with an invalid protocol"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port,
protocol="UDP")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('8e472e7e-a5c2-4dba-ac5c-993f6e6bb229')
def test_create_listener_invalid_protocol_port(self):
"""Test create listener with an invalid protocol_port"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port="9999999",
protocol=self.protocol)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('57fc90f4-95e4-4f3c-8f53-32c7282b956e')
def test_create_listener_invalid_admin_state_up(self):
"""Test update listener with an invalid admin_state_up"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
protocol_port=self.port,
protocol=self.protocol,
admin_state_up="abc123")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('556e1ab9-051c-4e9c-aaaa-f11d15de070b')
def test_create_listener_invalid_tenant_id(self):
"""Test create listener with an invalid tenant id"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port,
protocol=self.protocol,
tenant_id="&^%123")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('59d32fd7-06f6-4466-bdd4-0be23b15970c')
def test_create_listener_invalid_name(self):
"""Test create listener with an invalid name
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port,
protocol=self.protocol,
name='a' * 256)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('95457f70-2c1a-4c14-aa80-db8e803d78a9')
def test_create_listener_invalid_description(self):
"""Test create listener with an invalid description
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port,
protocol=self.protocol,
description='a' * 256)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('177d337f-fe0c-406c-92f1-a25c0103bd0f')
def test_create_listener_invalid_connection_limit(self):
"""Test create listener_ids
with an invalid value for connection _limit field
"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port,
protocol=self.protocol,
connection_limit="&^%123")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('8af7b033-8ff7-4bdb-8949-76809745d8a9')
def test_create_listener_empty_load_balancer_id(self):
"""Test create listener with an empty load_balancer_id"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id="",
protocol_port=self.port,
protocol=self.protocol)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('242af61b-ce50-46e2-926a-6801600dcee4')
def test_create_listener_empty_protocol(self):
"""Test create listener with an empty protocol"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port,
protocol="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('4866af4c-2b91-4bce-af58-af77f19d9119')
def test_create_listener_empty_protocol_port(self):
"""Test create listener with an empty protocol_port"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port="",
protocol=self.protocol)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('09636ad1-a9d5-4c03-92db-ae5d9847993d')
def test_create_listener_empty_admin_state_up(self):
"""Test update listener with an empty admin_state_up"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
protocol_port=self.port,
protocol=self.protocol,
admin_state_up="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('46fc3784-d676-42f7-953b-a23c1d62323d')
def test_create_listener_empty_tenant_id(self):
"""Test create listener with an empty tenant id
Kilo: @decorators.skip_because(bug="1638701")
"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port,
protocol=self.protocol,
tenant_id="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('b4120626-a47e-4b4e-9b64-017e595c4daf')
def test_create_listener_empty_name(self):
"""Test create listener with an empty name"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8081
create_new_listener_kwargs['name'] = ""
new_listener = self._create_listener(
**create_new_listener_kwargs)
new_listener_id = new_listener['id']
self.addCleanup(self._delete_listener, new_listener_id)
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id, new_listener_id])
listener = self._show_listener(new_listener_id)
self.assertEqual(new_listener, listener)
@decorators.attr(type='smoke')
@decorators.idempotent_id('af067d00-d496-4f02-87d6-40624c34d492')
def test_create_listener_empty_description(self):
"""Test create listener with an empty description"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8082
create_new_listener_kwargs['description'] = ""
new_listener = self._create_listener(
**create_new_listener_kwargs)
new_listener_id = new_listener['id']
self.addCleanup(self._delete_listener, new_listener_id)
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id, new_listener_id])
listener = self._show_listener(new_listener_id)
self.assertEqual(new_listener, listener)
@decorators.attr(type='negative')
@decorators.idempotent_id('dd271757-c447-4579-a417-f9d0871b145c')
def test_create_listener_empty_connection_limit(self):
"""Test create listener with an empty connection _limit field"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
loadbalancer_id=self.load_balancer_id,
protocol_port=self.port,
protocol=self.protocol,
connection_limit="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('a1602217-e1b4-4f85-8a5e-d474477333f3')
def test_create_listener_incorrect_attribute(self):
"""Test create a listener withan extra, incorrect field"""
self.assertRaises(exceptions.BadRequest,
self._create_listener,
incorrect_attribute="incorrect_attribute",
**self.create_listener_kwargs)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('27c443ff-3aee-4ae6-8b9a-6abf3d5443bf')
def test_update_listener(self):
"""Test update listener"""
self._update_listener(self.listener_id,
name='new_name')
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
listener = self._show_listener(self.listener_id)
self.assertEqual(listener.get('name'), 'new_name')
@decorators.attr(type='negative')
@decorators.idempotent_id('a709e4da-01ef-4dda-a336-f5e37268b5ea')
def test_update_listener_invalid_tenant_id(self):
"""Test update listener with an invalid tenant id"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
tenant_id="&^%123")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('d88dd3d5-a52f-4306-ba53-e8f6f4e1b399')
def test_update_listener_invalid_admin_state_up(self):
"""Test update a listener with an invalid admin_state_up"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
admin_state_up="$23")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('7c0efb63-90d9-43d0-b959-eb841ef39832')
def test_update_listener_invalid_name(self):
"""Test update a listener with an invalid name
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
name='a' * 256)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('ba9bfad8-dbb0-4cbc-b2e3-52bf72bc1fc5')
def test_update_listener_invalid_description(self):
"""Test update a listener with an invalid description
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
description='a' * 256)
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('dcafa50b-cece-4904-bcc9-a0dd1ac99a7e')
def test_update_listener_invalid_connection_limit(self):
"""Test update a listener with an invalid connection_limit"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
connection_limit="$23")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('27e009c5-3c79-414d-863d-24b731f03123')
def test_update_listener_incorrect_attribute(self):
"""Test update a listener with an extra, incorrect field"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
name="listener_name123",
description="listener_description123",
admin_state_up=True,
connection_limit=10,
vip_subnet_id="123321123")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('e8bdd948-7bea-494b-8a4a-e730b70f2882')
def test_update_listener_missing_name(self):
"""Test update listener with a missing name"""
old_listener = self._show_listener(self.listener_id)
old_name = old_listener['name']
self._update_listener(self.listener_id,
description='updated')
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
listener = self._show_listener(self.listener_id)
self.assertEqual(listener.get('name'), old_name)
@decorators.attr(type='smoke')
@decorators.idempotent_id('7e0194b8-9315-452d-9de5-d48f227b626f')
def test_update_listener_missing_description(self):
"""Test update listener with a missing description"""
old_listener = self._show_listener(self.listener_id)
old_description = old_listener['description']
self._update_listener(self.listener_id,
name='updated_name')
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
listener = self._show_listener(self.listener_id)
self.assertEqual(listener.get('description'), old_description)
@decorators.attr(type='smoke')
@decorators.idempotent_id('285dd3f2-fcb8-4ccb-b9ce-d6207b29a2f8')
def test_update_listener_missing_admin_state_up(self):
"""Test update listener with a missing admin_state_up"""
old_listener = self._show_listener(self.listener_id)
old_admin_state_up = old_listener['admin_state_up']
self._update_listener(self.listener_id,
name='updated_name')
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
listener = self._show_listener(self.listener_id)
self.assertEqual(listener.get('admin_state_up'), old_admin_state_up)
@decorators.attr(type='smoke')
@decorators.idempotent_id('5c510338-0f8a-4d1e-805b-f8458f2e80ee')
def test_update_listener_missing_connection_limit(self):
"""Test update listener with a missing connection_limit"""
old_listener = self._show_listener(self.listener_id)
old_connection_limit = old_listener['connection_limit']
self._update_listener(self.listener_id,
name='updated_name')
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
listener = self._show_listener(self.listener_id)
self.assertEqual(listener.get('connection_limit'),
old_connection_limit)
@decorators.attr(type='negative')
@decorators.idempotent_id('677205d9-9d97-4232-a8e3-d17ebf42ff05')
def test_update_listener_empty_tenant_id(self):
"""Test update listener with an empty tenant id"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
tenant_id="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='negative')
@decorators.idempotent_id('6e9f8fdb-48b0-4c4e-9b29-460576b125ff')
def test_update_listener_empty_admin_state_up(self):
"""Test update a listener with an empty admin_state_up"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
admin_state_up="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('cf619b8d-1916-4144-85c7-e5a34e0d7a2b')
def test_update_listener_empty_name(self):
"""Test update a listener with an empty name"""
self._update_listener(self.listener_id,
name="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
listener = self._show_listener(self.listener_id)
self.assertEqual(listener.get('name'), "")
@decorators.attr(type='smoke')
@decorators.idempotent_id('a9b6f721-c3c1-4d22-a3e5-7e89b58fa3a7')
def test_update_listener_empty_description(self):
"""Test update a listener with an empty description"""
self._update_listener(self.listener_id,
description="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
listener = self._show_listener(self.listener_id)
self.assertEqual(listener.get('description'), "")
@decorators.attr(type='negative')
@decorators.idempotent_id('7ddcf46b-068b-449c-9dde-ea4021dd76bf')
def test_update_listener_empty_connection_limit(self):
"""Test update a listener with an empty connection_limit"""
self.assertRaises(exceptions.BadRequest,
self._update_listener,
listener_id=self.listener_id,
connection_limit="")
self._check_status_tree(load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id])
@decorators.attr(type='smoke')
@decorators.idempotent_id('c891c857-fa89-4775-92d8-5320321b86cd')
def test_delete_listener(self):
"""Test delete listener"""
create_new_listener_kwargs = self.create_listener_kwargs
create_new_listener_kwargs['protocol_port'] = 8083
new_listener = self._create_listener(**create_new_listener_kwargs)
new_listener_id = new_listener['id']
self._check_status_tree(
load_balancer_id=self.load_balancer_id,
listener_ids=[self.listener_id, new_listener_id])
listener = self._show_listener(new_listener_id)
self.assertEqual(new_listener, listener)
self.assertNotEqual(self.listener, new_listener)
self._delete_listener(new_listener_id)
self.assertRaises(exceptions.NotFound,
self._show_listener,
new_listener_id)

View File

@ -1,115 +0,0 @@
# 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 oslo_log import log as logging
import testtools
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as ex
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
LOG = logging.getLogger(__name__)
class LoadBalancersTest(base.BaseAdminTestCase):
"""Tests the following operations in the Neutron-LBaaS API
using the REST client for Load Balancers with default credentials:
list load balancers
create load balancer
get load balancer
update load balancer
delete load balancer
"""
@classmethod
def resource_setup(cls):
super(LoadBalancersTest, cls).resource_setup()
cls.create_lb_kwargs = {'tenant_id': cls.subnet['tenant_id'],
'vip_subnet_id': cls.subnet['id']}
cls.load_balancer = \
cls._create_active_load_balancer(**cls.create_lb_kwargs)
cls.load_balancer_id = cls.load_balancer['id']
@decorators.attr(type='smoke')
@testtools.skipIf('1641902' in CONF.nsxv.bugs_to_resolve,
"skip_because bug=1641902")
@decorators.idempotent_id('0008ae1e-77a2-45d9-b81e-0e3119b5a26d')
def test_create_load_balancer_missing_tenant_id_field_for_admin(self):
"""Test create load balancer with a missing tenant id field.
Verify tenant_id matches when creating loadbalancer vs.
load balancer(admin tenant)
Kilo: @decorators.skip_because(bug="1641902")
"""
load_balancer = self._create_load_balancer(
vip_subnet_id=self.subnet['id'])
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
admin_lb = self._show_load_balancer(
load_balancer.get('id'))
self.assertEqual(load_balancer.get('tenant_id'),
admin_lb.get('tenant_id'))
self._wait_for_load_balancer_status(load_balancer['id'])
@decorators.attr(type='smoke')
@testtools.skipIf('1715126' in CONF.nsxv.bugs_to_resolve,
"skip_because bug=1715126")
@decorators.idempotent_id('37620941-47c1-40b2-84d8-db17ff823ebc')
def test_create_load_balancer_missing_tenant_id_for_other_tenant(self):
"""Test create load balancer with a missing tenant id field.
Verify tenant_id does not match of subnet(non-admin tenant) vs.
load balancer(admin tenant)
Kilo: @decorators.skip_because(bug="1638571")
"""
load_balancer = self._create_load_balancer(
vip_subnet_id=self.subnet['id'])
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
self.assertNotEqual(load_balancer.get('tenant_id'),
self.subnet['tenant_id'])
self._wait_for_load_balancer_status(load_balancer['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('5bf483f5-ae28-47f5-8805-642da0ffcb40')
# Empty tenant_id causing ServerFault
def test_create_load_balancer_empty_tenant_id_field(self):
"""Test create load balancer with empty tenant_id field should fail
Kilo: @decorators.skip_because(bug="1638148")
"""
self.assertRaises(ex.BadRequest,
self._create_load_balancer,
vip_subnet_id=self.subnet['id'],
wait=False,
tenant_id="")
@decorators.attr(type='smoke')
@decorators.idempotent_id('19fc8a44-1280-49f3-be5b-0d30e6e43363')
# NSX-v: 2nd tenant_id at the same subnet not supported; got serverFault
def test_create_load_balancer_for_another_tenant(self):
"""Test create load balancer for other tenant
Kilo: @decorators.skip_because(bug="1638571")
"""
tenant = 'deffb4d7c0584e89a8ec99551565713c'
load_balancer = self._create_load_balancer(
vip_subnet_id=self.subnet['id'],
tenant_id=tenant)
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
self.assertEqual(load_balancer.get('tenant_id'), tenant)
self._wait_for_load_balancer_status(load_balancer['id'])

View File

@ -1,497 +0,0 @@
# 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 netaddr
from oslo_log import log as logging
import testtools
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
LOG = logging.getLogger(__name__)
class LoadBalancersTest(base.BaseTestCase):
"""Tests the following operations in the Neutron-LBaaS API
using the REST client for Load Balancers with default credentials:
list load balancers
create load balancer
get load balancer
update load balancer
delete load balancer
"""
@classmethod
def resource_setup(cls):
super(LoadBalancersTest, cls).resource_setup()
cls.create_lb_kwargs = {'tenant_id': cls.subnet['tenant_id'],
'vip_subnet_id': cls.subnet['id']}
cls.load_balancer = \
cls._create_active_load_balancer(**cls.create_lb_kwargs)
cls.load_balancer_id = cls.load_balancer['id']
@decorators.attr(type='smoke')
@decorators.idempotent_id('b7ea6c09-e077-4a67-859b-b2cd01e3b46b')
def test_list_load_balancers(self):
"""Test list load balancers with one load balancer"""
load_balancers = self._list_load_balancers()
self.assertEqual(len(load_balancers), 1)
self.assertIn(self.load_balancer, load_balancers)
@decorators.attr(type='smoke')
@decorators.idempotent_id('8c2302df-ca94-4950-9826-eb996630a392')
def test_list_load_balancers_two(self):
"""Test list load balancers with two load balancers"""
new_load_balancer = self._create_active_load_balancer(
**self.create_lb_kwargs)
new_load_balancer_id = new_load_balancer['id']
self.addCleanup(self._delete_load_balancer, new_load_balancer_id)
load_balancers = self._list_load_balancers()
self.assertEqual(len(load_balancers), 2)
self.assertIn(self.load_balancer, load_balancers)
self.assertIn(new_load_balancer, load_balancers)
self.assertNotEqual(self.load_balancer, new_load_balancer)
@decorators.attr(type='smoke')
@decorators.idempotent_id('56345a78-1d53-4c05-9d7b-3e5cf34c22aa')
def test_get_load_balancer(self):
"""Test get load balancer"""
load_balancer = self._show_load_balancer(
self.load_balancer_id)
self.assertEqual(self.load_balancer, load_balancer)
@decorators.attr(type='smoke')
@decorators.idempotent_id('5bf80330-d908-4025-9467-bca1727525c8')
def test_create_load_balancer(self):
"""Test create load balancer"""
new_load_balancer = self._create_active_load_balancer(
**self.create_lb_kwargs)
new_load_balancer_id = new_load_balancer['id']
self.addCleanup(self._delete_load_balancer, new_load_balancer_id)
load_balancer = self._show_load_balancer(
new_load_balancer_id)
self.assertEqual(new_load_balancer, load_balancer)
self.assertNotEqual(self.load_balancer, new_load_balancer)
@decorators.attr(type='negative')
@decorators.idempotent_id('66bf5390-154f-4627-af61-2c1c30325d6f')
def test_create_load_balancer_missing_vip_subnet_id_field(self):
"""Test create load balancer
with a missing required vip_subnet_id field
"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
tenant_id=self.subnet['tenant_id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('8e78a7e6-2da3-4f79-9f66-fd1447277883')
def test_create_load_balancer_empty_provider_field(self):
"""Test create load balancer with an empty provider field"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
provider="")
@decorators.attr(type='smoke')
@decorators.idempotent_id('def37122-3f9a-47f5-b7b5-b5c0d5e7e5ca')
def test_create_load_balancer_empty_description_field(self):
"""Test create load balancer with an empty description field"""
load_balancer = self._create_active_load_balancer(
vip_subnet_id=self.subnet['id'], description="")
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
self.assertEqual(load_balancer.get('description'), "")
@decorators.attr(type='negative')
@decorators.idempotent_id('69944c74-3ea1-4c06-8d28-82120721a13e')
def test_create_load_balancer_empty_vip_address_field(self):
"""Test create load balancer with empty vip_address field"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
vip_subnet_id=self.subnet['id'],
vip_address="")
@decorators.attr(type='smoke')
@decorators.idempotent_id('63bbe788-f3a6-444f-89b3-8c740425fc39')
def test_create_load_balancer_missing_admin_state_up(self):
"""Test create load balancer with a missing admin_state_up field"""
load_balancer = self._create_active_load_balancer(
vip_subnet_id=self.subnet['id'])
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
self.assertEqual(load_balancer.get('admin_state_up'), True)
@decorators.attr(type='negative')
@decorators.idempotent_id('499f164a-e926-47a6-808a-14f3c29d04c9')
def test_create_load_balancer_empty_admin_state_up_field(self):
"""Test create load balancer with empty admin_state_up field"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
vip_subnet_id=self.subnet['id'],
admin_state_up="")
@decorators.attr(type='smoke')
@decorators.idempotent_id('e4511356-0e78-457c-a310-8515b2dedad4')
def test_create_load_balancer_missing_name(self):
"""Test create load balancer with a missing name field"""
load_balancer = self._create_load_balancer(
vip_subnet_id=self.subnet['id'])
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
self.assertEqual(load_balancer.get('name'), '')
self._wait_for_load_balancer_status(load_balancer['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('6bd4a92c-7498-4b92-aeae-bce0b74608e3')
def test_create_load_balancer_empty_name(self):
"""Test create load balancer with an empty name field"""
load_balancer = self._create_load_balancer(
vip_subnet_id=self.subnet['id'], name="")
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
self.assertEqual(load_balancer.get('name'), "")
self._wait_for_load_balancer_status(load_balancer['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('e605b1ea-5179-4035-8100-c24d0164a5a5')
def test_create_load_balancer_missing_description(self):
"""Test create load balancer with a missing description field"""
load_balancer = self._create_load_balancer(
vip_subnet_id=self.subnet['id'])
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
self.assertEqual(load_balancer.get('description'), '')
self._wait_for_load_balancer_status(load_balancer['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('9f718024-340b-405f-817f-311392353c32')
def test_create_load_balancer_missing_vip_address(self):
"""Test create load balancer
with a missing vip_address field,checks for
ipversion and actual ip address
"""
load_balancer = self._create_active_load_balancer(
vip_subnet_id=self.subnet['id'])
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
load_balancer_ip_initial = load_balancer['vip_address']
ip = netaddr.IPAddress(load_balancer_ip_initial)
self.assertEqual(ip.version, 4)
load_balancer = self._show_load_balancer(
load_balancer['id'])
load_balancer_final = load_balancer['vip_address']
self.assertEqual(load_balancer_ip_initial, load_balancer_final)
@decorators.attr(type='smoke')
@decorators.idempotent_id('f599ccbd-73e8-4e27-96a5-d9e0e3419a9f')
def test_create_load_balancer_missing_provider_field(self):
"""Test create load balancer with a missing provider field"""
load_balancer = self._create_active_load_balancer(
vip_subnet_id=self.subnet['id'])
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
load_balancer_initial = load_balancer['provider']
load_balancer = self._show_load_balancer(
load_balancer['id'])
load_balancer_final = load_balancer['provider']
self.assertEqual(load_balancer_initial, load_balancer_final)
@decorators.attr(type='negative')
@decorators.idempotent_id('377166eb-f581-4383-bc2e-54fdeed73e42')
def test_create_load_balancer_invalid_vip_subnet_id(self):
"""Test create load balancer with an invalid vip subnet id"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
vip_subnet_id="abc123")
@decorators.attr(type='negative')
@decorators.idempotent_id('512bec06-5259-4e93-b482-7ec3346c794a')
def test_create_load_balancer_empty_vip_subnet_id(self):
"""Test create load balancer with an empty vip subnet id"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
vip_subnet_id="")
@decorators.attr(type='negative')
@decorators.idempotent_id('02bd6d0e-820e-46fb-89cb-1d335e7aaa02')
def test_create_load_balancer_invalid_tenant_id(self):
"""Test create load balancer with an invalid tenant id"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
tenant_id="&^%123")
@decorators.attr(type='negative')
@decorators.idempotent_id('b8c56e4a-9644-4119-8fc9-130841caf662')
def test_create_load_balancer_invalid_name(self):
"""Test create load balancer with an invalid name
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
tenant_id=self.subnet['tenant_id'],
vip_subnet_id=self.subnet['id'],
name='n' * 256)
@decorators.attr(type='negative')
@decorators.idempotent_id('d638ae60-7de5-45da-a7d9-53eca4998980')
def test_create_load_balancer_invalid_description(self):
"""Test create load balancer with an invalid description
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
tenant_id=self.subnet['tenant_id'],
vip_subnet_id=self.subnet['id'],
description='d' * 256)
@decorators.attr(type='negative')
@decorators.idempotent_id('56768aa6-b26e-48aa-8118-956c62930d79')
def test_create_load_balancer_incorrect_attribute(self):
"""Test create a load balancer with an extra, incorrect field"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
tenant_id=self.subnet['tenant_id'],
vip_subnet_id=self.subnet['id'],
protocol_port=80)
@decorators.attr(type='smoke')
@decorators.idempotent_id('a130e70f-9d76-4bff-89de-3e564952b244')
def test_create_load_balancer_missing_tenant_id_field(self):
"""Test create load balancer with a missing tenant id field"""
load_balancer = self._create_load_balancer(
vip_subnet_id=self.subnet['id'])
self.addCleanup(self._delete_load_balancer, load_balancer['id'])
self.assertEqual(load_balancer.get('tenant_id'),
self.subnet['tenant_id'])
self._wait_for_load_balancer_status(load_balancer['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('25261cca-0c38-4dc8-bb40-f7692035740f')
def test_create_load_balancer_empty_tenant_id_field(self):
"""Test create load balancer with empty tenant_id field"""
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
vip_subnet_id=self.subnet['id'],
wait=False,
tenant_id="")
@decorators.attr(type='negative')
@decorators.idempotent_id('10de328d-c754-484b-841f-313307f92935')
def test_create_load_balancer_other_tenant_id_field(self):
"""Test create load balancer for other tenant"""
tenant = 'deffb4d7c0584e89a8ec99551565713c'
self.assertRaises(exceptions.BadRequest,
self._create_load_balancer,
wait=False,
vip_subnet_id=self.subnet['id'],
tenant_id=tenant)
@decorators.attr(type='negative')
@testtools.skipIf('1703396' in CONF.nsxv.bugs_to_resolve,
"skip_because bug=1703396")
@decorators.idempotent_id('9963cbf5-97d0-4ab9-96e5-6cbd65c98714')
def test_create_load_balancer_invalid_flavor_field(self):
"""Test create load balancer with an invalid flavor field"""
self.assertRaises(exceptions.NotFound,
self._create_load_balancer,
vip_subnet_id=self.subnet['id'],
flavor_id="NO_SUCH_FLAVOR")
@decorators.attr(type='negative')
@testtools.skipIf('1703396' in CONF.nsxv.bugs_to_resolve,
"skip_because bug=1703396")
@decorators.idempotent_id('f7319e32-0fad-450e-8f53-7567f56e8223')
def test_create_load_balancer_provider_flavor_conflict(self):
"""Test create load balancer with both a provider and a flavor"""
self.assertRaises(exceptions.Conflict,
self._create_load_balancer,
vip_subnet_id=self.subnet['id'],
flavor_id="NO_SUCH_FLAVOR",
provider="NO_SUCH_PROVIDER")
@decorators.attr(type='smoke')
@decorators.idempotent_id('1d92d98f-550f-4f05-a246-cdf4525459a2')
def test_update_load_balancer(self):
"""Test update load balancer"""
self._update_load_balancer(self.load_balancer_id,
name='new_name')
load_balancer = self._show_load_balancer(
self.load_balancer_id)
self.assertEqual(load_balancer.get('name'), 'new_name')
@decorators.attr(type='smoke')
@decorators.idempotent_id('474ca200-8dea-4d20-8468-abc0169a445b')
def test_update_load_balancer_empty_name(self):
"""Test update load balancer with empty name"""
self._update_load_balancer(self.load_balancer_id,
name="")
load_balancer = self._show_load_balancer(
self.load_balancer_id)
self.assertEqual(load_balancer.get('name'), "")
@decorators.attr(type='negative')
@decorators.idempotent_id('551be885-215d-4941-8870-651cbc871162')
def test_update_load_balancer_invalid_name(self):
"""Test update load balancer with invalid name
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(exceptions.BadRequest,
self._update_load_balancer,
load_balancer_id=self.load_balancer_id,
wait=False,
name='a' * 256)
@decorators.attr(type='smoke')
@decorators.idempotent_id('62eef0ba-3859-4c8f-9e6a-8d6918754597')
def test_update_load_balancer_missing_name(self):
"""Test update load balancer with missing name"""
loadbalancer = self._show_load_balancer(
self.load_balancer_id)
load_balancer_initial = loadbalancer['name']
self._update_load_balancer(self.load_balancer_id)
load_balancer = self._show_load_balancer(
self.load_balancer_id)
load_balancer_new = load_balancer['name']
self.assertEqual(load_balancer_initial, load_balancer_new)
@decorators.attr(type='negative')
@decorators.idempotent_id('ab3550c6-8b21-463c-bc5d-e79cbae3432f')
def test_update_load_balancer_invalid_description(self):
"""Test update load balancer with invalid description
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(exceptions.BadRequest,
self._update_load_balancer,
load_balancer_id=self.load_balancer_id,
wait=False,
description='a' * 256)
@decorators.attr(type='smoke')
@decorators.idempotent_id('157ebdbf-4ad2-495d-b880-c1b1a8edc46d')
def test_update_load_balancer_empty_description(self):
"""Test update load balancer with empty description"""
self._update_load_balancer(self.load_balancer_id,
description="")
load_balancer = self._show_load_balancer(
self.load_balancer_id)
self.assertEqual(load_balancer.get('description'), "")
@decorators.attr(type='smoke')
@decorators.idempotent_id('d13fa2f5-e8df-4d53-86a8-68583941200c')
def test_update_load_balancer_missing_description(self):
"""Test update load balancer with missing description"""
loadbalancer = self._show_load_balancer(
self.load_balancer_id)
load_balancer_initial = loadbalancer['description']
self._update_load_balancer(self.load_balancer_id)
load_balancer = self._show_load_balancer(
self.load_balancer_id)
load_balancer_new = load_balancer['description']
self.assertEqual(load_balancer_initial, load_balancer_new)
@decorators.attr(type='negative')
@decorators.idempotent_id('96e46a1a-62e7-47f1-98c5-9983f89e622f')
def test_update_load_balancer_invalid_admin_state_up_field(self):
"""Test update load balancer with an invalid admin_state_up"""
self.assertRaises(exceptions.BadRequest,
self._update_load_balancer,
load_balancer_id=self.load_balancer_id,
wait=False,
admin_state_up="a&^%$jbc123")
@decorators.attr(type='negative')
@decorators.idempotent_id('48f1e227-8b15-4389-a050-7ce76f4b4d46')
def test_update_load_balancer_empty_admin_state_up_field(self):
"""Test update load balancer with an empty admin_state_up"""
self.assertRaises(exceptions.BadRequest,
self._update_load_balancer,
load_balancer_id=self.load_balancer_id,
wait=False,
admin_state_up="")
@decorators.attr(type='smoke')
@decorators.idempotent_id('a9182e53-ddaa-4f41-af54-585d983279ba')
def test_update_load_balancer_missing_admin_state_up(self):
"""Test update load balancer with missing admin state field"""
loadbalancer = self._show_load_balancer(
self.load_balancer_id)
load_balancer_initial = loadbalancer['admin_state_up']
self._update_load_balancer(self.load_balancer_id)
self.assertEqual(load_balancer_initial, True)
@decorators.attr(type='negative')
@decorators.idempotent_id('bfbe9339-d083-4a88-b6d6-015522809c3a')
def test_update_load_balancer_incorrect_attribute(self):
"""Test update a load balancer with an extra, invalid attribute"""
self.assertRaises(exceptions.BadRequest,
self._update_load_balancer,
load_balancer_id=self.load_balancer_id,
wait=False,
name="lb_name",
description="lb_name_description",
admin_state_up=True,
port=80)
@decorators.attr(type='smoke')
@decorators.idempotent_id('d2258984-6e9a-41d6-bffa-0543c8b1f2b0')
def test_get_load_balancer_status_tree(self):
"""Test get load balancer status tree"""
statuses = self._show_load_balancer_status_tree(
self.load_balancer_id)
load_balancer = statuses['loadbalancer']
self.assertEqual("ONLINE", load_balancer['operating_status'])
self.assertEqual("ACTIVE", load_balancer['provisioning_status'])
self.assertEmpty(load_balancer['listeners'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('a23677a9-b770-4894-8be9-cd66590c228b')
def test_get_load_balancer_stats(self):
"""Test get load balancer stats"""
stats = self._show_load_balancer_stats(
self.load_balancer_id)
self.assertEqual(0, stats['bytes_in'])
self.assertEqual(0, stats['bytes_out'])
self.assertEqual(0, stats['total_connections'])
self.assertEqual(0, stats['active_connections'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('f289f8df-a867-45cd-bee3-7ff08f5e96e0')
def test_delete_load_balancer(self):
"""Test delete load balancer"""
new_load_balancer = self._create_active_load_balancer(
**self.create_lb_kwargs)
new_load_balancer_id = new_load_balancer['id']
load_balancer = self._show_load_balancer(
new_load_balancer_id)
self.assertEqual(new_load_balancer, load_balancer)
self.assertNotEqual(self.load_balancer, new_load_balancer)
self._delete_load_balancer(new_load_balancer_id)
self.assertRaises(exceptions.NotFound,
self._show_load_balancer,
new_load_balancer_id)

View File

@ -1,84 +0,0 @@
# 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 oslo_log import log as logging
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as ex
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
LOG = logging.getLogger(__name__)
class MemberTest(base.BaseAdminTestCase):
"""Test the member creation operation in admin scope in Neutron-LBaaS API
using the REST client for members:
"""
@classmethod
def resource_setup(cls):
super(MemberTest, cls).resource_setup()
# core network setup is moved to base class
cls.load_balancer = cls._create_active_load_balancer(
tenant_id=cls.tenant_id,
vip_subnet_id=cls.subnet.get('id'))
cls.load_balancer_id = cls.load_balancer.get("id")
cls._wait_for_load_balancer_status(cls.load_balancer_id)
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
cls.listener_id = cls.listener.get('id')
cls.pool = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
listener_id=cls.listener_id)
cls.pool_id = cls.pool.get('id')
@classmethod
def resource_cleanup(cls):
super(MemberTest, cls).resource_cleanup()
@decorators.attr(type='smoke')
@decorators.idempotent_id('03eeec24-78d8-4c2f-8d6c-4a78817f352e')
def test_create_member_invalid_tenant_id(self):
"""Test create member with invalid tenant_id"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
# avoid port=80 to avoid duplicate port during failed testings
member_opts['protocol_port'] = 84
member_opts['subnet_id'] = self.subnet_id
member_opts['tenant_id'] = "$232!$pw"
member = self._create_member(self.pool_id, **member_opts)
self.addCleanup(self._delete_member, self.pool_id, member['id'])
self.assertEqual(member['subnet_id'], self.subnet_id)
self.assertEqual(member['tenant_id'], "$232!$pw")
@decorators.attr(type='negative')
@decorators.idempotent_id('01c9ea0c-bdfe-4108-95d1-69ecdc0a1f26')
def test_create_member_empty_tenant_id(self):
"""Test create member with an empty tenant_id should fail
Kilo: @decorators.skip_because(bug="1638148")
"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
member_opts['tenant_id'] = ""
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)

View File

@ -1,479 +0,0 @@
# 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 oslo_log import log as logging
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as ex
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
LOG = logging.getLogger(__name__)
class MemberTest(base.BaseTestCase):
"""Test the following operations in Neutron-LBaaS API
using the REST client for members:
list members of a pool
create a member of a Pool
update a pool member
delete a member
"""
@classmethod
def resource_setup(cls):
super(MemberTest, cls).resource_setup()
# core network setup is moved to base class
cls.load_balancer = cls._create_active_load_balancer(
tenant_id=cls.tenant_id,
vip_subnet_id=cls.subnet.get('id'))
cls.load_balancer_id = cls.load_balancer.get("id")
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
cls.listener_id = cls.listener.get('id')
cls.pool = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
listener_id=cls.listener_id)
cls.pool_id = cls.pool.get('id')
@classmethod
def resource_cleanup(cls):
super(MemberTest, cls).resource_cleanup()
@decorators.attr(type='smoke')
@decorators.idempotent_id('6dcdc53c-52cf-4b6e-aeec-d13df68ed001')
def test_list_empty_members(self):
"""Test that pool members are empty."""
members = self._list_members(self.pool_id)
self.assertEmpty(members,
msg='Initial pool was supposed to be empty')
@decorators.attr(type='smoke')
@decorators.idempotent_id('346e49ce-0665-4995-a03a-b007052d3619')
def test_list_3_members(self):
"""Test that we can list members. """
member_ips_exp = set([u"127.0.0.0", u"127.0.0.1", u"127.0.0.2"])
for ip in member_ips_exp:
member_opts = self.build_member_opts()
member_opts["address"] = ip
member = self._create_member(self.pool_id, **member_opts)
self.addCleanup(self._delete_member, self.pool_id, member['id'])
members = self._list_members(self.pool_id)
self.assertEqual(3, len(members))
for member in members:
self.assertEqual(member["tenant_id"], self.tenant_id)
self.assertEqual(member["protocol_port"], 80)
self.assertEqual(member["subnet_id"], self.subnet_id)
found_member_ips = set([m["address"] for m in members])
self.assertEqual(found_member_ips, member_ips_exp)
@decorators.attr(type='smoke')
@decorators.idempotent_id('3121bbdc-81e4-40e3-bf66-3ceefd72a0f5')
def test_add_member(self):
"""Test that we can add a single member."""
expect_empty_members = self._list_members(self.pool_id)
self.assertEmpty(expect_empty_members)
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id, **member_opts)
member_id = member.get("id")
self.addCleanup(self._delete_member, self.pool_id, member_id)
self.assertEqual(member_opts["address"], member["address"])
self.assertEqual(self.tenant_id, member["tenant_id"])
self.assertEqual(80, member["protocol_port"])
self.assertEqual(self.subnet_id, member["subnet_id"])
# Should have default values for admin_state_up and weight
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(1, member["weight"])
@decorators.attr(type='smoke')
@decorators.idempotent_id('fc513a45-4c24-42ea-8807-a9b86a81ee56')
def test_get_member(self):
"""Test that we can fetch a member by id."""
member_opts = self.build_member_opts()
member_id = self._create_member(self.pool_id,
**member_opts)["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
member = self._show_member(self.pool_id, member_id)
self.assertEqual(member_id, member["id"])
self.assertEqual(member_opts["address"], member["address"])
self.assertEqual(member_opts["tenant_id"], member["tenant_id"])
self.assertEqual(member_opts["protocol_port"], member["protocol_port"])
self.assertEqual(member_opts["subnet_id"], member["subnet_id"])
@decorators.attr(type='smoke')
@decorators.idempotent_id('2cead036-5a63-43a4-9d9d-03c9b744c101')
def test_create_member_missing_required_field_tenant_id(self):
"""Test if a non_admin user can create a member_opts
with tenant_id missing
"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
member = self._create_member(self.pool_id, **member_opts)
self.addCleanup(self._delete_member, self.pool_id, member['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('d7ed0870-a065-4fbd-8d95-0ea4d12063c2')
def test_create_member_missing_required_field_address(self):
"""Test create a member with missing field address"""
member_opts = {}
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('8d2b9a53-aac7-4fb9-b068-47647289aa21')
def test_create_member_missing_required_field_protocol_port(self):
"""Test create a member with missing field protocol_port"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['subnet_id'] = self.subnet_id
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('9710cd4c-aac0-4b71-b295-82a88c67b0b8')
def test_create_member_missing_required_field_subnet_id(self):
"""Test create a member with missing field subnet_id """
member_opts = {}
member_opts['protocol_port'] = 80
member_opts['address'] = "127.0.0.1"
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('a6814c49-758d-490a-9557-ef03f0d78c44')
def test_raises_BadRequest_when_missing_attrs_during_member_create(self):
"""Test failure on missing attributes on member create."""
member_opts = {}
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('840bfa84-1d16-4149-a863-6f7afec1682f')
def test_create_member_invalid_tenant_id(self):
"""Test create member with invalid tenant_id"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
member_opts['tenant_id'] = "$232!$pw"
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('a99dbd0a-5f8c-4c96-8900-1a7d297d913b')
def test_create_member_invalid_address(self):
"""Test create member with invalid address"""
member_opts = {}
member_opts['address'] = "127$%<ki"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('736b0771-b98c-4045-97e0-a44e4e18c22e')
def test_create_member_invalid_protocol_port(self):
"""Test create member with invalid protocol_port"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 8090000
member_opts['subnet_id'] = self.subnet_id
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('2cc67f5a-3f66-427e-90b8-59a3da5c1d21')
def test_create_member_invalid_subnet_id(self):
"""Test create member with invalid subnet_id"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = "45k%^"
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('3403c6f5-5a30-4115-ac3a-8a22855fd614')
def test_create_member_invalid_admin_state_up(self):
"""Test create member with invalid admin_state_up"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
member_opts['admin_state_up'] = "$232!$pw"
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('b12216ec-3442-4239-ba2c-dd17640449d1')
def test_create_member_invalid_weight(self):
"""Test create member with invalid weight"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
member_opts['weight'] = "$232!$pw"
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('88eb464b-4de6-4ed7-a1e8-bc61581a5c6e')
def test_create_member_empty_tenant_id(self):
"""Test create member with an empty tenant_id"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
member_opts['tenant_id'] = ""
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('238cd859-2b60-4e42-b356-c6b38768c3e4')
def test_create_member_empty_address(self):
"""Test create member with an empty address"""
member_opts = {}
member_opts['address'] = ""
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('834905ac-5c95-4dfc-900c-1676b6c28247')
def test_create_member_empty_protocol_port(self):
"""Test create member with an empty protocol_port"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = ""
member_opts['subnet_id'] = self.subnet_id
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('a0f2148e-160e-4b12-8e30-567a0448d179')
def test_create_member_empty_subnet_id(self):
"""Test create member with empty subnet_id"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = ""
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('63cd5897-b82c-4508-8be7-3b7ccab21798')
def test_create_member_empty_admin_state_up(self):
"""Test create member with an empty admin_state_up"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
member_opts['admin_state_up'] = ""
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('55f16682-74a2-4df7-a6b3-2da3623f4a41')
def test_create_member_empty_weight(self):
"""Test create member with an empty weight"""
member_opts = {}
member_opts['address'] = "127.0.0.1"
member_opts['protocol_port'] = 80
member_opts['subnet_id'] = self.subnet_id
member_opts['weight'] = ""
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='smoke')
@decorators.idempotent_id('c99f6146-2c85-4a32-a850-942d6836c175')
def test_delete_member(self):
"""Test that we can delete a member by id."""
member_opts = self.build_member_opts()
member_id = self._create_member(self.pool_id,
**member_opts)["id"]
members = self._list_members(self.pool_id)
self.assertEqual(1, len(members))
self._delete_member(self.pool_id, member_id)
members = self._list_members(self.pool_id)
self.assertEmpty(members)
@decorators.attr(type='smoke')
@decorators.idempotent_id('7d51aa2d-9582-4160-b07b-bf3c3b3e335e')
def test_update_member(self):
"""Test that we can update a member."""
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id,
**member_opts)
member_id = member["id"]
self.addCleanup(self._delete_member, self.pool_id, member['id'])
# Make sure the defaults are correct
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(1, member["weight"])
# Lets overwrite the defaults
member_opts = {"weight": 10, "admin_state_up": False}
member = self._update_member(self.pool_id, member_id,
**member_opts)
# And make sure they stick
self.assertFalse(member["admin_state_up"])
self.assertEqual(10, member["weight"])
@decorators.attr(type='smoke')
@decorators.idempotent_id('101555d6-c472-45e4-b302-b2916ab6fad5')
def test_update_member_missing_admin_state_up(self):
"""Test that we can update a member with missing admin_state_up."""
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id,
**member_opts)
member_id = member["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(1, member["weight"])
member_opts = {"weight": 10}
member = self._update_member(self.pool_id, member_id,
**member_opts)
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(10, member["weight"])
@decorators.attr(type='smoke')
@decorators.idempotent_id('815c037b-7e3b-474d-a4f6-eec26b44d677')
def test_update_member_missing_weight(self):
"""Test that we can update a member with missing weight."""
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id,
**member_opts)
member_id = member["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(1, member["weight"])
member_opts = {"admin_state_up": False}
member = self._update_member(self.pool_id, member_id,
**member_opts)
self.assertFalse(member["admin_state_up"])
self.assertEqual(1, member["weight"])
@decorators.attr(type='negative')
@decorators.idempotent_id('3ab3bb11-e287-4693-8ea0-5cfbb4cc2c85')
def test_update_member_invalid_admin_state_up(self):
"""Test that we can update a member with empty admin_state_up."""
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id,
**member_opts)
member_id = member["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(1, member["weight"])
member_opts = {"weight": 10, "admin_state_up": "%^67"}
self.assertRaises(ex.BadRequest, self._update_member,
self.pool_id, member_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('71979c3b-08d6-449b-8de2-1eefc9d0db0e')
def test_update_member_invalid_weight(self):
"""Test that we can update a member with an empty weight."""
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id,
**member_opts)
member_id = member["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(1, member["weight"])
member_opts = {"admin_state_up": False, "weight": "*^$df"}
self.assertRaises(ex.BadRequest, self._update_member,
self.pool_id, member_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('e1470212-0a36-4d8c-8e30-1f69a8d31ae1')
def test_update_member_empty_admin_state_up(self):
"""Test that we can update a member with empty admin_state_up."""
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id,
**member_opts)
member_id = member["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(1, member["weight"])
member_opts = {"weight": 10, "admin_state_up": ""}
self.assertRaises(ex.BadRequest, self._update_member,
self.pool_id, member_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('cd1e276c-b220-439d-a9dc-823a10d11b6a')
def test_update_member_empty_weight(self):
"""Test that we can update a member with an empty weight."""
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id,
**member_opts)
member_id = member["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
self.assertEqual(True, member["admin_state_up"])
self.assertEqual(1, member["weight"])
member_opts = {"admin_state_up": False, "weight": ""}
self.assertRaises(ex.BadRequest, self._update_member,
self.pool_id, member_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('25779006-1e2c-4155-9126-49f45e7646a3')
def test_raises_immutable_when_updating_immutable_attrs_on_member(self):
"""Test failure on immutable attribute on member create."""
member_opts = self.build_member_opts()
member_id = self._create_member(self.pool_id,
**member_opts)["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
member_opts = {"address": "127.0.0.69"}
# The following code actually raises a 400 instead of a 422 as expected
# Will need to consult with blogan as to what to fix
self.assertRaises(ex.BadRequest, self._update_member,
self.pool_id, member_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('a332ecda-bb18-4cc2-b847-c09a72d90fd1')
def test_raises_exception_on_invalid_attr_on_create(self):
"""Test failure on invalid attribute on member create."""
member_opts = self.build_member_opts()
member_opts["invalid_op"] = "should_break_request"
self.assertRaises(ex.BadRequest, self._create_member,
self.pool_id, **member_opts)
@decorators.attr(type='negative')
@decorators.idempotent_id('bc4c3eb5-14d5-43dd-93cb-603801fa6f32')
def test_raises_exception_on_invalid_attr_on_update(self):
"""Test failure on invalid attribute on member update."""
member_opts = self.build_member_opts()
member = self._create_member(self.pool_id, **member_opts)
member_id = member["id"]
self.addCleanup(self._delete_member, self.pool_id, member_id)
member_opts["invalid_op"] = "watch_this_break"
self.assertRaises(ex.BadRequest, self._update_member,
self.pool_id, member_id, **member_opts)
@classmethod
def build_member_opts(cls, **kw):
"""Build out default member dictionary """
opts = {"address": kw.get("address", "127.0.0.1"),
"tenant_id": kw.get("tenant_id", cls.tenant_id),
"protocol_port": kw.get("protocol_port", 80),
"subnet_id": kw.get("subnet_id", cls.subnet_id)}
return opts

View File

@ -1,114 +0,0 @@
# 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 tempest.lib import exceptions as ex
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
PROTOCOL_PORT = 80
class TestPools(base.BaseAdminTestCase):
"""Tests the following operations in the Neutron-LBaaS API
using the REST client for Pools:
list pools
create pool
get pool
update pool
delete pool
"""
@classmethod
def resource_setup(cls):
super(TestPools, cls).resource_setup()
cls.load_balancer = cls._create_load_balancer(
tenant_id=cls.subnet.get('tenant_id'),
vip_subnet_id=cls.subnet.get('id'))
def increment_protocol_port(self):
global PROTOCOL_PORT
PROTOCOL_PORT += 1
def _prepare_and_create_pool(self, protocol=None, lb_algorithm=None,
listener_id=None, **kwargs):
self.increment_protocol_port()
if not protocol:
protocol = 'HTTP'
if not lb_algorithm:
lb_algorithm = 'ROUND_ROBIN'
if not listener_id:
listener = self._create_listener(
loadbalancer_id=self.load_balancer.get('id'),
protocol='HTTP', protocol_port=PROTOCOL_PORT, **kwargs)
listener_id = listener.get('id')
response = self._create_pool(protocol=protocol,
lb_algorithm=lb_algorithm,
listener_id=listener_id,
**kwargs)
self.addCleanup(self._delete_pool, response['id'])
return response
@decorators.attr(type='negative')
@decorators.idempotent_id('71b9d3e1-3f13-4c84-a905-054c9cd3d4aa')
def test_create_pool_using_empty_tenant_field(self):
"""Test create pool with empty tenant field should fail
Kilo: @decorators.skip_because(bug="1638148")
"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
tenant_id="",
lb_algorithm='ROUND_ROBIN')
@decorators.attr(type='smoke')
@decorators.idempotent_id('f782967d-8dca-4d7b-b625-bfd811379b42')
def test_create_pool_missing_tenant_id_for_other_tenant(self):
"""Test create pool with a missing tenant id field.
Verify tenant_id does not match when creating pool vs.
pool (admin client)
"""
new_pool = self._prepare_and_create_pool(
protocol='HTTP',
lb_algorithm='ROUND_ROBIN')
pool = self._show_pool(new_pool.get('id'))
pool_tenant = pool['tenant_id']
self.assertNotEqual(pool_tenant, self.subnet['tenant_id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('140c4c95-3d12-47d7-9b20-cc3c60e24af9')
def test_create_pool_missing_tenant_id_for_admin(self):
"""Test create pool with a missing tenant id field.
Verify tenant_id matches when creating pool vs. pool (admin client)
"""
new_pool = self._prepare_and_create_pool(
protocol='HTTP',
lb_algorithm='ROUND_ROBIN')
pool = self._show_pool(new_pool.get('id'))
pool_tenant = pool['tenant_id']
self.assertEqual(pool_tenant, pool.get('tenant_id'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('1cf07f5c-7609-4b64-b5b8-f27050860132')
def test_create_pool_for_another_tenant(self):
"""Test create pool for other tenant field"""
tenant = 'deffb4d7c0584e89a8ec99551565713c'
new_pool = self._prepare_and_create_pool(
tenant_id=tenant)
pool = self._show_pool(new_pool.get('id'))
pool_tenant = pool.get('tenant_id')
self.assertEqual(pool_tenant, tenant)

View File

@ -1,634 +0,0 @@
# 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 tempest.lib import exceptions as ex
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
PROTOCOL_PORT = 80
class TestPools(base.BaseTestCase):
"""Tests the following operations in the Neutron-LBaaS API
using the REST client for Pools:
list pools
create pool
get pool
update pool
delete pool
"""
@classmethod
def resource_setup(cls):
super(TestPools, cls).resource_setup()
cls.load_balancer = cls._create_load_balancer(
tenant_id=cls.subnet.get('tenant_id'),
vip_subnet_id=cls.subnet.get('id'),
wait=True)
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
def increment_protocol_port(self):
global PROTOCOL_PORT
PROTOCOL_PORT += 1
def _prepare_and_create_pool(self, protocol=None, lb_algorithm=None,
listener_id=None, cleanup=True, **kwargs):
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
self.increment_protocol_port()
if not protocol:
protocol = 'HTTP'
if not lb_algorithm:
lb_algorithm = 'ROUND_ROBIN'
if not listener_id:
listener = self._create_listener(
loadbalancer_id=self.load_balancer.get('id'),
protocol='HTTP', protocol_port=PROTOCOL_PORT,
wait=True)
listener_id = listener.get('id')
response = self._create_pool(protocol=protocol,
lb_algorithm=lb_algorithm,
listener_id=listener_id,
wait=True,
**kwargs)
if cleanup:
self.addCleanup(self._delete_pool, response['id'])
return response
@decorators.attr(type='smoke')
@decorators.idempotent_id('99154002-e598-4277-b6d8-bf0fe10f276f')
def test_list_pools_empty(self):
"""Test get pools when empty"""
pools = self._list_pools()
self.assertEmpty(pools)
@decorators.attr(type='smoke')
@decorators.idempotent_id('4f09b544-8e82-4313-b452-8fe3ca5ad14e')
def test_list_pools_one(self):
"""Test get pools with one pool"""
new_pool = self._prepare_and_create_pool()
new_pool = self._show_pool(new_pool['id'])
pools = self._list_pools()
self.assertEqual(1, len(pools))
self.assertIn(new_pool, pools)
@decorators.attr(type='smoke')
@decorators.idempotent_id('7562b846-a685-49ea-9d41-afcaff418bae')
def test_list_pools_two(self):
"""Test get pools with two pools"""
new_pool1 = self._prepare_and_create_pool()
new_pool2 = self._prepare_and_create_pool()
pools = self._list_pools()
self.assertEqual(2, len(pools))
self.assertIn(new_pool1, pools)
self.assertIn(new_pool2, pools)
@decorators.attr(type='smoke')
@decorators.idempotent_id('0cf61c6a-efd5-4859-9d92-da204f5ec1ed')
def test_get_pool(self):
"""Test get pool"""
new_pool = self._prepare_and_create_pool()
pool = self._show_pool(new_pool.get('id'))
self.assertEqual(new_pool, pool)
@decorators.attr(type='smoke')
@decorators.idempotent_id('7fc310a0-7640-4f7c-8cdb-53b6ae23bd52')
def test_create_pool(self):
"""Test create pool"""
new_pool = self._prepare_and_create_pool()
pool = self._show_pool(new_pool.get('id'))
self.assertEqual(new_pool, pool)
@decorators.attr(type='negative')
@decorators.idempotent_id('5f414612-4f8c-4f48-ac99-286356870fae')
def test_create_pool_missing_required_fields(self):
"""Test create pool with a missing required fields"""
tenant_id = self.subnet.get('tenant_id')
self.assertRaises(ex.BadRequest, self._create_pool,
tenant_id=tenant_id,
lb_algorithm='ROUND_ROBIN')
@decorators.attr(type='smoke')
@decorators.idempotent_id('7fe53b0c-d7b8-4283-aeb3-eeeb3219e42f')
def test_create_pool_missing_tenant_field(self):
"""Test create pool with a missing required tenant field"""
tenant_id = self.subnet.get('tenant_id')
new_pool = self._prepare_and_create_pool(
protocol='HTTP',
lb_algorithm='ROUND_ROBIN')
pool = self._show_pool(new_pool.get('id'))
pool_tenant = pool['tenant_id']
self.assertEqual(tenant_id, pool_tenant)
@decorators.attr(type='negative')
@decorators.idempotent_id('7d17e507-99c2-4e8f-a403-27b630b403a2')
def test_create_pool_missing_protocol_field(self):
"""Test create pool with a missing required protocol field"""
self.increment_protocol_port()
listener = self._create_listener(
loadbalancer_id=self.load_balancer.get('id'),
protocol='HTTP', protocol_port=PROTOCOL_PORT)
self.addCleanup(self._delete_listener, listener['id'])
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
listener_id = listener.get('id')
tenant_id = self.subnet.get('tenant_id')
self.assertRaises(ex.BadRequest, self._create_pool,
tenant_id=tenant_id,
listener_id=listener_id,
lb_algorithm='ROUND_ROBIN')
@decorators.attr(type='negative')
@decorators.idempotent_id('99051cc6-bf51-4af0-b530-edbfb7d4b7ab')
def test_create_pool_missing_lb_algorithm_field(self):
"""Test create pool with a missing required lb algorithm field"""
self.increment_protocol_port()
listener = self._create_listener(
loadbalancer_id=self.load_balancer.get('id'),
protocol='HTTP', protocol_port=PROTOCOL_PORT)
self.addCleanup(self._delete_listener, listener['id'])
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
listener_id = listener.get('id')
tenant_id = self.subnet.get('tenant_id')
self.assertRaises(ex.BadRequest, self._create_pool,
tenant_id=tenant_id,
listener_id=listener_id,
protocol='HTTP')
@decorators.attr(type='negative')
@decorators.idempotent_id('d04b75fe-688b-4713-83d1-f0ac29005391')
def test_create_pool_missing_listener_id_field(self):
"""Test create pool with a missing required listener id field"""
tenant_id = self.subnet.get('tenant_id')
self.assertRaises(ex.BadRequest, self._create_pool,
tenant_id=tenant_id,
lb_algorithm='ROUND_ROBIN',
protocol='HTTP')
@decorators.attr(type='smoke')
@decorators.idempotent_id('378c56b4-cf61-448b-8460-1ffb1a091ea5')
def test_create_pool_missing_description_field(self):
"""Test create pool with missing description field"""
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
new_pool = self._prepare_and_create_pool()
pool_initial = self._show_pool(new_pool.get('id'))
desc = pool_initial.get('description')
self.assertEqual(desc, "")
@decorators.attr(type='smoke')
@decorators.idempotent_id('f73ff259-7fbb-41ac-ab92-c6eef0213e20')
def test_create_pool_missing_name_field(self):
"""Test create pool with a missing name field"""
new_pool = self._prepare_and_create_pool()
pool_initial = self._show_pool(new_pool.get('id'))
name = pool_initial.get('name')
self.assertEqual(name, "")
@decorators.attr(type='smoke')
@decorators.idempotent_id('37957c70-6979-4e15-a316-8c29cb7e724e')
def test_create_pool_missing_admin_state_up_field(self):
"""Test create pool with a missing admin_state_up field"""
new_pool = self._prepare_and_create_pool()
pool_initial = self._show_pool(new_pool.get('id'))
state = pool_initial.get('admin_state_up')
self.assertEqual(state, True)
@decorators.attr(type='smoke')
@decorators.idempotent_id('d1e41b4b-fe79-4bec-bc94-5934995c6e05')
def test_create_pool_missing_session_pers_field(self):
"""Test create pool with a missing session_pers field"""
new_pool = self._prepare_and_create_pool()
pool_initial = self._show_pool(new_pool.get('id'))
sess = pool_initial.get('session_persistence')
self.assertIsNone(sess)
@decorators.attr(type='negative')
@decorators.idempotent_id('440b3975-b7c8-4cff-85a5-a0a02ad6b8f9')
def test_create_pool_invalid_protocol(self):
"""Test create pool with an invalid protocol"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='UDP',
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('a0b322b1-629c-483c-9136-397fc9100e48')
def test_create_pool_invalid_session_persistence_field(self):
"""Test create pool with invalid session persistance field"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
session_persistence={'type': 'HTTP'},
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('53cd9427-29fa-4a55-adb8-9cb6388b9548')
def test_create_pool_invalid_algorithm(self):
"""Test create pool with an invalid algorithm"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
lb_algorithm='LEAST_CON',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('26e6bb34-4b0f-4650-a5dc-87484fa55038')
def test_create_pool_invalid_admin_state_up(self):
"""Test create pool with an invalid admin state up field"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
admin_state_up="$!1%9823",
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('8df02129-2b9c-4628-a390-805967107090')
def test_create_pool_invalid_listener_field(self):
"""Test create pool with invalid listener field"""
tenant_id = self.subnet.get('tenant_id')
self.assertRaises(ex.BadRequest, self._create_pool,
tenant_id=tenant_id,
lb_algorithm='ROUND_ROBIN',
protocol='HTTP',
listener_id="$@5$%$7863")
@decorators.attr(type='negative')
@decorators.idempotent_id('94949cd4-ebc1-4af5-a220-9ebb32772fbc')
def test_create_pool_invalid_tenant_id_field(self):
"""Test create pool with invalid tenant_id field"""
self.increment_protocol_port()
listener = self._create_listener(
loadbalancer_id=self.load_balancer.get('id'),
protocol='HTTP', protocol_port=PROTOCOL_PORT)
self.addCleanup(self._delete_listener, listener['id'])
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
listener_id = listener.get('id')
self.assertRaises(ex.BadRequest, self._create_pool,
tenant_id="*&7653^%&",
lb_algorithm='ROUND_ROBIN',
protocol='HTTP',
listener_id=listener_id)
@decorators.attr(type='negative')
@decorators.idempotent_id('e335db64-ad16-4e23-bd60-c72c37c7b188')
def test_create_pool_incorrect_attribute(self):
"""Test create a pool with an extra, incorrect field"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
lb_algorithm='ROUND_ROBIN',
protocol_port=80,
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('390053c1-adc9-4b1a-8eb0-dbdb9085cf0f')
def test_create_pool_empty_listener_field(self):
"""Test create pool with empty listener field"""
tenant_id = self.subnet.get('tenant_id')
self.assertRaises(ex.BadRequest, self._create_pool,
tenant_id=tenant_id,
lb_algorithm='ROUND_ROBIN',
protocol='HTTP',
listener_id="")
@decorators.attr(type='smoke')
@decorators.idempotent_id('8b25defa-8efc-47f5-a43d-3d299d7b9752')
def test_create_pool_empty_description_field(self):
"""Test create pool with empty description field"""
new_pool = self._prepare_and_create_pool(description="")
pool = self._show_pool(new_pool.get('id'))
pool_desc = pool.get('description')
self.assertEqual(pool_desc, '')
@decorators.attr(type='smoke')
@decorators.idempotent_id('c8cd496c-7698-4c0e-bbed-fe9ef6c910de')
def test_create_pool_empty_name_field(self):
"""Test create pool with empty name field"""
new_pool = self._prepare_and_create_pool(name="")
pool = self._show_pool(new_pool.get('id'))
pool_name = pool.get('name')
self.assertEqual(pool_name, '')
@decorators.attr(type='negative')
@decorators.idempotent_id('b7997d71-84ea-43d2-8ce0-eea4156cc952')
def test_create_pool_empty_protocol(self):
"""Test create pool with an empty protocol"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol="",
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('bffe50bb-8be5-4ed9-aea6-a15b40342599')
def test_create_pool_empty_session_persistence_field(self):
"""Test create pool with empty session persistence field"""
self.assertRaises(ex.BadRequest, self._create_pool,
session_persistence="",
protocol='HTTP',
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('4cfd301a-baae-462d-8041-84c337e95d16')
def test_create_pool_empty_algorithm(self):
"""Test create pool with an empty algorithm"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
lb_algorithm="",
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('814de2e3-a536-4ab1-a80f-9506b11c7bc8')
def test_create_pool_empty_admin_state_up(self):
"""Test create pool with an invalid admin state up field"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
admin_state_up="",
lb_algorithm='ROUND_ROBIN')
@decorators.attr(type='negative')
@decorators.idempotent_id('0f230e6d-057d-4da8-a42d-f32464ae1c47')
def test_create_pool_empty_tenant_field(self):
"""Test create pool with empty tenant field"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
tenant_id="",
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('4a0e711a-b4da-4226-b265-f87b04ee4977')
def test_create_pool_for_other_tenant_field(self):
"""Test create pool for other tenant field"""
tenant = 'deffb4d7c0584e89a8ec99551565713c'
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
tenant_id=tenant,
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('cb564af8-89aa-40ca-850e-55418da0f235')
def test_create_pool_invalid_name_field(self):
"""known bug with
input more than 255 chars Test create pool with invalid name field
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(ex.BadRequest, self._create_pool,
protocol='HTTP',
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'],
name='n' * 256)
@decorators.attr(type='negative')
@decorators.idempotent_id('7f4472be-feb7-4ab7-9fb9-97e08f1fa787')
def test_create_pool_invalid_desc_field(self):
"""known bug with
input more than 255 chars Test create pool with invalid desc field
Kilo: @decorators.skip_because(bug="1637877")
"""
self.assertRaises(ex.BadRequest, self._prepare_and_create_pool,
protocol='HTTP',
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'],
description='d' * 256)
@decorators.attr(type='negative')
@decorators.idempotent_id('b09b14dc-029d-4132-94dd-e713c9bfa0ee')
def test_create_pool_with_session_persistence_unsupported_type(self):
"""Test create a pool
with an incorrect type value for session persistence
"""
self.assertRaises(ex.BadRequest, self._create_pool,
session_persistence={'type': 'UNSUPPORTED'},
protocol='HTTP',
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('b5af574a-d05f-4db0-aece-58676cdbf440')
def test_create_pool_with_session_persistence_http_cookie(self):
"""Test create a pool with session_persistence type=HTTP_COOKIE"""
new_pool = self._prepare_and_create_pool(
session_persistence={'type': 'HTTP_COOKIE'})
pool = self._show_pool(new_pool.get('id'))
self.assertEqual(new_pool, pool)
@decorators.attr(type='smoke')
@decorators.idempotent_id('2d6b6667-e38b-4e7f-8443-8dc7ee63ea87')
def test_create_pool_with_session_persistence_app_cookie(self):
"""Test create a pool with session_persistence type=APP_COOKIE"""
new_pool = self._prepare_and_create_pool(
session_persistence={'type': 'APP_COOKIE',
'cookie_name': 'sessionId'})
pool = self._show_pool(new_pool.get('id'))
self.assertEqual(new_pool, pool)
@decorators.attr(type='negative')
@decorators.idempotent_id('9ac450fc-24c5-4b5c-a781-b23e5713f172')
def test_create_pool_with_session_persistence_redundant_cookie_name(self):
"""Test create a pool
with session_persistence with cookie_name for type=HTTP_COOKIE
"""
self.assertRaises(ex.BadRequest, self._create_pool,
session_persistence={'type': 'HTTP_COOKIE',
'cookie_name': 'sessionId'},
protocol='HTTP',
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='negative')
@decorators.idempotent_id('7783ebd0-5bd9-43f0-baf2-a43212ba2617')
def test_create_pool_with_session_persistence_without_cookie_name(self):
"""Test create a pool
with session_persistence without cookie_name for type=APP_COOKIE
"""
self.assertRaises(ex.BadRequest, self._create_pool,
session_persistence={'type': 'APP_COOKIE'},
protocol='HTTP',
lb_algorithm='ROUND_ROBIN',
listener_id=self.listener['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('767ed26e-7114-402a-bdee-443d52009a73')
def test_update_pool(self):
"""Test update pool"""
new_pool = self._prepare_and_create_pool()
desc = 'testing update with new description'
pool = self._update_pool(new_pool.get('id'),
description=desc,
wait=True)
self.assertEqual(desc, pool.get('description'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('5cbc4dac-13fc-44de-b98f-41ca369a6e0f')
def test_update_pool_missing_name(self):
"""Test update pool with missing name"""
new_pool = self._prepare_and_create_pool()
pool_initial = self._show_pool(new_pool.get('id'))
name = pool_initial.get('name')
pool = self._update_pool(new_pool.get('id'))
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
self.assertEqual(name, pool.get('name'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('af9c2f8e-b0e3-455b-83f0-222f8d692185')
def test_update_pool_missing_description(self):
"""Test update pool with missing description"""
new_pool = self._prepare_and_create_pool()
pool_initial = self._show_pool(new_pool.get('id'))
desc = pool_initial.get('description')
pool = self._update_pool(new_pool.get('id'))
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
self.assertEqual(desc, pool.get('description'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('3b41e855-edca-42c1-a1c6-07421f87704d')
def test_update_pool_missing_admin_state_up(self):
"""Test update pool with missing admin state up field"""
new_pool = self._prepare_and_create_pool()
pool_initial = self._show_pool(new_pool.get('id'))
admin = pool_initial.get('admin_state_up')
pool = self._update_pool(new_pool.get('id'))
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
self.assertEqual(admin, pool.get('admin_state_up'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('8b49ecc3-4694-4482-9b2d-dc928576e161')
def test_update_pool_missing_session_persistence(self):
"""Test update pool with missing session persistence"""
new_pool = self._prepare_and_create_pool()
pool_initial = self._show_pool(new_pool.get('id'))
sess_pers = pool_initial.get('session_persistence')
pool = self._update_pool(new_pool.get('id'))
self.assertAlmostEqual(sess_pers, pool.get('session_persistence'))
@decorators.attr(type='negative')
@decorators.idempotent_id('23a9dbaf-105b-450e-95cf-050203b28366')
def test_update_pool_invalid_name(self):
"""Test update pool with invalid name
Kilo: @decorators.skip_because(bug="1637877")
"""
new_pool = self._prepare_and_create_pool()
self.assertRaises(ex.BadRequest, self._update_pool,
new_pool.get('id'), name='n' * 256)
@decorators.attr(type='negative')
@decorators.idempotent_id('efeeb827-5cb0-4349-8272-b2dbcbf42d22')
def test_update_pool_invalid_desc(self):
"""Test update pool with invalid desc
Kilo: @decorators.skip_because(bug="1637877")
"""
new_pool = self._prepare_and_create_pool()
self.assertRaises(ex.BadRequest, self._update_pool,
new_pool.get('id'),
description='d' * 256)
@decorators.attr(type='negative')
@decorators.idempotent_id('a91c1380-0d36-43a1-bf64-8fe9078e2bbd')
def test_update_pool_invalid_admin_state_up(self):
"""Test update pool with an invalid admin_state_up"""
new_pool = self._prepare_and_create_pool()
self.assertRaises(ex.BadRequest, self._update_pool,
new_pool.get('id'), admin_state_up='hello')
@decorators.attr(type='negative')
@decorators.idempotent_id('5d45b0e3-7d7f-4523-8504-9ccfd6ecec81')
def test_update_pool_invalid_session_persistence(self):
"""Test update pool with an invalid session pers. field"""
new_pool = self._prepare_and_create_pool()
self.assertRaises(ex.BadRequest, self._update_pool,
new_pool.get('id'),
session_persistence={'type': 'Hello'})
@decorators.attr(type='smoke')
@decorators.idempotent_id('3ddec9b1-fc7a-4073-9451-e73316237763')
def test_update_pool_empty_name(self):
"""Test update pool with empty name"""
new_pool = self._prepare_and_create_pool()
pool = self._update_pool(new_pool.get('id'), name="")
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
self.assertEqual(pool.get('name'), "")
@decorators.attr(type='smoke')
@decorators.idempotent_id('171e1153-9898-467d-80ed-d6deed430342')
def test_update_pool_empty_description(self):
"""Test update pool with empty description"""
new_pool = self._prepare_and_create_pool()
pool = self._update_pool(new_pool.get('id'),
description="")
self._wait_for_load_balancer_status(self.load_balancer.get('id'))
self.assertEqual(pool.get('description'), "")
@decorators.attr(type='negative')
@decorators.idempotent_id('397bd0ec-0e82-4421-a672-b7a2c4e84b56')
def test_update_pool_empty_admin_state_up(self):
"""Test update pool with empty admin state up"""
new_pool = self._prepare_and_create_pool()
self.assertRaises(ex.BadRequest, self._update_pool,
new_pool.get('id'), admin_state_up="")
@decorators.attr(type='negative')
@decorators.idempotent_id('f68a6ed5-4577-44f1-81c8-6dd30d8a874d')
def test_update_pool_empty_session_persistence(self):
"""Test update pool with empty session persistence field"""
new_pool = self._prepare_and_create_pool()
self.assertRaises(ex.BadRequest, self._update_pool,
new_pool.get('id'),
session_persistence="")
@decorators.attr(type='negative')
@decorators.idempotent_id('d8027ea2-6912-41f7-bf5a-f2eb3d0901b1')
def test_update_pool_invalid_attribute(self):
"""Test update pool with an invalid attribute"""
new_pool = self._prepare_and_create_pool()
self.assertRaises(ex.BadRequest, self._update_pool,
new_pool.get('id'), lb_algorithm='ROUNDED')
@decorators.attr(type='negative')
@decorators.idempotent_id('a58822ee-56fc-4b96-bb28-47cd07ae9cb8')
def test_update_pool_incorrect_attribute(self):
"""Test update a pool with an extra, incorrect field"""
new_pool = self._prepare_and_create_pool()
self.assertRaises(ex.BadRequest, self._update_pool,
new_pool.get('id'), protocol='HTTPS')
@decorators.attr(type='smoke')
@decorators.idempotent_id('4839f03e-2439-4619-8546-411ca883066d')
def test_delete_pool(self):
"""Test delete pool"""
new_pool = self._prepare_and_create_pool(cleanup=False)
pool = self._show_pool(new_pool.get('id'))
self.assertEqual(new_pool, pool)
self._delete_pool(new_pool.get('id'))
self.assertRaises(ex.NotFound, self._show_pool,
new_pool.get('id'))
@decorators.attr(type='smoke')
@decorators.idempotent_id('cd30962a-12ce-4ae9-89de-db007aebbd9f')
def test_delete_invalid_pool(self):
"""Test delete pool that doesn't exist"""
new_pool = self._prepare_and_create_pool(cleanup=False)
pool = self._show_pool(new_pool.get('id'))
self.assertEqual(new_pool, pool)
self._delete_pool(new_pool.get('id'))
self.assertRaises(ex.NotFound, self._delete_pool,
new_pool.get('id'))

View File

@ -1,270 +0,0 @@
# 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 testtools
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.lib import exceptions
from tempest import test
from vmware_nsx_tempest.tests.nsxv.api import base_provider as base
CONF = config.CONF
class AdminPolicyTest(base.BaseAdminNetworkTest):
"""Provides organization to policy traffic using NSX security policy
When security-group-policy extension is enabled:
1. Only Admin can create secuiry-group-policy.
2. Tenants can not create security-group.
3. No security rules can be added to security-group-policy.
4. Only Admin can update security-group-policy.
If tests failed, check vmware/nsx.ini and neutron/policy.json to make
sure correct settings are being applied.
ATTENTIONS:
if allow_tenant_rules_with_policy=True
run test_tenant_create_security_group_if_allowed
if allow_tenant_rules_with_policy=False
run test_tenant_cannot_create_security_group (negative test)
WARNING: Tempest scenario tests, tenants will create security-groups,
and failures should be expected. So when run scenario tests,
set allow_tenant_rules_with_policy to True.
"""
@classmethod
def skip_checks(cls):
super(AdminPolicyTest, cls).skip_checks()
if not test.is_extension_enabled('security-group-policy', 'network'):
msg = "Extension security-group-policy is not enabled."
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(AdminPolicyTest, cls).setup_clients()
cls.cmgr_pri = cls.get_client_manager('primary')
cls.cmgr_alt = cls.get_client_manager('alt')
cls.cmgr_adm = cls.get_client_manager('admin')
@classmethod
def resource_setup(cls):
super(AdminPolicyTest, cls).resource_setup()
cls.default_policy_id = CONF.nsxv.default_policy_id
cls.alt_policy_id = CONF.nsxv.alt_policy_id
if not (cls.default_policy_id and
cls.default_policy_id.startswith("policy-")):
msg = "default_policy_id is not defined in session nsxv"
raise cls.skipException(msg)
def delete_security_group(self, sg_client, sg_id):
sg_client.delete_security_group(sg_id)
def create_security_group(self, sg_client, sg_name=None, desc=None,
tenant_id=None):
name = sg_name or data_utils.rand_name('security-group')
desc = desc or "OS security-group %s" % name
sg_dict = dict(name=name, description=desc)
if tenant_id:
sg_dict['tenant_id'] = tenant_id
sg = sg_client.create_security_group(**sg_dict)
sg = sg.get('security_group', sg)
return sg
def create_security_group_policy(self, cmgr=None, policy_id=None,
tenant_id=None, provider=False):
cmgr = cmgr or self.cmgr_adm
policy_id = policy_id or self.default_policy_id
sg_client = cmgr.security_groups_client
sg_dict = dict(policy=policy_id,
name=data_utils.rand_name('admin-policy'))
if tenant_id:
sg_dict['tenant_id'] = tenant_id
if provider:
sg_dict['provider'] = True
sg = sg_client.create_security_group(**sg_dict)
sg = sg.get('security_group', sg)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_security_group,
sg_client, sg.get('id'))
return sg
def update_security_group_policy(self, security_group_id,
new_policy_id, cmgr=None):
cmgr = cmgr or self.cmgr_adm
sg_client = cmgr.security_groups_client
sg = sg_client.update_security_group(security_group_id,
policy=new_policy_id)
return sg.get('security_group', sg)
def create_security_group_rule(self, security_group_id,
cmgr=None, tenant_id=None):
cmgr = cmgr or self.cmgr_adm
sgr_client = cmgr.security_group_rules_client
sgr_dict = dict(security_group_id=security_group_id,
direction='ingress', protocol='icmp')
if tenant_id:
sgr_dict['tenant_id'] = tenant_id
sgr = sgr_client.create_security_group_rule(**sgr_dict)
return sgr.get('security_group_rule', sgr)
def get_default_security_group_policy(self, cmgr=None):
cmgr = cmgr or self.cmgr_adm
sg_client = cmgr.security_groups_client
sg_list = sg_client.list_security_groups()
# why list twice, see bug#1772424
sg_list = sg_client.list_security_groups(name='default')
sg_list = sg_list.get('security_groups', sg_list)
return sg_list[0]
def show_security_group_policy(self, security_group_id, cmgr=None):
cmgr = cmgr or self.cmgr_adm
sg_client = cmgr.security_groups_client
sg = sg_client.show_security_group(security_group_id)
return sg.get('security_group', sg)
@decorators.idempotent_id('825d0270-6649-44f2-ac0c-a3b5566d0d2a')
def test_admin_can_crud_policy(self):
sg_desc = "crud security-group-policy"
sg_client = self.cmgr_adm.security_groups_client
sg = self.create_security_group_policy(self.cmgr_adm)
sg_id = sg.get('id')
self.assertEqual(self.default_policy_id, sg.get('policy'))
sg_client.update_security_group(sg_id, description=sg_desc)
sg_show = self.show_security_group_policy(sg_id)
self.assertEqual(sg_desc, sg_show.get('description'))
self.delete_security_group(sg_client, sg_id)
sg_list = sg_client.list_security_groups(id=sg_id)
sg_list = sg_list.get('security_groups', sg_list)
self.assertEqual(len(sg_list), 0)
@decorators.idempotent_id('809d72be-c2d8-4e32-b538-09a5003630c0')
def test_admin_can_create_policy_for_tenant(self):
tenant_id = self.cmgr_alt.networks_client.tenant_id
sg = self.create_security_group_policy(self.cmgr_adm,
tenant_id=tenant_id)
self.assertEqual(self.default_policy_id, sg.get('policy'))
@decorators.idempotent_id('1ab540b0-2a56-46cd-bbaa-607a655b4688')
def test_admin_can_create_provider_policy(self):
tenant_id = self.cmgr_pri.networks_client.tenant_id
sg = self.create_security_group_policy(self.cmgr_adm,
tenant_id=tenant_id,
provider=True)
self.assertEqual(self.default_policy_id, sg.get('policy'))
self.assertEqual(sg.get('provider'), True)
@decorators.idempotent_id('1d31ea7a-37f1-40db-b917-4acfbf565ae2')
def test_tenant_has_default_policy(self):
sg = self.get_default_security_group_policy(self.cmgr_pri)
self.assertEqual(self.default_policy_id, sg.get('policy'))
@testtools.skipIf(not CONF.nsxv.alt_policy_id.startswith('policy-'),
"nsxv.alt_policy_id not defined.")
@decorators.idempotent_id('6784cf25-6b50-4349-b96b-85076111dbf4')
def test_admin_change_tenant_policy(self):
tenant_id = self.cmgr_alt.networks_client.tenant_id
sg = self.create_security_group_policy(tenant_id=tenant_id)
sg_id = sg.get('id')
self.update_security_group_policy(sg_id, self.alt_policy_id)
sg = self.show_security_group_policy(sg_id, self.cmgr_alt)
self.assertEqual(self.alt_policy_id, sg.get('policy'))
@testtools.skipIf(not CONF.nsxv.allow_tenant_rules_with_policy,
"skip because tenant is not allowed to create SG.")
@decorators.idempotent_id('4abf29bd-22ae-46b4-846b-e7c28f318159')
def test_tenant_create_security_group_if_allowed(self):
"""test if allow_tenant_rules_with_policy=True"""
sg_client = self.cmgr_pri.security_groups_client
sg_name = data_utils.rand_name('security-group')
sg = self.create_security_group(sg_client, sg_name)
self.assertEqual(sg.get('name'), sg_name)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('5099604c-637a-4b25-8756-c6fc0929f963')
def test_add_rules_to_policy_disallowed(self):
tenant_id = self.cmgr_pri.networks_client.tenant_id
sg = self.create_security_group_policy(self.cmgr_adm,
tenant_id=tenant_id)
self.assertRaises(exceptions.BadRequest,
self.create_security_group_rule, sg.get('id'),
cmgr=self.cmgr_adm, tenant_id=tenant_id)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('9a604036-ace6-4ced-92b8-be732eee310f')
def test_cannot_create_policy_with_invalid_policy_id(self):
self.assertRaises(exceptions.BadRequest,
self.create_security_group_policy,
self.cmgr_adm, "invalid-policy-id")
@decorators.attr(type=['negative'])
@decorators.idempotent_id('4d383d3c-f1e6-47e3-906e-3c171146965a')
def test_tenant_cannot_delete_its_policy(self):
tenant_cmgr = self.cmgr_alt
tenant_id = tenant_cmgr.networks_client.tenant_id
sg = self.create_security_group_policy(cmgr=self.cmgr_adm,
tenant_id=tenant_id)
sg_id = sg.get('id')
tenant_sg_client = tenant_cmgr.security_groups_client
self.assertRaises(exceptions.Forbidden,
self.delete_security_group,
tenant_sg_client, sg_id)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('154985cd-26b2-468d-af6d-b6144ef2d378')
def test_tenant_cannot_update_its_policy(self):
tenant_cmgr = self.cmgr_alt
tenant_id = tenant_cmgr.networks_client.tenant_id
sg = self.create_security_group_policy(cmgr=self.cmgr_adm,
tenant_id=tenant_id)
sg_id = sg.get('id')
self.assertRaises(exceptions.Forbidden,
self.update_security_group_policy,
sg_id, self.alt_policy_id, self.cmgr_alt)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('d6d8c918-d488-40c4-83dc-8ce1a565e54f')
def test_tenant_cannot_create_policy(self):
self.assertRaises(exceptions.Forbidden,
self.create_security_group_policy,
self.cmgr_pri)
@decorators.attr(type=['negative'])
@testtools.skipIf(CONF.nsxv.allow_tenant_rules_with_policy,
"skip because tenant is allowed to create SG.")
@decorators.idempotent_id('82aa02ee-8008-47a9-90ea-ba7840bfb932')
def test_tenant_cannot_create_security_group(self):
"""Only valid if allow_tenant_rules_with_policy=True
If test fail, check nsx.ini and vmware_nsx_tempest/config.py
to make sure they are the same value.
Exception is BadRequest, not Forbideen as the message is
edited first before integration check.
counter part test is:
test_tenant_create_security_group_if_allowed()
"""
sg_client = self.cmgr_pri.security_groups_client
sg_name = data_utils.rand_name('security-group')
self.assertRaises(exceptions.BadRequest,
self.create_security_group,
sg_client, sg_name)

View File

@ -1,129 +0,0 @@
# 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.
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 vmware_nsx_tempest.tests.nsxv.api import base_provider as base
CONF = config.CONF
class DnsSearchDomainTest(base.BaseAdminNetworkTest):
@classmethod
def resource_setup(cls):
super(DnsSearchDomainTest, cls).resource_setup()
cls.dns_search_domain = CONF.network.dns_search_domain
network_name = data_utils.rand_name('dns-search')
resp = cls.create_network(client=cls.networks_client,
name=network_name)
cls.project_network = resp.get('network', resp)
# addCleanup() only available at instance, not at class
resp = cls.create_subnet(cls.project_network,
name=network_name,
client=cls.subnets_client,
dns_search_domain=cls.dns_search_domain)
cls.tenant_subnet = resp.get('subnet', resp)
@classmethod
def resource_cleanup(cls):
# we need to cleanup resouces created at class methods
test_utils.call_and_ignore_notfound_exc(
cls.networks_client.delete_network,
cls.project_network['id'])
super(DnsSearchDomainTest, cls).resource_cleanup()
def create_networks(self, network_name):
resp = self.create_network(client=self.networks_client,
name=network_name)
network = resp.get('network', resp)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.networks_client.delete_network,
network['id'])
resp = self.create_subnet(network,
name=network_name,
client=self.subnets_client,
dns_search_domain=self.dns_search_domain)
subnet = resp.get('subnet', resp)
return (network, subnet)
@decorators.idempotent_id('879d620c-535c-467f-9e62-f2bf3178b5b7')
def test_dns_search_domain_crud_operations(self):
"""perform CRUD operation on subnet with dns_search_domain."""
network_name = data_utils.rand_name('crud-search-domain')
network, subnet = self.create_networks(network_name)
self.assertEqual('ACTIVE', network['status'])
new_name = network_name + "-update"
resp = self.update_subnet(
subnet['id'], name=new_name,
client=self.subnets_client,
dns_search_domain=self.dns_search_domain)
subnet = resp.get('subnet', resp)
self.assertEqual(subnet['name'], new_name)
self.assertEqual(subnet['dns_search_domain'],
self.dns_search_domain)
subnet_list = self.list_subnets(client=self.subnets_client,
name=new_name)['subnets']
self.assertEqual(1, len(subnet_list))
self.delete_subnet(subnet['id'])
subnet_list = self.list_subnets(client=self.subnets_client,
name=new_name)['subnets']
self.assertEqual(0, len(subnet_list))
@decorators.idempotent_id('40facdd9-40c0-48a1-bff1-57ba0ed0dc49')
def test_list_search_domain(self):
subnet_list = self.list_subnets(client=self.subnets_client,
subnet_id=self.tenant_subnet['id'])
self.assertEqual(1, len(subnet_list))
@decorators.idempotent_id('8d023934-b0c8-4588-b48b-17db047a4d8b')
def test_show_search_domain(self):
resp = self.show_subnet(self.tenant_subnet['id'],
client=self.subnets_client)
subnet = resp.get('subnet', resp)
self.assertEqual(self.dns_search_domain,
subnet['dns_search_domain'])
@decorators.idempotent_id('2b5990bf-d904-4e18-b197-93f3c061c260')
def test_update_subnet_search_domain_field(self):
"""attach 2nd subnet to network and update its dns_search_domain."""
subnet_name = data_utils.rand_name('upd-search-domain')
# 2nd subnet attached to a network, make sure to use different cidr
resp = self.create_subnet(self.project_network,
name=subnet_name,
cidr_offset=1,
client=self.subnets_client)
subnet = resp.get('subnet', resp)
self.assertNotIn('dns_search_domain', subnet)
resp = self.update_subnet(
subnet['id'],
client=self.subnets_client,
dns_search_domain=self.dns_search_domain)
subnet = resp.get('subnet', resp)
self.assertEqual(subnet['dns_search_domain'],
self.dns_search_domain)
# no method to remove dns_search_domain attribute
# set to '' to clear search domain
resp = self.update_subnet(
subnet['id'],
client=self.subnets_client,
dns_search_domain='')
subnet = resp.get('subnet', resp)
self.assertEqual(subnet['dns_search_domain'], '')
self.delete_subnet(subnet['id'],
client=self.subnets_client)

View File

@ -1,56 +0,0 @@
# 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.
from tempest.api.network import base
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.lib import exceptions
CONF = config.CONF
class DnsSearchDoaminsNegativeTest(base.BaseAdminNetworkTest):
@classmethod
def skip_checks(cls):
super(DnsSearchDoaminsNegativeTest, cls).skip_checks()
def create_network_with_bad_dns_search_domain(
self, dns_search_domain="vmware@com"):
networks_client = self.networks_client
subnets_client = self.subnets_client
network_name = data_utils.rand_name('dns-sear-negative')
resp = networks_client.create_network(name=network_name)
network = resp.get('network', resp)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
networks_client.delete_network,
network['id'])
subnet_cfg = {
'client': subnets_client,
'name': network_name,
'dns_search_domain': dns_search_domain}
# should trigger exception of BadRequest with message:
# Invalid input for dns_search_domain: ...
resp = self.create_subnet(network, **subnet_cfg)
subnet = resp.get('subnet', resp)
return (network, subnet)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('11bdc214-10d7-4926-8f49-2da3d8719143')
def test_create_dns_search_domain_negative(self):
self.assertRaises(exceptions.BadRequest,
self.create_network_with_bad_dns_search_domain)

View File

@ -1,116 +0,0 @@
# Copyright 2015 OpenStack Foundation
# 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 oslo_log import log as logging
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import test_subnets as SNET
LOG = logging.getLogger(__name__)
class FlatNetworksTestJSON(SNET.SubnetTestJSON):
_interface = 'json'
_provider_network_body = {
'name': data_utils.rand_name('FLAT-network'),
'provider:network_type': 'flat'}
@classmethod
def resource_setup(cls):
super(FlatNetworksTestJSON, cls).resource_setup()
def _create_network(self, _auto_clean_up=True, network_name=None,
**kwargs):
network_name = network_name or data_utils.rand_name('flat-netwk')
# self.create_network expect network_name
# self.admin_client.create_network()
# and self.client.create_network() expect name
post_body = {'name': network_name,
'provider:network_type': 'flat'}
post_body.update(kwargs)
LOG.debug("create FLAT network: %s", str(post_body))
body = self.admin_networks_client.create_network(**post_body)
network = body['network']
if _auto_clean_up:
self.addCleanup(self._try_delete_network, network['id'])
return network
@decorators.idempotent_id('dc2f2f46-0577-4e2a-b35d-3c8c8bbce5bf')
def test_create_network(self):
# Create a network as an admin user specifying the
# flat network type attribute
network = self._create_network()
# Verifies router:network_type parameter
self.assertIsNotNone(network['id'])
self.assertEqual(network.get('provider:network_type'), 'flat')
@decorators.idempotent_id('777fc335-b26c-42ea-9759-c71dff2ce1c6')
def test_update_network(self):
# Update flat network as an admin user specifying the
# flat network attribute
network = self._create_network(shared=True, _auto_clean_up=False)
self.assertEqual(network.get('shared'), True)
new_name = network['name'] + "-updated"
update_body = {'shared': False, 'name': new_name}
body = self.update_network(network['id'], **update_body)
updated_network = body['network']
# Verify that name and shared parameters were updated
self.assertEqual(updated_network['shared'], False)
self.assertEqual(updated_network['name'], new_name)
# get flat network attributes and verify them
body = self.show_network(network['id'])
updated_network = body['network']
# Verify that name and shared parameters were updated
self.assertEqual(updated_network['shared'], False)
self.assertEqual(updated_network['name'], new_name)
self.assertEqual(updated_network['status'], network['status'])
self.assertEqual(updated_network['subnets'], network['subnets'])
self._delete_network(network['id'])
@decorators.idempotent_id('1dfc1c11-e838-464c-85b2-ed5e4c477c64')
def test_list_networks(self):
# Create flat network
network = self._create_network(shared=True)
# List networks as a normal user and confirm it is available
body = self.list_networks(client=self.networks_client)
network_list = [net['id'] for net in body['networks']]
self.assertIn(network['id'], network_list)
update_body = {'shared': False}
body = self.update_network(network['id'], **update_body)
# List networks as a normal user and confirm it is not available
body = self.list_networks(client=self.networks_client)
network_list = [net['id'] for net in body['networks']]
self.assertNotIn(network['id'], network_list)
@decorators.idempotent_id('b5649fe2-a214-4105-8053-1825a877c45b')
def test_show_network_attributes(self):
# Create flat network
network = self._create_network(shared=True)
# Show a flat network as a normal user and confirm the
# flat network attribute is returned.
body = self.show_network(network['id'], client=self.networks_client)
show_net = body['network']
self.assertEqual(network['name'], show_net['name'])
self.assertEqual(network['id'], show_net['id'])
# provider attributes are for admin only
body = self.show_network(network['id'])
show_net = body['network']
net_attr_list = show_net.keys()
for attr in ('admin_state_up', 'port_security_enabled', 'shared',
'status', 'subnets', 'tenant_id', 'router:external',
'provider:network_type', 'provider:physical_network',
'provider:segmentation_id'):
self.assertIn(attr, net_attr_list)

View File

@ -1,186 +0,0 @@
# Copyright 2015 OpenStack Foundation
# Copyright 2015 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.api.network import base
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest import test
from vmware_nsx_tempest.services import base_l2gw
from vmware_nsx_tempest.services import l2_gateway_client as L2GW
CONF = config.CONF
L2GW_RID = 'l2_gateway'
L2GW_RIDs = 'l2_gateways'
MSG_DIFF = "l2gw %s=%s is not the same as requested=%s"
class L2GatewayTest(base.BaseAdminNetworkTest):
"""Test l2-gateway operations:
l2-gateway-create
l2-gateway-show
l2-gateway-update
l2-gateway-list
l2-gateway-delete
over single device/interface/vlan
over single device/interface/multiple-vlans
over single device/multiple-interfaces/multiple-vlans
over multiple-device/multiple-interfaces/multiple-vlans
"""
credentials = ['primary', 'admin']
@classmethod
def skip_checks(cls):
super(L2GatewayTest, cls).skip_checks()
if not test.is_extension_enabled('l2-gateway', 'network'):
msg = "l2-gateway extension not enabled."
raise cls.skipException(msg)
# if CONF attr device_on_vlan not defined, SKIP entire test suite
cls.getattr_or_skip_test("device_one_vlan")
@classmethod
def getattr_or_skip_test(cls, l2gw_attr_name):
attr_value = getattr(CONF.l2gw, l2gw_attr_name, None)
if attr_value:
return attr_value
msg = "CONF session:l2gw attr:%s is not defined." % (l2gw_attr_name)
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(L2GatewayTest, cls).setup_clients()
cls.l2gw_created = {}
l2gw_mgr = cls.os_adm
cls.l2gw_client = L2GW.get_client(l2gw_mgr)
cls.l2gw_list_0 = cls.l2gw_client.list_l2_gateways()[L2GW_RIDs]
@classmethod
def resource_setup(cls):
super(L2GatewayTest, cls).resource_setup()
@classmethod
def resource_cleanup(cls):
for _id in cls.l2gw_created.keys():
try:
cls.l2gw_client.delete_l2_gateway(_id)
except Exception:
# log it please
pass
def get_segmentation_id(self, _l2gw, d_idx=0, i_idx=0):
_dev = _l2gw['devices'][d_idx]
_seg = _dev['interfaces'][i_idx].get('segmentation_id', [])
return sorted(_seg)
def pop_segmentation_id(self, _l2gw, d_idx=0, i_idx=0):
_dev = _l2gw['devices'][d_idx]
_seg = _dev['interfaces'][i_idx].pop('segmentation_id', [])
return sorted(_seg)
def get_interfaces(self, _l2gw, d_idx=0):
_dev = _l2gw['devices'][d_idx]
return sorted(_dev)
def do_csuld_single_device_interface_vlan(self, _name, _devices):
_vlan_id_list = self.get_segmentation_id(_devices, 0, 0)
_res_new = self.l2gw_client.create_l2_gateway(
name=_name, **_devices)[L2GW_RID]
self.l2gw_created[_res_new['id']] = _res_new
self.assertEqual(_name, _res_new['name'],
MSG_DIFF % ('name', _res_new['name'], _name))
# w/wo vlan provided, need to check it is assigned/not-assigned
_seg_list = self.get_segmentation_id(_res_new, 0, 0)
self.assertEqual(0, cmp(_vlan_id_list, _seg_list),
MSG_DIFF % ('vlan', _seg_list, _vlan_id_list))
_res_show = self.l2gw_client.show_l2_gateway(
_res_new['id'])[L2GW_RID]
_if_created = _res_new['devices'][0]['interfaces']
_if_shown = _res_show['devices'][0]['interfaces']
self.assertEqual(0, cmp(_if_created, _if_shown),
MSG_DIFF % ('interfaces', _if_created, _if_shown))
_name2 = _name + "-day2"
_res_upd = self.l2gw_client.update_l2_gateway(
_res_new['id'], name=_name2)[L2GW_RID]
_res_lst = self.l2gw_client.list_l2_gateways(
name=_name2)[L2GW_RIDs][0]
self.assertEqual(_name2 == _res_upd['name'],
_name2 == _res_lst['name'],
MSG_DIFF % ('name', _res_new['name'], _name2))
self.l2gw_client.delete_l2_gateway(_res_new['id'])
_res_lst = self.l2gw_client.list_l2_gateways(name=_name2)[L2GW_RIDs]
self.l2gw_created.pop(_res_new['id'])
self.assertEmpty(_res_lst,
"l2gw name=%s, id=%s not deleted." %
(_name2, _res_new['id']))
@decorators.idempotent_id('8b45a9a5-468b-4317-983d-7cceda367074')
def test_csuld_single_device_interface_without_vlan(self):
"""Single device/interface/vlan
Create l2gw with one and only one VLAN. In this case,
l2-gateway-connnection does not need to specify VLAN.
"""
dev_profile = self.getattr_or_skip_test("device_one_vlan")
_name = data_utils.rand_name('l2gw-1v1')
_devices = base_l2gw.get_l2gw_body(dev_profile)
self.pop_segmentation_id(_devices, 0, 0)
self.do_csuld_single_device_interface_vlan(_name, _devices)
@decorators.idempotent_id('af57cf56-a169-4d88-b32e-7f49365ce407')
def test_csuld_single_device_interface_vlan(self):
"""Single device/interface/vlan
Create l2gw without specifying LAN. In this case,
l2-gateway-connnection need to specify VLAN.
"""
dev_profile = self.getattr_or_skip_test("device_one_vlan")
_name = data_utils.rand_name('l2gw-1v2')
_devices = base_l2gw.get_l2gw_body(dev_profile)
self.do_csuld_single_device_interface_vlan(_name, _devices)
@decorators.idempotent_id('cb59145e-3d2b-46b7-8f7b-f30f794a4d51')
@decorators.skip_because(bug="1559913")
def test_csuld_single_device_interface_mvlan(self):
dev_profile = self.getattr_or_skip_test("device_multiple_vlans")
_name = data_utils.rand_name('l2gw-2v1')
_devices = base_l2gw.get_l2gw_body(dev_profile)
self.do_csuld_single_device_interface_vlan(_name, _devices)
@decorators.skip_because(bug="1559913")
@decorators.idempotent_id('5522bdfe-ebe8-4eea-81b4-f4075bb608cf')
def test_csuld_single_device_minterface_mvlan_type1(self):
# NSX-v does not support multiple interfaces
dev_profile = self.getattr_or_skip_test(
"multiple_interfaces_multiple_vlans")
_name = data_utils.rand_name('l2gw-m2v1')
_devices = base_l2gw.get_l2gw_body(dev_profile)
self.do_csuld_single_device_interface_vlan(_name, _devices)
@decorators.skip_because(bug="1559913")
@decorators.idempotent_id('5bec26e0-855f-4537-b31b-31663a820ddb')
def test_csuld_single_device_minterface_mvlan_type2(self):
# NSX-v does not support multiple interfaces
dev_profile = self.getattr_or_skip_test(
"multiple_interfaces_multiple_vlans")
_name = data_utils.rand_name('l2gw-m2v2')
_devices = base_l2gw.get_l2gw_body(dev_profile)
self.do_csuld_single_device_interface_vlan(_name, _devices)

View File

@ -1,273 +0,0 @@
# Copyright 2015 OpenStack Foundation
# Copyright 2015 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 netaddr
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 import decorators
from vmware_nsx_tempest.services import base_l2gw
from vmware_nsx_tempest.services import l2_gateway_client as L2GW
from vmware_nsx_tempest.services import \
l2_gateway_connection_client as L2GWC
CONF = config.CONF
L2GW_RID = 'l2_gateway'
L2GW_RIDs = 'l2_gateways'
L2GWC_RID = 'l2_gateway_connection'
L2GWC_RIDs = 'l2_gateway_connections'
MSG_DIFF = "l2gw %s=%s is not the same as requested=%s"
class L2GatewayConnectionTest(base.BaseAdminNetworkTest):
"""Test l2-gateway-connection operations:
l2-gateway-connection-create
l2-gateway-connection-show
l2-gateway-connection-update (no case)
l2-gateway-connection-list
l2-gateway-connection-delete
over single device/interface/vlan
over single device/interface/multiple-vlans
over single device/multiple-interfaces/multiple-vlans
over multiple-device/multiple-interfaces/multiple-vlans
"""
credentials = ['primary', 'admin']
@classmethod
def skip_checks(cls):
super(L2GatewayConnectionTest, cls).skip_checks()
if not test.is_extension_enabled('l2-gateway', 'network'):
msg = "l2-gateway extension not enabled."
raise cls.skipException(msg)
if not test.is_extension_enabled('l2-gateway-connection',
'network'):
msg = "l2-gateway-connection extension is not enabled"
raise cls.skipException(msg)
# skip test if CONF session:l2gw does not have the following opts
cls.getattr_or_skip_test("device_one_vlan")
cls.getattr_or_skip_test("vlan_subnet_ipv4_dict")
@classmethod
def getattr_or_skip_test(cls, l2gw_attr_name):
attr_value = getattr(CONF.l2gw, l2gw_attr_name, None)
if attr_value:
return attr_value
msg = "CONF session:l2gw attr:%s is not defined." % (l2gw_attr_name)
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(L2GatewayConnectionTest, cls).setup_clients()
cls.l2gw_created = {}
cls.l2gwc_created = {}
l2gw_mgr = cls.os_adm
cls.l2gw_client = L2GW.get_client(l2gw_mgr)
cls.l2gwc_client = L2GWC.get_client(l2gw_mgr)
cls.l2gw_list_0 = cls.l2gw_client.list_l2_gateways()[L2GW_RIDs]
@classmethod
def resource_setup(cls):
super(L2GatewayConnectionTest, cls).resource_setup()
# create primary tenant's VLAN network
_subnet = cls.getattr_or_skip_test("vlan_subnet_ipv4_dict")
for _x in ('mask_bits',):
if _x in _subnet:
_subnet[_x] = int(_subnet[_x])
# cidr must be presented & in IPNetwork structure
_subnet['cidr'] = netaddr.IPNetwork(_subnet['cidr'])
_start = _subnet.pop('start', None)
_end = _subnet.pop('end', None)
if _start and _end:
_subnet['allocation_pools'] = [{'start': _start, 'end': _end}]
cls.network = cls.create_network()
# baseAdminNetworkTest does not derive ip_version, mask_bits from cidr
_subnet['ip_version'] = 4
if 'mask_bits' not in _subnet:
_subnet['mask_bits'] = _subnet['cidr'].prefixlen
cls.subnet = cls.create_subnet(cls.network, **_subnet)
@classmethod
def resource_cleanup(cls):
cls.l2gw_cleanup()
if hasattr(cls, 'network'):
cls.networks_client.delete_network(cls.network['id'])
@classmethod
def l2gw_cleanup(cls):
"""
Delete created L2GWs and L2GWCs.
"""
for _id in cls.l2gwc_created.keys():
try:
cls.l2gwc_client.delete_l2_gateway_connection(_id)
except Exception:
# log it please
pass
for _id in cls.l2gw_created.keys():
try:
cls.l2gw_client.delete_l2_gateway(_id)
except Exception:
# log it please
pass
@classmethod
def get_ipaddress_from_tempest_conf(cls, ip_version=4):
"""Return first subnet gateway for configured CIDR."""
if ip_version == 4:
cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
elif ip_version == 6:
cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
return netaddr.IPAddress(cidr)
def get_segmentation_id(self, _l2gw, d_idx=0, i_idx=0):
_dev = _l2gw['devices'][d_idx]
_seg = _dev['interfaces'][i_idx].get('segmentation_id', [])
return sorted(_seg)
def get_interfaces(self, _l2gw, d_idx=0):
_dev = _l2gw['devices'][d_idx]
return sorted(_dev)
def pop_segmentation_id(self, _l2gw, d_idx=0, i_idx=0):
_dev = _l2gw['devices'][d_idx]
_seg = _dev['interfaces'][i_idx].pop('segmentation_id', [])
return sorted(_seg)
def create_l2gw_switch(self, _name, _devices):
_vlan_id_list = self.get_segmentation_id(_devices)
_res_new = self.l2gw_client.create_l2_gateway(
name=_name, **_devices)[L2GW_RID]
self.l2gw_created[_res_new['id']] = _res_new
_res_show = self.l2gw_client.show_l2_gateway(
_res_new['id'])[L2GW_RID]
return (_res_show, _vlan_id_list)
def create_l2gw_connection(self, _l2gw, network_id=None, **kwargs):
network_id = network_id or self.network['id']
_seg_id = kwargs.pop('default_segmentation_id',
kwargs.pop('segmentation_id', None))
cr_body = {'l2_gateway_id': _l2gw['id'], 'network_id': network_id}
if _seg_id:
cr_body['segmentation_id'] = _seg_id
_res_new = self.l2gwc_client.create_l2_gateway_connection(
**cr_body)[L2GWC_RID]
self.l2gwc_created[_res_new['id']] = _res_new
_res_show = self.l2gwc_client.show_l2_gateway_connection(
_res_new['id'])[L2GWC_RID]
return (_res_show, _seg_id)
def do_suld_l2gw_connection(self, _res_new):
_res_show = self.l2gwc_client.show_l2_gateway_connection(
_res_new['id'])[L2GWC_RID]
for _k in ('l2_gateway_id', 'network_id'):
self.assertEqual(_res_show[_k], _res_new[_k])
_res_lst = self.l2gwc_client.list_l2_gateway_connections(
l2_gateway_id=_res_new['l2_gateway_id'],
network_id=_res_new['network_id'])[L2GWC_RIDs][0]
self.assertEqual(_res_show['l2_gateway_id'], _res_lst['l2_gateway_id'])
self.l2gwc_client.delete_l2_gateway_connection(_res_new['id'])
_res_lst = self.l2gwc_client.list_l2_gateway_connections(
l2_gateway_id=_res_new['l2_gateway_id'],
network_id=_res_new['network_id'])[L2GWC_RIDs]
self.l2gwc_created.pop(_res_new['id'])
self.assertEmpty(_res_lst,
"l2gwc id=%s not deleted." % (_res_new['id']))
@decorators.idempotent_id('6628c662-b997-46cd-8266-77f329bda062')
def test_csuld_single_device_interface_without_vlan(self):
"""Single device/interface/vlan
Create l2gw with one and only one VLAN. In this case,
l2-gateway-connnection does not need to specify VLAN.
"""
dev_profile = self.getattr_or_skip_test("device_one_vlan")
_name = data_utils.rand_name('l2gwc-1v1')
_devices = base_l2gw.get_l2gw_body(dev_profile)
_vlan_id_list = self.pop_segmentation_id(_devices)
(_gw, _seg_list) = self.create_l2gw_switch(_name, _devices)
(_res_new, _seg_id) = self.create_l2gw_connection(
_gw, segmentation_id=_vlan_id_list[0])
_seg_new = str(_res_new.get('segmentation_id'))
self.assertEqual(_seg_new, str(_seg_id))
self.do_suld_l2gw_connection(_res_new)
self.addCleanup(self.l2gw_cleanup)
@decorators.idempotent_id('222104e3-1260-42c1-bdf6-536c1141387c')
def test_csuld_single_device_interface_vlan(self):
"""Single device/interface/vlan
Create l2gw without specifying LAN. In this case,
l2-gateway-connnection need to specify VLAN.
"""
dev_profile = self.getattr_or_skip_test("device_one_vlan")
_name = data_utils.rand_name('l2gwc-1v2')
_devices = base_l2gw.get_l2gw_body(dev_profile)
(_gw, _seg_list) = self.create_l2gw_switch(_name, _devices)
(_res_new, _seg_id) = self.create_l2gw_connection(_gw)
_seg_new = _res_new.get('segmentation_id', None)
# vlan specified @l2-gateway, so it is empty @l2-gateway-connection
self.assertEmpty(_seg_new)
self.do_suld_l2gw_connection(_res_new)
self.addCleanup(self.l2gw_cleanup)
@decorators.skip_because(bug="1559913")
@decorators.idempotent_id('1875eca7-fde9-49ba-be21-47a8cc41f2e5')
def test_csuld_single_device_interface_mvlan_type2(self):
dev_profile = self.getattr_or_skip_test("device_multiple_vlans")
_name = data_utils.rand_name('l2gwc-2v1')
_devices = base_l2gw.get_l2gw_body(dev_profile)
_vlan_id_list = self.get_segmentation_id(_devices)
(_gw, _seg_list) = self.create_l2gw_switch(_name, _devices)
(_res_new, _seg_id_list) = self.create_l2gw_connection(_gw)
_seg_id_list = _res_new.get('segmentation_id')
self.assertEqaul(0, cmp(_vlan_id_list, _seg_id_list),
MSG_DIFF % ('vlan', _vlan_id_list, _seg_id_list))
self.do_suld_l2gw_connection(_res_new)
self.addCleanup(self.l2gw_cleanup)
@decorators.skip_because(bug="1559913")
@decorators.idempotent_id('53755cb0-fdca-4ee7-8e43-a9b8a9d6d90a')
def test_csuld_single_device_minterface_mvlan_type1(self):
# NSX-v does not support multiple interfaces
dev_profile = self.getattr_or_skip_test(
"multiple_interfaces_multiple_vlans")
_name = data_utils.rand_name('l2gwc-m2v1')
_devices = base_l2gw.get_l2gw_body(dev_profile)
_gw = self.create_l2gw_switch(_name, _devices)
(_res_new, _seg_id) = self.create_l2gw_connection(_gw)
self.do_suld_l2gw_connection(_res_new)
self.addCleanup(self.l2gw_cleanup)
@decorators.skip_because(bug="1559913")
@decorators.idempotent_id('723b0b78-35d7-4774-89c1-ec73797a1fe3')
def test_csuld_single_device_minterface_mvlan_type2(self):
dev_profile = self.getattr_or_skip_test(
"multiple_interfaces_multiple_vlans")
_name = data_utils.rand_name('l2gwc-m2v2')
_devices = base_l2gw.get_l2gw_body(dev_profile)
_gw = self.create_l2gw_switch(_name, _devices)
(_res_new, _seg_id) = self.create_l2gw_connection(_gw)
self.do_suld_l2gw_connection(_res_new)
self.addCleanup(self.l2gw_cleanup)

View File

@ -1,306 +0,0 @@
# 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 base_provider as base
import six
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.services import nsxv_client
CONF = config.CONF
class MultipleTransportZonesTest(base.BaseAdminNetworkTest):
"""Validate that NSX-v plugin can support multiple transport zones.
The test environment must at least have 1 additional TZ created.
The default number of TZs used to test, include the default TZ is 3.
However, all MTZ tests can run with 2 TZs in the testbed.
"""
@classmethod
def skip_checks(cls):
super(MultipleTransportZonesTest, cls).skip_checks()
if not test.is_extension_enabled('provider', 'network'):
msg = "provider extension is not enabled"
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(MultipleTransportZonesTest, cls).setup_clients()
@classmethod
def resource_setup(cls):
super(MultipleTransportZonesTest, 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 = CONF.nsxv.max_mtz
@classmethod
def create_project_network_subnet(cls, name_prefix='mtz-project'):
network_name = data_utils.rand_name(name_prefix)
resp = cls.create_network(client=cls.networks_client,
name=network_name)
network = resp.get('network', resp)
cls.tenant_net = [None, network]
resp = cls.create_subnet(network,
name=network_name,
client=cls.subnets_client)
subnet = resp.get('subnet', resp)
return (network['id'], (None, network, subnet))
@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 create_network_subnet(self, scope_id, cidr=None, cidr_offset=0):
network_name = data_utils.rand_name('mtz-network-')
create_kwargs = {'provider:network_type': self.provider_network_type,
'provider:physical_network': scope_id}
resp = self.create_network(network_name, **create_kwargs)
network = resp.get('network', resp)
net_id = network['id']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, net_id)
self.assertEqual(scope_id,
network['provider:physical_network'])
resp = self.create_subnet(network,
name=network_name,
cidr=cidr,
cidr_offset=cidr_offset)
subnet = resp.get('subnet', resp)
resp = self.show_network(net_id)
s_network = resp.get('network', resp)
net_subnets = s_network['subnets']
self.assertIn(subnet['id'], net_subnets)
lswitch_list = self.vsm.get_all_logical_switches(scope_id)
lswitch_list = [x for x in lswitch_list if x['name'] == net_id]
msg = ("network=%s is not configured by specified vdn_scope_id=%s"
% (net_id, scope_id))
self.assertTrue(len(lswitch_list) == 1, msg=msg)
return (net_id, s_network, subnet)
def delete_networks(self, nets):
for net_id in six.iterkeys(nets):
self.delete_network(net_id)
def check_update_network(self, network):
new_name = network['name'] + "-2nd"
self.update_network(network['id'], name=new_name)
resp = self.show_network(network['id'])
s_network = resp.get('network', resp)
self.assertEqual(new_name, s_network['name'])
def check_update_subnet(self, subnet):
new_name = subnet['name'] + "-2nd"
self.update_subnet(subnet['id'], name=new_name)
resp = self.show_subnet(subnet['id'])['subnet']
s_subnet = resp.get('subnet', resp)
self.assertEqual(new_name, s_subnet['name'])
def create_show_update_delete_mtz_network_subnet(self, s_id):
net_id, network, subnet = self.create_network_subnet(s_id)
self.check_update_network(network)
self.check_update_subnet(subnet)
self.delete_network(net_id)
def create_router_by_type(self, router_type, name=None, **kwargs):
routers_client = self.admin_manager.routers_client
router_name = name or data_utils.rand_name('mtz-')
create_kwargs = dict(name=router_name, 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
kwargs.update(create_kwargs)
router = routers_client.create_router(**kwargs)
router = router['router'] if 'router' in router else router
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
routers_client.delete_router, router['id'])
self.assertEqual(router['name'], router_name)
return (routers_client, router)
def create_router_and_add_interfaces(self, router_type, nets):
(routers_client, router) = self.create_router_by_type(router_type)
if router_type == 'exclusive':
router_nsxv_name = '%s-%s' % (router['name'], router['id'])
exc_edge = self.vsm.get_edge(router_nsxv_name)
self.assertTrue(exc_edge is not None)
self.assertEqual(exc_edge['edgeType'], 'gatewayServices')
for net_id, (s_id, network, subnet) in six.iteritems(nets):
# register to cleanup before adding interfaces so interfaces
# and router can be deleted if test is aborted.
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
routers_client.remove_router_interface,
router['id'], subnet_id=subnet['id'])
routers_client.add_router_interface(
router['id'], subnet_id=subnet['id'])
return router
def clear_router_gateway_and_interfaces(self, router, nets):
routers_client = self.admin_manager.routers_client
routers_client.update_router(router['id'],
external_gateway_info=dict())
for net_id, (s_id, network, subnet) in six.iteritems(nets):
try:
routers_client.remove_router_interface(
router['id'], subnet_id=subnet['id'])
except Exception:
pass
def _test_router_with_multiple_mtz_networks(self, router_type):
"""test router attached with multiple TZs."""
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
nets = {}
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_network_subnet(
s_id, cidr_offset=(cidr_step + 2))
nets[net_id] = (s_id, network, subnet)
router = self.create_router_and_add_interfaces(router_type, nets)
self.clear_router_gateway_and_interfaces(router, nets)
def _test_router_with_network_and_mtz_networks(self, router_type):
"""test router attached with multiple TZs and one tenant network."""
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
nets = {}
net_id, net_info = self.create_project_network_subnet('mtz-tenant')
nets[net_id] = net_info
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_network_subnet(
s_id, cidr_offset=(cidr_step + 2))
nets[net_id] = (s_id, network, subnet)
router = self.create_router_and_add_interfaces(router_type, nets)
self.clear_router_gateway_and_interfaces(router, nets)
@decorators.idempotent_id('39bc7909-912c-4e16-8246-773ae6a40ba4')
def test_mtz_network_crud_operations(self):
scope_id_list = self.get_all_scope_id_list(with_default_scope=False)
s_id = scope_id_list[0]
self.create_show_update_delete_mtz_network_subnet(s_id)
@decorators.idempotent_id('4e1717d6-df39-4539-99da-df23814cfe14')
def test_mtz_overlay_network(self):
"""overlay subnets with the same TZ"""
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
s_id = scope_id_list[0]
nets = {}
for cidr_step in range(1, self.MAX_MTZ):
net_id, network, subnet = self.create_network_subnet(s_id)
nets[net_id] = (s_id, network, subnet)
self.delete_networks(nets)
@decorators.idempotent_id('6ecf67fc-4396-41d9-9d84-9d8c936dcb8f')
def test_multiple_mtz_overlay_network(self):
"""overlay subnets from multiple TZs."""
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
nets = {}
cidr_step = 0
for s_id in scope_id_list:
net_id, network, subnet = self.create_network_subnet(s_id)
nets[net_id] = (s_id, network, subnet)
net_id, network, subnet = self.create_network_subnet(s_id)
nets[net_id] = (s_id, network, subnet)
cidr_step += 1
if cidr_step < self.MAX_MTZ:
break
self.delete_networks(nets)
@decorators.idempotent_id('e7e0fc6c-41fd-44bc-b9b1-4501ce618738')
def test_mtz_non_overlay_network(self):
"""non-overlay subnets from one TZ."""
scope_id_list = self.get_all_scope_id_list(with_default_scope=False)
s_id = scope_id_list[0]
nets = {}
for cidr_step in range(0, self.MAX_MTZ):
net_id, network, subnet = self.create_network_subnet(
s_id, cidr_offset=(cidr_step + 1))
nets[net_id] = (s_id, network, subnet)
self.delete_networks(nets)
@decorators.idempotent_id('b1cb5815-6380-421f-beef-ae3cb148cef4')
def test_multiple_mtz_non_overlay_network(self):
"""non-overlay subnets from multiple TZs."""
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
nets = {}
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_network_subnet(
s_id, cidr_offset=cidr_step)
nets[net_id] = (s_id, network, subnet)
self.delete_networks(nets)
@decorators.idempotent_id('006a1a4b-4b63-4663-8baa-affe5df62b11')
def test_shared_router_with_multiple_mtz_networks(self):
"""shared router attached with multiple TZs."""
self._test_router_with_multiple_mtz_networks(
router_type='shared')
@decorators.idempotent_id('b160d1dc-0332-4d1a-b2a0-c11f57fe4dd9')
def test_exclusive_router_with_multiple_mtz_networks(self):
"""exclusive router attached with multiple TZs."""
self._test_router_with_multiple_mtz_networks(
router_type='exclusive')
@decorators.skip_because(bug="1592174")
@decorators.idempotent_id('2c46290c-8a08-4037-aada-f96fd34b3260')
def test_distributed_router_with_multiple_mtz_networks(self):
"""exclusive router attached with multiple TZs."""
self._test_router_with_multiple_mtz_networks(
router_type='distributed')
@decorators.idempotent_id('be8f7320-2246-43f3-a826-768f763c9bd0')
def test_shared_router_with_network_and_mtz_networks(self):
"""router attached with multiple TZs and one tenant network."""
self._test_router_with_network_and_mtz_networks(
router_type='shared')
@decorators.idempotent_id('3cb27410-67e2-4e82-95c7-3dbbe9a8c64b')
def test_exclusive_router_with_network_and_mtz_networks(self):
"""router attached with multiple TZs and one tenant network."""
self._test_router_with_network_and_mtz_networks(
router_type='exclusive')
@decorators.skip_because(bug="1592174")
@decorators.idempotent_id('e7c066d5-c2f1-41e7-bc86-9b6295461903')
def test_distributed_router_with_network_and_mtz_networks(self):
"""router attached with multiple TZs and one tenant network."""
self._test_router_with_network_and_mtz_networks(
router_type='distributed')

View File

@ -1,60 +0,0 @@
# 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.
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest.api.network import base
from tempest import config
CONF = config.CONF
class MultipleTransportZonesNegativeTest(base.BaseAdminNetworkTest):
@classmethod
def skip_checks(cls):
super(MultipleTransportZonesNegativeTest, cls).skip_checks()
if not hasattr(CONF.nsxv, 'vdn_scope_id'):
msg = "Testbed Network & Security vdn_scope_id not specified."
raise cls.skipException(msg)
def create_mtz_networks(self, networks_client=None, scope_id=None):
networks_client = networks_client or self.admin_networks_client
scope_id = scope_id or CONF.nsxv.vdn_scope_id
network_name = data_utils.rand_name('mtz-negative-')
create_kwargs = {'provider:network_type': 'vxlan',
'provider:physical_network': scope_id}
resp = networks_client.create_network(name=network_name,
**create_kwargs)
network = resp['network'] if 'network' in resp else resp
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
networks_client.delete_network,
network['id'])
return network
@decorators.attr(type=['negative'])
@decorators.idempotent_id('8aff7abc-eacd-409c-8278-4cb7bde6da84')
def test_create_mtz_networks(self):
# Multiple Transport Zone use provier network to implement
# its TZ allocation.
# Only admin client can create MTZ networks.
# non-admin client can not create mtz network
self.assertRaises(lib_exc.Forbidden,
self.create_mtz_networks,
networks_client=self.networks_client)

View File

@ -1,266 +0,0 @@
# 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.
import base_provider as base
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.lib import exceptions as ex
from oslo_log import log as logging
CONF = config.CONF
LOG = logging.getLogger(__name__)
class PortTypeTest(base.BaseAdminNetworkTest):
"""NSX-V OpenStack port types test
Positive
- Create direct port
- Enable port direct vnic-type
- Delete direct port
- List ports with direct port
- Create, update, delete direct port
Negative
- Create direct port without flat network with port configs
- Create direct port with flat network without port configs
- Update direct port with flat network without port configs
- Update direct port without flat network with port configs
"""
@classmethod
def setup_clients(cls):
super(PortTypeTest, cls).setup_clients()
@classmethod
def resource_setup(cls):
super(PortTypeTest, cls).resource_setup()
def _create_flat_network(self, _auto_clean_up=True, network_name=None,
**kwargs):
network_name = network_name or data_utils.rand_name('flat-net')
post_body = {'name': network_name,
'provider:network_type': 'flat'}
post_body.update(kwargs)
LOG.debug("create FLAT network: %s", str(post_body))
body = self.admin_networks_client.create_network(**post_body)
network = body['network']
self.networks.append(network)
if _auto_clean_up:
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, network['id'])
return network
def _create_direct_port(self, network_id, _auto_clean_up=True,
port_name=None, **kwargs):
dir_port_name = port_name or data_utils.rand_name('direct-port')
post_body = {'name': dir_port_name,
'port_security_enabled': 'False',
'security_groups': [],
'binding:vnic_type': 'direct'}
post_body.update(kwargs)
LOG.debug("create DIRECT port: %s", str(post_body))
body = self.create_port(network_id=network_id, **post_body)
dir_port = body['port']
if _auto_clean_up:
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, dir_port['id'])
return dir_port
@decorators.attr(type='nsxv')
@decorators.idempotent_id('ebb15f36-79bd-4461-91b5-84a57616730c')
def test_create_direct_port(self):
"""
Test create a direct openstack port. After creation, check
OpenStack for the port vnic-type.
"""
test_flat_net = self._create_flat_network()
dir_port = self._create_direct_port(network_id=test_flat_net['id'])
self.assertEqual(dir_port['binding:vnic_type'], 'direct',
"Created port type is not DIRECT")
@decorators.attr(type='nsxv')
@decorators.idempotent_id('2eaa0014-3265-479c-9012-c110df566ef1')
def test_enable_port_direct(self):
"""
Test updating a port to be a direct openstack port.
After updating, check nsx_v backend for the port type.
"""
test_flat_net = self._create_flat_network()
test_port_name = data_utils.rand_name('test-port-')
orig_post = {'name': test_port_name,
'port_security_enabled': 'False',
'security_groups': []}
LOG.debug("create NORMAL port: %s", str(orig_post))
test_port = self.create_port(network_id=test_flat_net['id'],
**orig_post)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, test_port['port']['id'])
post_body = {'binding:vnic_type': 'direct'}
LOG.debug("update port to be DIRECT: %s", str(orig_post))
self.assertEqual(test_port['port']['binding:vnic_type'], 'normal',
"Port vnic-type is not NORMAL")
updated_port = self.update_port(test_port['port']['id'], **post_body)
self.assertEqual(updated_port['port']['binding:vnic_type'], 'direct',
"Port vnic-type was not updated to DIRECT")
@decorators.attr(type='nsxv')
@decorators.idempotent_id('d77125af-7e8f-4dcf-a3a4-7956b3eaa2d2')
def test_delete_direct_port(self):
"""
Test create, then delete a direct openstack port.
Verify port type and port delete.
"""
test_flat_net = self._create_flat_network()
dir_port = self._create_direct_port(network_id=test_flat_net['id'])
self.assertEqual(dir_port['binding:vnic_type'], 'direct',
"Port type is not DIRECT")
self.assertFalse(self.delete_port(dir_port['id']),
"Delete of Direct port was not successful")
@decorators.attr(type='nsxv')
@decorators.idempotent_id('b69f5ff1-7e86-4790-9392-434cd9ab808f')
def test_list_direct_ports(self):
"""
Create one each of a normal and direct port.
Verify that both ports are included in port-list output.
"""
test_list_ports = []
test_flat_net = self._create_flat_network()
dir_port = self._create_direct_port(network_id=test_flat_net['id'])
test_list_ports.append(dir_port)
vanilla_port_name = data_utils.rand_name('vanilla-port-')
vanilla_post = {'name': vanilla_port_name}
body = self.create_port(network_id=test_flat_net['id'],
**vanilla_post)
test_port = body['port']
test_list_ports.append(test_port)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, test_port['id'])
body = self.admin_ports_client.list_ports(
network_id=test_flat_net['id'])
ports_list = body['ports']
pids_list = [p['id'] for p in ports_list]
ports_not_listed = []
for port in test_list_ports:
if port['id'] not in pids_list:
ports_not_listed.append(port['id'])
self.assertEmpty(ports_not_listed, "These ports not listed: %s"
% ports_not_listed)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('9b7ec966-f4e4-4087-9789-96a3aa669fa2')
def test_create_update_delete_direct_port(self):
"""
Create, update, delete direct port. Verify port type and update
operation.
"""
test_flat_net = self._create_flat_network()
dir_port = self._create_direct_port(network_id=test_flat_net['id'])
self.assertEqual(dir_port['binding:vnic_type'], 'direct',
"Port VNIC_TYPE should be set to DIRECT")
updated_port_name = data_utils.rand_name('update-port-')
updated_post = {'name': updated_port_name}
updated_port = self.update_port(dir_port['id'], **updated_post)['port']
self.assertEqual(updated_port['binding:vnic_type'], 'direct',
"VNIC_TYPE is not correct type, should be DIRECT")
self.assertEqual(updated_port['name'], updated_port_name,
"Port name should be updated to %s"
% updated_port_name)
@decorators.attr(type='nsxv')
@decorators.attr(type='negative')
@decorators.idempotent_id('e661ba70-0ab4-4f91-8d84-c5c102ec5793')
def test_create_direct_port_without_flat_network_negative(self):
"""
Create a network. Create a direct openstack port.
Creation should fail on a bad request since flat net prereq is not met
"""
net_name = data_utils.rand_name('test-net')
net_body = self.create_network(name=net_name)
test_net = net_body['network']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, test_net['id'])
self.assertRaises(ex.BadRequest, self._create_direct_port,
network_id=test_net['id'])
@decorators.attr(type='nsxv')
@decorators.attr(type='negative')
@decorators.idempotent_id('ee87287f-4ec6-4502-9bc1-855fa7c93e90')
def test_create_direct_port_w_flat_net_wout_port_settings_negative(self):
"""
Create a flat network. Create a direct openstack port without required
port settings.
"""
test_flat_net = self._create_flat_network()
test_port_name = data_utils.rand_name('test-port-')
orig_post = {'name': test_port_name, 'binding:vnic_type': 'direct'}
LOG.debug("create DIRECT port: %s", str(orig_post))
self.assertRaises(ex.BadRequest,
self.create_port, network_id=test_flat_net['id'],
**orig_post)
@decorators.attr(type='nsxv')
@decorators.attr(type='negative')
@decorators.idempotent_id('03e0065e-6d76-45d5-9192-ce89853dfa9e')
def test_update_direct_port_w_flat_net_wout_port_configs_negative(self):
"""
Create a flat network. Create an openstack port with vnic-type normal.
Update port to set vnic-type to direct, without required port settings.
Update should fail on a bad request since prereq is not met.
"""
test_flat_net = self._create_flat_network()
test_port_name = data_utils.rand_name('test-port-')
orig_post = {'name': test_port_name}
LOG.debug("create NORMAL port: %s", str(orig_post))
test_port = self.create_port(network_id=test_flat_net['id'],
**orig_post)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, test_port['port']['id'])
post_body = {'binding:vnic_type': 'direct'}
LOG.debug("update port to be DIRECT: %s", str(orig_post))
self.assertEqual(test_port['port']['binding:vnic_type'], 'normal',
"Orig port should be vnic-type NORMAL")
self.assertRaises(ex.BadRequest, self.update_port,
test_port['port']['id'], **post_body)
@decorators.attr(type='nsxv')
@decorators.attr(type='negative')
@decorators.idempotent_id('d3e75ed7-f3e5-4395-9ab0-063e7a8c141c')
def test_update_direct_port_wout_flat_net_with_port_configs_negative(self):
"""
Create a network. Create a normal openstack port. Update port to direct
vnic-type. Update should fail since flat net prereq is not met
"""
net_name = data_utils.rand_name('test-net')
net_body = self.create_network(name=net_name)
test_net = net_body['network']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, test_net['id'])
test_port_name = data_utils.rand_name('test-port-')
orig_post = {'name': test_port_name}
LOG.debug("create NORMAL port: %s", str(orig_post))
test_port = self.create_port(network_id=test_net['id'],
**orig_post)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_port, test_port['port']['id'])
post_body = {'port_security_enabled': 'False',
'security_groups': [],
'binding:vnic_type': 'direct'}
self.assertRaises(ex.BadRequest, self.update_port,
test_port['port']['id'], **post_body)

View File

@ -1,331 +0,0 @@
# 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
from oslo_log import log as logging
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.lib import exceptions
from tempest import test
from vmware_nsx_tempest.services import nsxv_client
from vmware_nsx_tempest.tests.nsxv.api import base_provider as base
CONF = config.CONF
LOG = logging.getLogger(__name__)
class ProviderSecGroup(base.BaseAdminNetworkTest):
"""Test Provider Security Group
1. Only Admin can create provider security group.
2. Tenants can not create provider security-group.
3. Check Provider sec group at beckend in firewall section
4. Check the priority of provider sec groups at beckend
5. Check non-admin tenant can't create provider security group
6. Check multiple rules under provider sec group
"""
@classmethod
def skip_checks(cls):
super(ProviderSecGroup, cls).skip_checks()
if not test.is_extension_enabled('provider-security-group', 'network'):
msg = "Extension provider-security-group is not enabled."
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(ProviderSecGroup, cls).setup_clients()
cls.cmgr_pri = cls.get_client_manager('primary')
cls.cmgr_alt = cls.get_client_manager('alt')
cls.cmgr_adm = cls.get_client_manager('admin')
@classmethod
def resource_setup(cls):
super(ProviderSecGroup, 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)
def delete_security_group(self, sg_client, sg_id):
sg_client.delete_security_group(sg_id)
def create_security_provider_group(self, cmgr=None,
project_id=None, provider=False):
cmgr = cmgr or self.cmgr_adm
sg_client = cmgr.security_groups_client
sg_dict = dict(name=data_utils.rand_name('provider-sec-group'))
if project_id:
sg_dict['tenant_id'] = project_id
if provider:
sg_dict['provider'] = True
sg = sg_client.create_security_group(**sg_dict)
sg = sg.get('security_group', sg)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_security_group,
sg_client, sg.get('id'))
return sg
def update_security_provider_group(self, security_group_id,
new_policy_id, cmgr=None):
cmgr = cmgr or self.cmgr_adm
sg_client = cmgr.security_groups_client
sg = sg_client.update_security_group(security_group_id,
policy=new_policy_id)
return sg.get('security_group', sg)
def create_security_group_rule(self, security_group_id,
cmgr=None, project_id=None,
protocol=None):
cmgr = cmgr or self.cmgr_adm
sgr_client = cmgr.security_group_rules_client
sgr_dict = dict(security_group_id=security_group_id,
direction='ingress', protocol=protocol)
if project_id:
sgr_dict['tenant_id'] = project_id
sgr = sgr_client.create_security_group_rule(**sgr_dict)
return sgr.get('security_group_rule', sgr)
def show_security_provider_group(self, security_group_id, cmgr=None):
cmgr = cmgr or self.cmgr_adm
sg_client = cmgr.security_groups_client
sg = sg_client.show_security_group(security_group_id)
return sg.get('security_group', sg)
def get_default_security_group_policy(self, cmgr=None):
cmgr = cmgr or self.cmgr_adm
sg_client = cmgr.security_groups_client
sg_list = sg_client.list_security_groups()
# why list twice, see bug#1772424
sg_list = sg_client.list_security_groups(name='default')
sg_list = sg_list.get('security_groups', sg_list)
return sg_list[0]
@decorators.attr(type='nsxv')
@decorators.idempotent_id('5480d96e-287b-4e59-9ee3-d1bcf451dfc9')
def test_provider_security_group_crud(self):
sg_desc = "crud provider-security-group"
sg_client = self.cmgr_adm.security_groups_client
sg = self.create_security_provider_group(self.cmgr_adm, provider=True)
sg_id = sg.get('id')
show_sec_group = sg_client.show_security_group(sg_id)
self.assertEqual(True, show_sec_group['security_group']['provider'])
sg_show = sg_client.update_security_group(sg_id, description=sg_desc)
self.assertEqual(sg_desc, sg_show['security_group'].get('description'))
self.delete_security_group(sg_client, sg_id)
sg_list = sg_client.list_security_groups(id=sg_id)
sg_list = sg_list.get('security_groups', sg_list)
self.assertEqual(len(sg_list), 0)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('6e48a2ed-8035-4986-a5c6-903c49ae26a2')
def test_admin_can_create_provider_security_group_for_tenant(self):
project_id = self.cmgr_alt.networks_client.tenant_id
sg = self.create_security_provider_group(self.cmgr_adm,
project_id=project_id,
provider=True)
self.assertEqual(True, sg.get('provider'))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('95ce76a4-a125-411b-95d7-7a66addf0efc')
def test_tenant_provider_sec_group_with_no_rules(self):
sg = self.create_security_provider_group(self.cmgr_adm,
provider=True)
self.assertEmpty(sg.get('security_group_rules'))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('5e6237ca-033a-4bee-b5fb-8f225ed00b0c')
def test_admin_can_create_security_group_rule(self):
sg_client = self.cmgr_adm.security_groups_client
sg = self.create_security_provider_group(self.cmgr_adm,
provider=True)
sg_id = sg.get('id')
self.create_security_group_rule(sg_id, cmgr=self.cmgr_adm,
protocol='icmp')
show_sec_group = sg_client.show_security_group(sg_id)
self.assertEqual('ingress',
show_sec_group['security_group']
['security_group_rules']
[0]['direction'])
self.assertEqual('icmp',
show_sec_group['security_group']
['security_group_rules']
[0]['protocol'])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('18737e13-4bca-4f62-b993-f021795a7dbf')
def test_provider_security_group_rule_at_beckend(self):
sg = self.create_security_provider_group(self.cmgr_adm, provider=True)
sg_id = sg.get('id')
sg_name = sg.get('name')
sg_rule = self.create_security_group_rule(sg_id, cmgr=self.cmgr_adm,
protocol='icmp')
sg_rule.get('id')
firewall_section = self.vsm.get_firewall()
for i in (0, len(firewall_section)):
if (sg_name in firewall_section['layer3Sections']
['layer3Sections'][i]['name']):
for rule in firewall_section.\
get('layer3Sections')['layer3Sections'][i]['rules']:
for rule_proto in rule['services']['serviceList']:
self.assertIn('ICMP', rule_proto['protocolName'])
self.assertIn('deny', rule['action'], "Provider "
"security Group applied")
@decorators.attr(type='nsxv')
@decorators.idempotent_id('b179a32b-e012-43ec-9d2d-f9e5801c97c6')
def test_provider_security_group_predence_at_beckend(self):
sg = self.create_security_provider_group(self.cmgr_adm, provider=True)
sg_name = sg.get('name')
firewall_section = self.vsm.get_firewall()
count = 0
for i in (0, len(firewall_section)):
if (count == 0):
self.assertIn(sg_name, firewall_section['layer3Sections']
['layer3Sections'][i]['name'],
"Provider security Group applied at the beckend"
" and has higher predence over default sec "
"group")
self.assertEqual(0, count)
break
count += count
self.assertEqual(0, count)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('38b21ea8-7822-4b1a-b923-cd00fa57ca4d')
def test_provider_security_group_at_port_level(self):
sg = self.create_security_provider_group(self.cmgr_adm,
provider=True)
sg_id = sg.get('id')
net_client = self.cmgr_adm.networks_client
body = {'name': 'provider-network'}
network = net_client.create_network(**body)
body = {"network_id": network['network']['id'],
"allocation_pools": [{"start": "2.0.0.2",
"end": "2.0.0.254"}],
"ip_version": 4, "cidr": "2.0.0.0/24"}
subnet_client = self.cmgr_adm.subnets_client
subnet_client.create_subnet(**body)
body = {"network_id": network['network']['id'],
"admin_state_up": 'true'}
port_client = self.cmgr_adm.ports_client
port_id = port_client.create_port(**body)
ss = port_client.show_port(port_id['port']['id'])
self.assertEqual([sg_id], ss['port']['provider_security_groups'])
body = {"id": port_id}
port_client.delete_port(port_id['port']['id'])
net_client.delete_network(network['network']['id'])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('b1e904fb-a70a-400e-a757-d772aab152eb')
def test_provider_sec_group_with_multiple_rules(self):
project_id = self.cmgr_adm.networks_client.tenant_id
sg = self.create_security_provider_group(self.cmgr_adm,
project_id=project_id)
sg_rule1 = self.create_security_group_rule(sg.get('id'),
cmgr=self.cmgr_adm,
project_id=project_id,
protocol='icmp')
sg_rule1_id = sg_rule1.get('id')
sg_rule2 = self.create_security_group_rule(sg.get('id'),
cmgr=self.cmgr_adm,
project_id=project_id,
protocol='tcp')
sg_rule2_id = sg_rule2.get('id')
self.assertNotEqual(sg_rule1_id, sg_rule2_id)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('edd94f8c-53b7-4286-9350-0ddc0af3213b')
def test_clear_provider_sec_group_from_port(self):
project_id = self.cmgr_adm.networks_client.tenant_id
self.create_security_provider_group(self.cmgr_adm,
project_id=project_id,
provider=True)
net_client = self.cmgr_adm.networks_client
body = {'name': 'provider-network'}
network = net_client.create_network(**body)
body = {"network_id": network['network']['id'],
"allocation_pools": [{"start": "2.0.0.2",
"end": "2.0.0.254"}],
"ip_version": 4, "cidr": "2.0.0.0/24"}
subnet_client = self.cmgr_adm.subnets_client
subnet_client.create_subnet(**body)
body = {"network_id": network['network']['id'],
"provider_security_groups": []}
port_client = self.cmgr_adm.ports_client
port_id = port_client.create_port(**body)
ss = port_client.show_port(port_id['port']['id'])
self.assertEmpty(ss['port']['provider_security_groups'])
port_client.delete_port(port_id['port']['id'])
net_client.delete_network(network['network']['id'])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('6c1e6728-b84a-47f9-9021-ff3e3f88a933')
def test_tenant_cannot_delete_admin_provider_security_group(self):
project_id = self.cmgr_adm.networks_client.tenant_id
sg = self.create_security_provider_group(self.cmgr_adm,
project_id=project_id,
provider=True)
sg_id = sg.get('id')
sg_client = self.cmgr_alt.security_groups_client
try:
self.delete_security_group(sg_client, sg_id)
except Exception:
LOG.debug("Non Admin tenant can't see admin"
"provider security group")
pass
@decorators.attr(type='nsxv')
@decorators.idempotent_id('94e06ee2-82ed-4203-ac9b-421a298bdba4')
def test_tenant_cannot_create_provider_sec_group(self):
project_id = self.cmgr_alt.networks_client.tenant_id
self.assertRaises(exceptions.Forbidden,
self.create_security_provider_group,
self.cmgr_alt, project_id=project_id,
provider=True)
LOG.debug("Non-Admin Tenant cannot create provider sec group")
@decorators.attr(type='nsxv')
@decorators.idempotent_id('01f00a36-7576-40e0-a397-b43860a9c122')
def test_update_port_with_psg(self):
net_client = self.cmgr_adm.networks_client
body = {'name': 'provider-network'}
network = net_client.create_network(**body)
body = {"network_id": network['network']['id'],
"allocation_pools": [{"start": "2.0.0.2",
"end": "2.0.0.254"}],
"ip_version": 4, "cidr": "2.0.0.0/24"}
subnet_client = self.cmgr_adm.subnets_client
subnet_client.create_subnet(**body)
body = {"network_id": network['network']['id'],
"provider_security_groups": []}
port_client = self.cmgr_adm.ports_client
port_id = port_client.create_port(**body)
ss = port_client.show_port(port_id['port']['id'])
self.assertEmpty(ss['port']['provider_security_groups'])
project_id = self.cmgr_adm.networks_client.tenant_id
sg = self.create_security_provider_group(self.cmgr_adm,
project_id=project_id,
provider=True)
sg_id = sg.get('id')
body = {"provider_security_groups": ["%s" % sg_id]}
port_client.update_port(port_id['port']['id'], **body)
ss = port_client.show_port(port_id['port']['id'])
self.assertIsNotNone(ss['port']['provider_security_groups'])
port_client.delete_port(port_id['port']['id'])
net_client.delete_network(network['network']['id'])

View File

@ -1,206 +0,0 @@
# 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 time
from oslo_log import log as logging
from tempest.api.network import base
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib.services import network as net_clients
from tempest import test
from vmware_nsx_tempest.services import nsxv_client
CONF = config.CONF
LOG = logging.getLogger(__name__)
ROUTER_SIZE = ('compact', 'large', 'xlarge', 'quadlarge')
class RouterSizeBaseTest(base.BaseAdminNetworkTest):
"""Base class to test creating routers with different router sizes:
NSX-v allows exclusive router to be created with one of ROUTER_SIZE.
Starts with VIO-3.0 it can update its router_size after created.
tempest internally uses urllib3 and by default it will retry very 60
seconds. However this retry mechanism causes bug#1716696.
A better solution is to change request's retry-time so it will not
cause neutront keep creating routers while router was not created
in time.
Methods should be used to change retry-time are:
create_exclusive_router & change_router_size
The retry-time is http_timeout in request.__init__() and is
defined by CONF.nsxv.create_router_http_timeout.
"""
@classmethod
def skip_checks(cls):
super(RouterSizeBaseTest, cls).skip_checks()
if not test.is_extension_enabled('nsxv-router-type', 'network'):
msg = "router-type extension is not enabled"
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(RouterSizeBaseTest, cls).setup_clients()
@classmethod
def resource_setup(cls):
super(RouterSizeBaseTest, cls).resource_setup()
cls.tenant_cidr = (CONF.network.project_network_cidr
if cls._ip_version == 4 else
CONF.network.project_network_v6_cidr)
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 setUp(self):
super(RouterSizeBaseTest, self).setUp()
params = {'build_interval': self.routers_client.build_interval,
'build_timeout': self.routers_client.build_timeout}
http_timeout = CONF.nsxv.create_router_http_timeout
self.router_sizes_client = net_clients.RoutersClient(
self.routers_client.auth_provider,
self.routers_client.service,
self.routers_client.region,
self.routers_client.endpoint_type,
http_timeout=http_timeout,
**params)
def create_exclusive_router(self, router_size):
name = data_utils.rand_name('rtr1-%s' % router_size)
LOG.debug("create router with size=%s", router_size)
ext_gw_info = dict(
network_id=CONF.network.public_network_id)
rtr_cfg = dict(
name=name, admin_state_up=False,
external_gateway_info=ext_gw_info,
router_type='exclusive',
router_size=router_size)
router = self.router_sizes_client.create_router(**rtr_cfg)
router = router.get('router', router)
self.routers.append(router)
self.assertEqual(router['name'], name)
self.check_router_nsx_name(router, router_size)
return router
def change_router_size(self, router, new_router_size):
LOG.debug("update router to size=%s", new_router_size)
update_router = self.router_sizes_client.update_router(
router['id'], router_size=new_router_size)['router']
self.assertEqual(update_router['router_size'], new_router_size)
self.check_router_nsx_name(update_router, new_router_size)
return router
def check_router_nsx_name(self, router, router_size=None):
router_nsxv_name = self.get_router_nsx_name(router)
exc_edge = self.vsm.get_edge(router_nsxv_name)
self.assertTrue(exc_edge is not None)
self.assertEqual(exc_edge['edgeType'], 'gatewayServices')
if router_size:
edge_type = exc_edge['appliancesSummary']['applianceSize']
LOG.debug("check router size at backend is %s", router_size)
self.assertEqual(edge_type, router_size)
return router_nsxv_name
def get_router_nsx_name(self, router):
router_nsxv_name = '%s-%s' % (router['name'], router['id'])
return router_nsxv_name
def do_create_update_delete_router_with_size(self,
router_size,
del_waitfor=10.0,
del_interval=1.5):
router = self.create_exclusive_router(router_size)
updated_name = 'updated-' + router['name']
update_router = self.router_sizes_client.update_router(
router['id'], name=updated_name)['router']
self.assertEqual(update_router['name'], updated_name)
# change router name, the backend also change
router = self.router_sizes_client.show_router(
router['id'])['router']
nsxv_edge_name = self.check_router_nsx_name(router, router_size)
# Delete the exclusive router and verify it has been deleted
# from nsxv backend
self.router_sizes_client.delete_router(router['id'])
list_body = self.router_sizes_client.list_routers()
routers_list = [r['id'] for r in list_body['routers']]
self.assertNotIn(router['id'], routers_list)
wait_till = time.time() + del_waitfor
while (time.time() < wait_till):
try:
self.assertIsNone(self.vsm.get_edge(nsxv_edge_name))
return
except Exception:
time.sleep(del_interval)
# last try. Fail if nesx_edge still exists
fail_msg = ("%s router nsxv_edge[%s] still exists after %s seconds." %
(router_size, nsxv_edge_name, del_waitfor))
self.assertEqual(self.vsm.get_edge(nsxv_edge_name), None, fail_msg)
def do_router_size_change_test(self, router_size, new_router_size_list):
router = self.create_exclusive_router(router_size)
for new_router_size in new_router_size_list:
self.change_router_size(router, new_router_size)
class CompactRouterTest(RouterSizeBaseTest):
@decorators.attr(type='nsxv')
@decorators.idempotent_id('d75fbcd5-c8cb-49ea-a868-ada12fd8c87f')
def test_create_update_delete_compact_router(self):
self.do_create_update_delete_router_with_size('compact')
class LargeRouterTest(RouterSizeBaseTest):
@decorators.attr(type='nsxv')
@decorators.idempotent_id('da00c74f-81e6-4ef9-8aca-8e0345b376e9')
def test_create_update_delete_large_router(self):
self.do_create_update_delete_router_with_size('large', 20.0)
class XlargeRouterTest(RouterSizeBaseTest):
@decorators.attr(type='nsxv')
@decorators.idempotent_id('091dad07-6044-4ca3-b16c-54a3ef92254b')
def test_create_update_delete_xlarge_router(self):
self.do_create_update_delete_router_with_size('xlarge', 20.0)
class QuadlargeRouterTest(RouterSizeBaseTest):
@decorators.attr(type='nsxv')
@decorators.idempotent_id('0f69bf8a-4b06-47ac-a3f7-eedba95fd395')
def test_create_update_delete_quadlarge_router(self):
self.do_create_update_delete_router_with_size('quadlarge', 30.0)
class RouterSizeChangeTest(RouterSizeBaseTest):
@decorators.idempotent_id('3201b0a9-702c-46cf-8512-f166a6ea5109')
def test_router_size_1sizeup_change(self):
self.do_router_size_change_test(
'compact',
('large', 'xlarge', 'quadlarge'))
@decorators.idempotent_id('c7ee9f78-4938-4bdd-b39c-1d736d41a84b')
def test_router_size_outofseq_change(self):
self.do_router_size_change_test(
"large",
('quadlarge', 'compact', 'xlarge', 'large'))

View File

@ -1,151 +0,0 @@
# Copyright 2015 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
from tempest.api.network import base
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.services import nsxv_client
CONF = config.CONF
class ExcRouterTest(base.BaseAdminNetworkTest):
"""
Test class for exclusive router type, which is 1:1 mapping of
NSX-v service edge. Tests will skipped if the router-type
extension is not enabled.
"""
@classmethod
def skip_checks(cls):
super(ExcRouterTest, cls).skip_checks()
if not test.is_extension_enabled('nsxv-router-type', 'network'):
msg = "router-type extension is not enabled"
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(ExcRouterTest, cls).setup_clients()
@classmethod
def resource_setup(cls):
super(ExcRouterTest, cls).resource_setup()
cls.tenant_cidr = (CONF.network.project_network_cidr
if cls._ip_version == 4 else
CONF.network.project_network_v6_cidr)
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 _delete_router(self, router):
body = self.ports_client.list_ports(device_id=router['id'])
interfaces = body['ports']
for interface in interfaces:
test_utils.call_and_ignore_notfound_exc(
self.routers_client.remove_router_interface, router['id'],
subnet_id=interface['fixed_ips'][0]['subnet_id'])
self.routers_client.delete_router(router['id'])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('ac1639a0-2a8d-4c68-bccd-54849fd45f86')
def test_create_exc_router(self):
"""
Test create an exclusive router. After creation, check nsx_v
backend create service for the exclusive router.
"""
name = data_utils.rand_name('router-')
router = self.routers_client.create_router(
name=name, external_gateway_info={
"network_id": CONF.network.public_network_id},
admin_state_up=False, router_type='exclusive')
self.addCleanup(self._delete_router, router['router'])
router_nsxv_name = '%s-%s' % (router['router']['name'],
router['router']['id'])
self.assertEqual(router['router']['name'], name)
exc_edge = self.vsm.get_edge(router_nsxv_name)
self.assertTrue(exc_edge is not None)
self.assertEqual(exc_edge['edgeType'], 'gatewayServices')
@decorators.attr(type='nsxv')
@decorators.idempotent_id('c4b94988-0bc7-11e5-9203-0050568833db')
def test_update_exc_router(self):
"""
Test update an exclusive router
"""
name = data_utils.rand_name('router-')
router = self.routers_client.create_router(
name=name, external_gateway_info={
"network_id": CONF.network.public_network_id},
admin_state_up=False, router_type='exclusive')
self.addCleanup(self._delete_router, router['router'])
self.assertEqual(router['router']['name'], name)
updated_name = 'updated' + name
update_body = self.routers_client.update_router(
router['router']['id'], name=updated_name)
self.assertEqual(update_body['router']['name'], updated_name)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('a0ff5afa-0bcc-11e5-9203-0050568833db')
def test_list_show_exc_router(self):
"""
Test list and show exclusive router.
"""
name = data_utils.rand_name('router-')
router = self.routers_client.create_router(
name=name, external_gateway_info={
"network_id": CONF.network.public_network_id},
admin_state_up=False, router_type='exclusive')
self.addCleanup(self._delete_router, router['router'])
self.assertEqual(router['router']['name'], name)
# Show details of exclusive router
show_body = self.routers_client.show_router(router['router']['id'])
self.assertEqual(show_body['router']['name'], name)
self.assertEqual(show_body['router']['admin_state_up'], False)
# List routers and verify if created router in list
list_body = self.routers_client.list_routers()
routers_list = [r['id'] for r in list_body['routers']]
self.assertIn(router['router']['id'], routers_list)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('adef8d1e-0bce-11e5-9203-0050568833db')
def test_delete_exc_router(self):
"""
Test create, update, and delete an exclusive router
"""
name = data_utils.rand_name('router-')
router = self.routers_client.create_router(
name=name, external_gateway_info={
"network_id": CONF.network.public_network_id},
admin_state_up=False, router_type='exclusive')
self.assertEqual(router['router']['name'], name)
# Update the name of the exclusive router
updated_name = 'updated' + name
update_body = self.routers_client.update_router(
router['router']['id'], name=updated_name)
self.assertEqual(update_body['router']['name'], updated_name)
# Delete the exclusive router and verify it has been deleted
# from nsxv backend
self.routers_client.delete_router(router['router']['id'])
list_body = self.routers_client.list_routers()
routers_list = [r['id'] for r in list_body['routers']]
self.assertNotIn(router['router']['id'], routers_list)
nsxv_edge_name = "%s-%s" % (name, router['router']['id'])
self.assertIsNone(self.vsm.get_edge(nsxv_edge_name))

View File

@ -1,263 +0,0 @@
# Copyright 2015 GlobalLogic. 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 oslo_log import log as logging
from tempest.api.network import base
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.lib import exceptions as lib_exc
from tempest import test
LOG = logging.getLogger(__name__)
CONF = config.CONF
class SubnetPoolsTestJSON(base.BaseNetworkTest):
"""Tests the following operations in the subnetpools API:
1. Create, update, delete list and show subnet pool.
2. Check shared subnetpool created by admin only.
3. Check no-admin tenant can't delete shared pool created by admin.
4. Create subentpool with quota limit for subnet and check subnet
exhaust.
5. Create subnets from subnetpool till the time no more ip left in
subnetpool.
v2.0 of the Neutron API is assumed. It is assumed that subnet_allocation
options mentioned in the [network-feature-enabled] section and
default_network option mentioned in the [network] section of
etc/tempest.conf:
"""
@classmethod
def skip_checks(cls):
super(SubnetPoolsTestJSON, cls).skip_checks()
if not test.is_extension_enabled('subnet_allocation', 'network'):
msg = "subnet_allocation extension not enabled."
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(SubnetPoolsTestJSON, cls).setup_clients()
cls.cmgr_pri = cls.get_client_manager('primary')
cls.cmgr_alt = cls.get_client_manager('alt')
cls.cmgr_adm = cls.get_client_manager('admin')
def clean_subnet(self, subnet_client, subnet_id):
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
subnet_client.delete_subnet,
subnet_id)
def _create_subnet_pool(self, client, name, default_quota=None,
shared='false'):
# create subnet pool
prefix = CONF.network.default_network
subnetpool_client = client.subnetpools_client
if default_quota is None:
body = subnetpool_client.create_subnetpool(name=name,
prefixes=prefix,
shared=shared)
else:
body = subnetpool_client.create_subnetpool(
name=name, prefixes=prefix, shared=shared,
default_quota=default_quota)
subnetpool_id = body["subnetpool"]["id"]
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
subnetpool_client.delete_subnetpool,
subnetpool_id)
return body
def _create_network_topo(self, subnetpool_id, prefixlen=26):
net_client = self.cmgr_adm.networks_client
body = {'name': 'provider-network'}
network = net_client.create_network(**body)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
net_client.delete_network,
network['network']['id'])
body = {"network_id": network['network']['id'],
"ip_version": 4, "subnetpool_id": subnetpool_id,
"prefixlen": 28}
subnet_client = self.cmgr_adm.subnets_client
subnet = subnet_client.create_subnet(**body)
self.clean_subnet(subnet_client, subnet['subnet']['id'])
network_topo = dict(network=network, subnet=subnet)
return network_topo
@decorators.idempotent_id('b39c237a-a1e8-4372-8f97-7fc9ff3660e3')
def test_subnetpools_crud_operations(self):
# create subnet pool
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name)
subnetpool_client = self.cmgr_adm.subnetpools_client
subnetpool_id = body["subnetpool"]["id"]
self.assertEqual(subnetpool_name, body["subnetpool"]["name"])
# get detail about subnet pool
body = subnetpool_client.show_subnetpool(subnetpool_id)
self.assertEqual(subnetpool_name, body["subnetpool"]["name"])
# update the subnet pool
subnetpool_name = data_utils.rand_name('subnetpools_update')
body = subnetpool_client.update_subnetpool(subnetpool_id,
name=subnetpool_name)
self.assertEqual(subnetpool_name, body["subnetpool"]["name"])
# delete subnet pool
body = subnetpool_client.delete_subnetpool(subnetpool_id)
self.assertRaises(lib_exc.NotFound,
subnetpool_client.show_subnetpool,
subnetpool_id)
@decorators.idempotent_id('de7b8aa9-0a94-4159-b3b8-4d41ae8348b1')
def test_subnetpools_shared_operations(self):
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name,
shared='true')
subnetpool_id = body["subnetpool"]["id"]
self.assertEqual(subnetpool_name, body["subnetpool"]["name"])
# get detail about subnet pool
subnetpool_alt_client = self.cmgr_alt.subnetpools_client
body = subnetpool_alt_client.show_subnetpool(subnetpool_id)
self.assertIn(subnetpool_id, body['subnetpool']['id'])
body = self._create_subnet_pool(self.cmgr_alt, subnetpool_name,
shared='false')
subnetpool_alt_id = body["subnetpool"]["id"]
subnetpool_pri_client = self.cmgr_pri.subnetpools_client
self.assertRaises(lib_exc.NotFound,
subnetpool_pri_client.show_subnetpool,
subnetpool_alt_id)
@decorators.idempotent_id('7eaf09a1-c0d4-403d-b6ef-f9d173b61219')
def test_shared_subnetpool_created_by_admin_only(self):
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name,
shared='true')
self.assertEqual(subnetpool_name, body["subnetpool"]["name"])
# get detail about subnet pool
subnetpool_alt_client = self.cmgr_alt.subnetpools_client
prefix = CONF.network.default_network
# PolicyNotAuthorized disallowed by policy
self.assertRaises(lib_exc.Forbidden,
subnetpool_alt_client.create_subnetpool,
name=subnetpool_name, prefixes=prefix,
shared='true')
@decorators.idempotent_id('99c3f9dc-64e2-4868-bfed-0838345e4684')
def test_shared_subnetpool_not_deleted_by_non_admin(self):
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name,
shared='true')
subnetpool_id = body["subnetpool"]["id"]
self.assertEqual(subnetpool_name, body["subnetpool"]["name"])
# get detail about subnet pool
subnetpool_alt_client = self.cmgr_alt.subnetpools_client
# PolicyNotAuthorized disallowed by policy
self.assertRaises(lib_exc.NotFound,
subnetpool_alt_client.delete_subnetpool,
subnetpool_id)
@decorators.idempotent_id('76988ed9-6eed-491c-89a5-ba4be430c7e2')
def test_subnetpools_with_quota_limit_subnets(self):
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name,
default_quota=70, shared='true')
subnetpool_id = body["subnetpool"]["id"]
network_topo = self._create_network_topo(subnetpool_id, prefixlen=28)
subnet_client = self.cmgr_adm.subnets_client
body = {"network_id": network_topo['network']['network']['id'],
"ip_version": 4, "subnetpool_id": subnetpool_id,
"prefixlen": 26, "enable_dhcp": 'false'}
# "Per-tenant subnet pool prefix quota exceeded"
self.assertRaises(lib_exc.Conflict,
subnet_client.create_subnet, **body)
@decorators.idempotent_id('bfc82211-20ae-4e3d-878d-f567bcefcec6')
def test_subnetpools_with_overlapping_subnets(self):
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name)
subnetpool_id = body["subnetpool"]["id"]
network_topo = self._create_network_topo(subnetpool_id, prefixlen=28)
subnet_client = self.cmgr_adm.subnets_client
body = {"network_id": network_topo['network']['network']['id'],
"ip_version": 4, "subnetpool_id": subnetpool_id,
"prefixlen": 28, "enable_dhcp": 'false'}
subnet = subnet_client.create_subnet(**body)
self.clean_subnet(subnet_client, subnet['subnet']['id'])
body = {"network_id": network_topo['network']['network']['id'],
"admin_state_up": 'true'}
port_client = self.cmgr_adm.ports_client
port_id = port_client.create_port(**body)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
port_client.delete_port,
port_id['port']['id'])
@decorators.idempotent_id('e6828de5-8b81-4e38-8c6f-5821ec75230f')
def test_multiple_subnets_from_multi_nets_under_same_pool(self):
# create subnet pool
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name)
subnetpool_id = body["subnetpool"]["id"]
# Create subnet1 , subnet2
self._create_network_topo(subnetpool_id, prefixlen=28)
self._create_network_topo(subnetpool_id, prefixlen=28)
@decorators.idempotent_id('7ecbc5c5-2c63-42e8-8120-3cf2c7e5b292')
def test_multiple_subnets_from_multi_pools_under_same_net(self):
# create subnetpool1
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name)
subnetpool_id = body["subnetpool"]["id"]
# create subnet1
network_topo = self._create_network_topo(subnetpool_id, prefixlen=28)
# create subnetpool2
subnet_client = self.cmgr_adm.subnets_client
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name)
subnetpool_id1 = body["subnetpool"]["id"]
body = {"network_id": network_topo['network']['network']['id'],
"ip_version": 4, "subnetpool_id": subnetpool_id1,
"prefixlen": 28, "enable_dhcp": 'false'}
# create subnet2
self.assertRaises(lib_exc.BadRequest,
subnet_client.create_subnet,
**body)
@decorators.idempotent_id('82412f8d-df29-4a23-b6c7-2c6d1035cf0b')
def test_subnetpools_with_overlapping_multi_subnets(self):
# create subnetpool1
subnetpool_name = data_utils.rand_name('subnetpools')
body = self._create_subnet_pool(self.cmgr_adm, subnetpool_name)
subnetpool_id = body["subnetpool"]["id"]
prefix = CONF.network.default_network
prefixlen = 26
# create network and subnet1
network_topo = self._create_network_topo(subnetpool_id,
prefixlen=prefixlen)
subnet_client = self.cmgr_adm.subnets_client
body = {"network_id": network_topo['network']['network']['id'],
"ip_version": 4, "subnetpool_id": subnetpool_id,
"prefixlen": prefixlen, "enable_dhcp": 'false'}
actual_netmask = int(prefix[0].split('/')[1])
no_of_ips = 2 ** (32 - actual_netmask)
no_of_ips_per_prefix = 2 ** (32 - prefixlen)
no_of_subnets = no_of_ips / no_of_ips_per_prefix
for subnet_num in range(1, no_of_subnets + 1):
try:
# create subnet2
subnet = subnet_client.create_subnet(**body)
self.clean_subnet(subnet_client, subnet['subnet']['id'])
except lib_exc.ServerFault:
pass
LOG.info("Failed to allocate subnet: Insufficient "
"prefix space to allocate subnet size")

View File

@ -1,496 +0,0 @@
# Copyright 2015 OpenStack Foundation
# 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 base_provider as base
from tempest.common import custom_matchers
from tempest import config
import netaddr
from oslo_log import log as logging
import six
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
CONF = config.CONF
LOG = logging.getLogger(__name__)
class SubnetTestJSON(base.BaseAdminNetworkTest):
_provider_network_body = {}
"""
[NOTE: This module copied/modified from api/network/test_networks.py
to create provider networks/subnets tests]
Tests the following operations in the Neutron API using the REST client for
Neutron:
create a network for a tenant
list tenant's networks
show a tenant network details
create a subnet for a tenant
list tenant's subnets
show a tenant subnet details
network update
subnet update
delete a network also deletes its subnets
All subnet tests are run once with ipv4 and once with ipv6.
v2.0 of the Neutron API is assumed. It is also assumed that the following
options are defined in the [network] section of etc/tempest.conf:
project_network_cidr with a block of cidr's from which smaller blocks
can be allocated for tenant ipv4 subnets
project_network_v6_cidr is the equivalent for ipv6 subnets
project_network_mask_bits with the mask bits to be used to partition
the block defined by project_network_cidr
project_network_v6_mask_bits is the equivalent for ipv6 subnets
"""
@classmethod
def resource_setup(cls):
super(SubnetTestJSON, cls).resource_setup()
for k, v in cls._provider_network_body.items():
if not v:
cls._provider_network_body.pop(k)
body = cls.create_network(client=cls.admin_networks_client,
**cls._provider_network_body)
cls.network = body['network']
cls.name = cls.network['name']
cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network)
cls.cidr = cls.subnet['cidr']
cls._subnet_data = {6: {'gateway':
str(cls._get_gateway_from_tempest_conf(6)),
'allocation_pools':
cls._get_allocation_pools_from_gateway(6),
'dns_nameservers': ['2001:4860:4860::8844',
'2001:4860:4860::8888'],
'host_routes': [{'destination': '2001::/64',
'nexthop': '2003::1'}],
'new_host_routes': [{'destination':
'2001::/64',
'nexthop': '2005::1'}],
'new_dns_nameservers':
['2001:4860:4860::7744',
'2001:4860:4860::7888']},
4: {'gateway':
str(cls._get_gateway_from_tempest_conf(4)),
'allocation_pools':
cls._get_allocation_pools_from_gateway(4),
'dns_nameservers': ['8.8.4.4', '8.8.8.8'],
'host_routes': [{'destination': '10.20.0.0/32',
'nexthop': '10.100.1.1'}],
'new_host_routes': [{'destination':
'10.20.0.0/32',
'nexthop':
'10.100.1.2'}],
'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
@classmethod
def _create_subnet_with_last_subnet_block(cls, network, ip_version=4):
"""Derive last subnet CIDR block from tenant CIDR and
create the subnet with that derived CIDR
"""
if ip_version == 4:
cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
mask_bits = CONF.network.project_network_mask_bits
elif ip_version == 6:
cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
mask_bits = CONF.network.project_network_v6_mask_bits
subnet_cidr = list(cidr.subnet(mask_bits))[-1]
gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
body = cls.create_subnet(network, gateway=gateway_ip,
cidr=subnet_cidr, mask_bits=mask_bits)
return body['subnet']
@classmethod
def _get_gateway_from_tempest_conf(cls, ip_version):
"""Return first subnet gateway for configured CIDR."""
if ip_version == 4:
cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
mask_bits = CONF.network.project_network_mask_bits
elif ip_version == 6:
cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
mask_bits = CONF.network.project_network_v6_mask_bits
if mask_bits >= cidr.prefixlen:
return netaddr.IPAddress(cidr) + 1
else:
for subnet in cidr.subnet(mask_bits):
return netaddr.IPAddress(subnet) + 1
@classmethod
def _get_allocation_pools_from_gateway(cls, ip_version):
"""Return allocation range for subnet of given gateway."""
gateway = cls._get_gateway_from_tempest_conf(ip_version)
return [{'start': str(gateway + 2), 'end': str(gateway + 3)}]
def subnet_dict(self, include_keys):
"""Return a subnet dict which has include_keys and their corresponding
value from self._subnet_data
"""
return dict((key, self._subnet_data[self._ip_version][key])
for key in include_keys)
def _create_network(self, _auto_clean_up=True, network_name=None,
**kwargs):
network_name = network_name or data_utils.rand_name('adm-netwk')
post_body = {'name': network_name}
post_body.update(kwargs)
LOG.debug("create ADM network: %s", str(post_body))
body = self.create_network(client=self.admin_networks_client,
**post_body)
network = body['network']
if _auto_clean_up:
self.addCleanup(self._try_delete_network, network['id'])
return network
# when you call _delete_network() you mean it is part of test,
# so we will not pass exception
def _delete_network(self, net_id):
self._remove_network_from_book(net_id)
return self.delete_network(net_id)
def _remove_network_from_book(self, net_id):
for idx, netwk_info in zip(range(0, len(self.admin_netwk_info)),
self.admin_netwk_info):
net_client, network = netwk_info
if network['id'] == net_id:
self.admin_netwk_info.pop(idx)
return
# call _try_delete_network() for teardown purpose, so pass exception
def _try_delete_network(self, net_id):
# delete network, if it exists
self._remove_network_from_book(net_id)
try:
self.delete_network(net_id)
# if network is not found, this means it was deleted in the test
except exceptions.NotFound:
pass
# by default, subnet will be deleted when its network is deleted
def _create_subnet(self, network, gateway='', cidr=None, mask_bits=None,
ip_version=None, cidr_offset=0,
_auto_clean_up=False, **kwargs):
body = self.create_subnet(network,
gateway=gateway,
cidr=cidr,
mask_bits=mask_bits,
ip_version=ip_version,
cidr_offset=cidr_offset,
**kwargs)
subnet = body['subnet']
if _auto_clean_up:
self.addCleanup(self._try_delete_subnet, subnet['id'])
return subnet
def _try_delete_subnet(self, net_id):
# delete subnet, if it exists
try:
self.delete_subnet(net_id)
# if network is not found, this means it was deleted in the test
except exceptions.NotFound:
pass
def _compare_resource_attrs(self, actual, expected):
exclude_keys = set(actual).symmetric_difference(expected)
self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
expected, exclude_keys))
def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
**kwargs):
network = self._create_network(_auto_clean_up=True)
net_id = network['id']
gateway = kwargs.pop('gateway', None)
subnet = self._create_subnet(network, gateway, cidr, mask_bits,
**kwargs)
compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
mask_bits=mask_bits, **kwargs)
compare_args = (dict((k, v)
for k, v in six.iteritems(compare_args_full)
if v is not None))
if 'dns_nameservers' in set(subnet).intersection(compare_args):
self.assertEqual(sorted(compare_args['dns_nameservers']),
sorted(subnet['dns_nameservers']))
del subnet['dns_nameservers'], compare_args['dns_nameservers']
self._compare_resource_attrs(subnet, compare_args)
self._delete_network(net_id)
@decorators.idempotent_id('2ecbc3ab-93dd-44bf-a827-95beeb008e9a')
def test_create_update_delete_network_subnet(self):
# Create a network
network = self._create_network(_auto_clean_up=True)
net_id = network['id']
self.assertEqual('ACTIVE', network['status'])
# Verify network update
new_name = data_utils.rand_name('new-adm-netwk')
body = self.update_network(net_id, name=new_name)
updated_net = body['network']
self.assertEqual(updated_net['name'], new_name)
# Find a cidr that is not in use yet and create a subnet with it
subnet = self._create_subnet(network)
subnet_id = subnet['id']
# Verify subnet update
new_name = data_utils.rand_name('new-subnet')
body = self.update_subnet(subnet_id, name=new_name)
updated_subnet = body['subnet']
self.assertEqual(updated_subnet['name'], new_name)
self._delete_network(net_id)
@decorators.idempotent_id('a2cf6398-aece-4256-88a6-0dfe8aa44975')
def test_show_network(self):
# Verify the details of a network
body = self.show_network(self.network['id'])
network = body['network']
for key in ['id', 'name']:
self.assertEqual(network[key], self.network[key])
@decorators.idempotent_id('5b42067d-4b9d-4f04-bb6a-adb9756ebe0c')
def test_show_network_fields(self):
# Verify specific fields of a network
fields = ['id', 'name']
body = self.show_network(self.network['id'], fields=fields)
network = body['network']
self.assertEqual(sorted(network.keys()), sorted(fields))
for field_name in fields:
self.assertEqual(network[field_name], self.network[field_name])
@decorators.idempotent_id('324be3c2-457d-4e21-b0b3-5106bbbf1a28')
def test_list_networks(self):
# Verify the network exists in the list of all networks
body = self.list_networks()
networks = [network['id'] for network in body['networks']
if network['id'] == self.network['id']]
self.assertNotEmpty(networks, "Created network not found in the list")
@decorators.idempotent_id('3a934a8d-6b52-427e-af49-3dfdd224fdeb')
def test_list_networks_fields(self):
# Verify specific fields of the networks
fields = ['id', 'name']
body = self.list_networks(fields=fields)
networks = body['networks']
self.assertNotEmpty(networks, "Network list returned is empty")
for network in networks:
self.assertEqual(sorted(network.keys()), sorted(fields))
@decorators.idempotent_id('5f6616c4-bfa7-4308-8eab-f45d75c94c6d')
def test_show_subnet(self):
# Verify the details of a subnet
body = self.show_subnet(self.subnet['id'])
subnet = body['subnet']
self.assertNotEmpty(subnet, "Subnet returned has no fields")
for key in ['id', 'cidr']:
self.assertIn(key, subnet)
self.assertEqual(subnet[key], self.subnet[key])
@decorators.idempotent_id('2f326955-551e-4e9e-a4f6-e5db77c34c8d')
def test_show_subnet_fields(self):
# Verify specific fields of a subnet
fields = ['id', 'network_id']
body = self.show_subnet(self.subnet['id'], fields=fields)
subnet = body['subnet']
self.assertEqual(sorted(subnet.keys()), sorted(fields))
for field_name in fields:
self.assertEqual(subnet[field_name], self.subnet[field_name])
@decorators.idempotent_id('66631557-2466-4827-bba6-d961b0242be3')
def test_list_subnets(self):
# Verify the subnet exists in the list of all subnets
body = self.list_subnets()
subnets = [subnet['id'] for subnet in body['subnets']
if subnet['id'] == self.subnet['id']]
self.assertNotEmpty(subnets, "Created subnet not found in the list")
@decorators.idempotent_id('3d5ea69b-f122-43e7-b7f4-c78586629eb8')
def test_list_subnets_fields(self):
# Verify specific fields of subnets
fields = ['id', 'network_id']
body = self.list_subnets(fields=fields)
subnets = body['subnets']
self.assertNotEmpty(subnets, "Subnet list returned is empty")
for subnet in subnets:
self.assertEqual(sorted(subnet.keys()), sorted(fields))
@decorators.idempotent_id('e966bb2f-402c-49b7-8147-b275cee584c4')
def test_delete_network_with_subnet(self):
# Creates a network
network = self._create_network(_auto_clean_up=True)
net_id = network['id']
# Find a cidr that is not in use yet and create a subnet with it
subnet = self._create_subnet(network)
subnet_id = subnet['id']
# Delete network while the subnet still exists
self._delete_network(net_id)
# Verify that the subnet got automatically deleted.
self.assertRaises(exceptions.NotFound,
self.show_subnet, subnet_id)
@decorators.idempotent_id('8aba0e1b-4b70-4181-a8a4-792c08db699d')
def test_create_delete_subnet_without_gateway(self):
self._create_verify_delete_subnet()
@decorators.idempotent_id('67364a4b-6725-4dbe-84cf-504bdb20ac06')
def test_create_delete_subnet_with_gw(self):
self._create_verify_delete_subnet(
**self.subnet_dict(['gateway']))
@decorators.idempotent_id('f8f43e65-5090-4902-b5d2-2b610505cca6')
def test_create_delete_subnet_with_allocation_pools(self):
self._create_verify_delete_subnet(
**self.subnet_dict(['allocation_pools']))
@decorators.idempotent_id('5b085669-97e6-48e0-b99e-315a9b4d8482')
def test_create_delete_subnet_with_gw_and_allocation_pools(self):
self._create_verify_delete_subnet(**self.subnet_dict(
['gateway', 'allocation_pools']))
@decorators.skip_because(bug="1501827")
@decorators.idempotent_id('3c4c36a1-684b-4e89-8e71-d528f19322a0')
def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
self._create_verify_delete_subnet(
**self.subnet_dict(['host_routes', 'dns_nameservers']))
@decorators.idempotent_id('df518c87-b817-48b5-9365-bd1daaf68955')
def test_create_delete_subnet_with_dns_nameservers(self):
self._create_verify_delete_subnet(
**self.subnet_dict(['dns_nameservers']))
@decorators.idempotent_id('b6822feb-6760-4052-b550-f0fe8bac7451')
def test_create_delete_subnet_with_dhcp_enabled(self):
self._create_verify_delete_subnet(enable_dhcp=True)
@decorators.skip_because(bug="1501827")
@decorators.idempotent_id('3c4c36a1-684a-4e89-8e71-d528f19324a0')
def test_update_subnet_gw_dns_host_routes_dhcp(self):
network = self._create_network(_auto_clean_up=True)
subnet_attrs = ['gateway', 'host_routes',
'dns_nameservers', 'allocation_pools']
subnet_dict = self.subnet_dict(subnet_attrs)
subnet = self._create_subnet(network, **subnet_dict)
subnet_id = subnet['id']
new_gateway = str(netaddr.IPAddress(
self._subnet_data[self._ip_version]['gateway']) + 1)
# Verify subnet update
new_host_routes = self._subnet_data[self._ip_version][
'new_host_routes']
new_dns_nameservers = self._subnet_data[self._ip_version][
'new_dns_nameservers']
kwargs = {'host_routes': new_host_routes,
'dns_nameservers': new_dns_nameservers,
'gateway_ip': new_gateway, 'enable_dhcp': True}
new_name = "New_subnet"
body = self.update_subnet(subnet_id, name=new_name, **kwargs)
updated_subnet = body['subnet']
kwargs['name'] = new_name
self.assertEqual(sorted(updated_subnet['dns_nameservers']),
sorted(kwargs['dns_nameservers']))
del subnet['dns_nameservers'], kwargs['dns_nameservers']
self._compare_resource_attrs(updated_subnet, kwargs)
self._delete_network(network['id'])
@decorators.idempotent_id('a5caa7d9-ab71-4278-a57c-d6631b7474f8')
def test_update_subnet_gw_dns_dhcp(self):
network = self._create_network(_auto_clean_up=True)
subnet_attrs = ['gateway',
'dns_nameservers', 'allocation_pools']
subnet_dict = self.subnet_dict(subnet_attrs)
subnet = self._create_subnet(network, **subnet_dict)
subnet_id = subnet['id']
new_gateway = str(netaddr.IPAddress(
self._subnet_data[self._ip_version]['gateway']) + 1)
# Verify subnet update
new_dns_nameservers = self._subnet_data[self._ip_version][
'new_dns_nameservers']
kwargs = {'dns_nameservers': new_dns_nameservers,
'gateway_ip': new_gateway, 'enable_dhcp': True}
new_name = "New_subnet"
body = self.update_subnet(subnet_id, name=new_name, **kwargs)
updated_subnet = body['subnet']
kwargs['name'] = new_name
self.assertEqual(sorted(updated_subnet['dns_nameservers']),
sorted(kwargs['dns_nameservers']))
del subnet['dns_nameservers'], kwargs['dns_nameservers']
self._compare_resource_attrs(updated_subnet, kwargs)
self._delete_network(network['id'])
@decorators.skip_because(bug="1501827")
@decorators.idempotent_id('a5caa7d5-ab71-4278-a57c-d6631b7474f8')
def test_create_delete_subnet_all_attributes(self):
self._create_verify_delete_subnet(
enable_dhcp=True,
**self.subnet_dict(['gateway',
'host_routes',
'dns_nameservers']))
@decorators.idempotent_id('a5caa7d9-ab71-4278-a57c-d6631b7474c8')
def test_create_delete_subnet_with_gw_dns(self):
self._create_verify_delete_subnet(
enable_dhcp=True,
**self.subnet_dict(['gateway',
'dns_nameservers']))
@decorators.idempotent_id('3c4c36a1-684b-4e89-8e71-d518f19324a0')
def test_add_upd_del_multiple_overlapping_networks_subnet(self):
r0, R1 = 0, 3 # (todo) get from CONF
return self._add_upd_del_multiple_networks_subnet(
r0, R1, "ovla-netwk")
@decorators.idempotent_id('5267bf9d-de82-4af9-914a-8320e9f4c38c')
def test_add_upd_del_multiple_nonoverlapping_networks_subnet(self):
r0, R1 = 1, 4 # (todo) get from CONF
return self._add_upd_del_multiple_networks_subnet(
r0, R1, "noov-netwk", _step_cidr=2)
def _add_upd_del_multiple_networks_subnet(self, r0, R1,
name_prefix="m-network",
_step_cidr=0):
m_name = data_utils.rand_name(name_prefix)
netwk = []
for x in range(r0, R1):
network = self._create_network(_auto_clean_up=True)
net_id = network['id']
self.assertEqual('ACTIVE', network['status'])
new_name = m_name + "-%02d" % x
body = self.update_network(net_id, name=new_name)
network = body['network']
cidr_offset = (x * _step_cidr) if _step_cidr > 0 else 0
subnet = self._create_subnet(network, cidr_offset=cidr_offset)
subnet_id = subnet['id']
netwk.append([x, net_id, subnet_id])
for x, net_id, subnet_id in netwk:
# make sure subnet is updatable after creation
new_name = m_name + "-%02d-snet" % x
body = self.update_subnet(subnet_id, name=new_name)
updated_subnet = body['subnet']
self.assertEqual(updated_subnet['name'], new_name)
self._delete_network(net_id)

View File

@ -1,264 +0,0 @@
# 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 os
import subprocess
import base_provider as base
from oslo_log import log as logging
import six
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
CONF = config.CONF
LOG = logging.getLogger(__name__)
class ProjectDeleteTest(base.BaseAdminNetworkTest):
"""Check Purge network resources using tenant-Id.
Validate that network resources which are not in use should get
deleted once neutron purge <tenant-id> is called.
"""
@classmethod
def skip_checks(cls):
super(ProjectDeleteTest, 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)
if not (CONF.auth.admin_username and CONF.auth.admin_password and
CONF.auth.admin_project_name):
msg = ('admin_username admin_password and admin_project_name\
should be provided in tempest.conf')
raise cls.skipException(msg)
process_obj = subprocess.Popen('neutron --version', shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
neutron_version = process_obj.stdout.readlines()
if neutron_version[0] < '4.1.2':
msg = ("Please update neutron verion,"
"run pip --upgrade pip and"
"pip install python-neutronclient upgrade")
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(ProjectDeleteTest, cls).setup_clients()
@classmethod
def resource_setup(cls):
super(ProjectDeleteTest, cls).resource_setup()
@classmethod
def create_tenant(self):
self.admin_manager.tenants_client
@classmethod
def create_network_subnet(self, cidr=None, cidr_offset=0):
network_name = data_utils.rand_name('project-network-')
resp = self.create_network(network_name)
network = resp.get('network', resp)
net_id = network['id']
resp = self.create_subnet(network,
name=network_name,
cidr=cidr,
cidr_offset=cidr_offset)
subnet = resp.get('subnet', resp)
resp = self.show_network(net_id)
s_network = resp.get('network', resp)
return (net_id, s_network, subnet)
def create_router_by_type(self, router_type, name=None, **kwargs):
routers_client = self.admin_manager.routers_client
router_name = name or data_utils.rand_name('mtz-')
create_kwargs = dict(name=router_name, 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
kwargs.update(create_kwargs)
router = routers_client.create_router(**kwargs)
router = router['router'] if 'router' in router else router
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
routers_client.delete_router, router['id'])
self.assertEqual(router['name'], router_name)
return (routers_client, router)
def create_router_and_add_interfaces(self, router_type, nets):
(routers_client, router) = self.create_router_by_type(router_type)
for net_id, (network, subnet) in six.iteritems(nets):
# register to cleanup before adding interfaces so interfaces
# and router can be deleted if test is aborted.
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
routers_client.remove_router_interface,
router['id'], subnet_id=subnet['id'])
routers_client.add_router_interface(
router['id'], subnet_id=subnet['id'])
return router
@decorators.idempotent_id('44e24f6b-9d9e-41a7-9d54-09d79b77dea5')
def test_project_delete_purge_using_non_admin(self):
nets = {}
net_id, network, subnet = self.create_network_subnet(cidr_offset=0)
nets[net_id] = (network, subnet)
router_type = 'shared'
self.create_router_and_add_interfaces(router_type, nets)
uri = CONF.identity.uri
os.environ['OS_AUTH_URL'] = uri
os.environ['OS_REGION_NAME'] = 'nova'
os.environ['OS_USERNAME'] = CONF.auth.admin_username
os.environ['OS_TENANT_NAME'] = CONF.auth.admin_project_name
os.environ['OS_PASSWORD'] = CONF.auth.admin_password
name = data_utils.rand_name('tenant-delete-')
tenant = self.admin_manager.tenants_client.create_tenant(name=name)
username = name + 'user'
kwargs = {'name': username, 'pass': 'password'}
tenant_user = self.admin_manager.users_client.create_user(**kwargs)
os.environ['OS_USERNAME'] = tenant_user['user']['username']
os.environ['OS_TENANT_NAME'] = tenant['tenant']['name']
os.environ['OS_PASSWORD'] = 'password'
local_tenant_id = network['tenant_id']
purge_output =\
os.popen('neutron --insecure purge %s --tenant-id=%s' %
(local_tenant_id,
tenant['tenant']['id'])).read().strip()
self.assertEqual(purge_output, '')
os.environ['OS_USERNAME'] = CONF.auth.admin_username
os.environ['OS_TENANT_NAME'] = CONF.auth.admin_project_name
os.environ['OS_PASSWORD'] = CONF.auth.admin_password
admin_tenant_id = os.popen(
"openstack --insecure project list | grep admin | awk '{print $2}'")\
.read()
purge_output =\
os.popen('neutron --insecure purge %s --tenant-id=%s' %
(local_tenant_id, admin_tenant_id)).read().strip()
self.assertIn('Purging resources: 100% complete', purge_output)
@decorators.idempotent_id('77ec7045-f8f0-4aa1-8e1d-68c0647fda89')
def test_project_delete_no_resource_for_deletion(self):
name = data_utils.rand_name('tenant-delete-')
network_client = self.admin_manager.networks_client
create_kwargs = dict(name=name)
network = network_client.create_network(**create_kwargs)
network_client.delete_network(network['network']['id'])
uri = CONF.identity.uri
os.environ['OS_AUTH_URL'] = uri
os.environ['OS_REGION_NAME'] = 'nova'
os.environ['OS_USERNAME'] = CONF.auth.admin_username
os.environ['OS_TENANT_NAME'] = CONF.auth.admin_project_name
os.environ['OS_PASSWORD'] = CONF.auth.admin_password
local_tenant_id = network['network']['tenant_id']
admin_tenant_id = os.popen(
"openstack --insecure project list | grep admin | awk '{print $2}'")\
.read()
purge_output =\
os.popen('neutron --insecure purge %s --tenant-id=%s' %
(local_tenant_id, admin_tenant_id)).read().strip()
purge_output =\
os.popen('neutron --insecure purge %s --tenant-id=%s' %
(local_tenant_id, admin_tenant_id)).read().strip()
LOG.debug("create VLAN network: %s", (purge_output))
check_output = 'Tenant has no supported resources'
self.assertIn(check_output, purge_output)
LOG.debug("Testcase run completed")
@decorators.idempotent_id('38bf4e22-c67a-42db-9e9d-a087369207d4')
def test_project_delete_with_all_resorces_deleted(self):
name = data_utils.rand_name('tenant-delete-')
security_client = self.admin_manager.security_groups_client
create_kwargs = dict(name=name)
sec_group = security_client.create_security_group(**create_kwargs)
network_name = name
resp = self.create_network(network_name)
network = resp.get('network', resp)
routers_client = self.admin_manager.routers_client
create_kwargs = dict(name=name)
router = routers_client.create_router(**create_kwargs)
floatingip_client = self.admin_manager.floating_ips_client
create_kwargs = {'floating_network_id': CONF.network.public_network_id}
floatingip = floatingip_client.create_floatingip(**create_kwargs)
uri = CONF.identity.uri
os.environ['OS_AUTH_URL'] = uri
os.environ['OS_REGION_NAME'] = 'nova'
os.environ['OS_USERNAME'] = CONF.auth.admin_username
os.environ['OS_TENANT_NAME'] = CONF.auth.admin_project_name
os.environ['OS_PASSWORD'] = CONF.auth.admin_password
self.admin_networks_client
local_tenant_id = network['tenant_id']
admin_tenant_id = os.popen(
"openstack --insecure project list | grep admin | awk '{print $2}'")\
.read()
purge_output =\
os.popen('neutron --insecure purge %s --tenant-id=%s' %
(local_tenant_id, admin_tenant_id)).read().strip()
LOG.debug("create VLAN network: %s", (purge_output))
check_output = ("Deleted 2 security_groups, 1 router, 1 network, "
"1 floatingip")
self.assertIn(check_output, purge_output)
list_of_sec_groups = security_client.list_security_groups()
self.assertNotIn(sec_group['security_group']['id'], list_of_sec_groups)
list_of_networks = self.admin_manager.networks_client.list_networks()
self.assertNotIn(network['id'], list_of_networks)
list_of_routers = routers_client.list_routers()
self.assertNotIn(router['router']['id'], list_of_routers)
list_of_floatingips = floatingip_client.list_floatingips()
self.assertNotIn(floatingip['floatingip']['id'], list_of_floatingips)
LOG.debug("Testcase run completed")
@decorators.idempotent_id('d617d637-5b2d-4ac8-93ce-80060d495bb2')
def test_project_delete_with_some_resources_left(self):
network_name = data_utils.rand_name('tenant-delete-')
resp = self.create_network(network_name)
network = resp.get('network', resp)
net_id = network['id']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_network, net_id)
resp = self.create_subnet(network,
name=network_name,
cidr=None,
cidr_offset=0)
subnet = resp.get('subnet', resp)
resp = self.show_network(net_id)
s_network = resp.get('network', resp)
net_subnets = s_network['subnets']
self.assertIn(subnet['id'], net_subnets)
uri = CONF.identity.uri
os.environ['OS_AUTH_URL'] = uri
os.environ['OS_REGION_NAME'] = 'nova'
os.environ['OS_USERNAME'] = CONF.auth.admin_username
os.environ['OS_TENANT_NAME'] = CONF.auth.admin_project_name
os.environ['OS_PASSWORD'] = CONF.auth.admin_password
self.admin_networks_client
local_tenant_id = network['tenant_id']
cmd = ("openstack --insecure project list |"
" grep admin | awk '{print $2}'")
admin_tenant_id = os.popen(cmd).read()
purge_output =\
os.popen('neutron --insecure purge %s --tenant-id=%s' %
(local_tenant_id, admin_tenant_id)).read().strip()
check_output = 'Deleted 1 security_group, 1 network'
self.assertIn(check_output, purge_output)
check_output = 'The following resources could not be deleted: 1 port'
self.assertIn(check_output, purge_output)
list_of_subnets = self.admin_manager.subnets_client.list_subnets()
self.assertNotIn(subnet['id'], list_of_subnets)
list_of_networks = self.admin_manager.networks_client.list_networks()
self.assertNotIn(network['id'], list_of_networks)
LOG.debug("create VLAN network: %s", (purge_output))

View File

@ -1,921 +0,0 @@
# Copyright 2014 NEC Corporation. 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 time
from neutron_lib import constants as nl_constants
import six
from tempest.api.network import base
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.lib import exceptions as lib_exc
from tempest import test
from vmware_nsx_tempest.common import constants
from vmware_nsx_tempest.services import fwaas_client as FWAASC
from vmware_nsx_tempest.services import nsxv_client
CONF = config.CONF
class FWaaSTestJSON(base.BaseNetworkTest):
"""
Tests the following operations in the Neutron API using the REST client for
Neutron:
CRUD firewall rules
CRUD firewall policies
CRUD firewall rules
Insert firewall rule to policy
Remove firewall rule from policy
Insert firewall rule after/before rule in policy
Update firewall policy audited attribute
Create exclusive router and attach to Firewall and check backend
Create distributed router and attach to Firewall and check backend
Create exclusive/distributed router and attach to Firewall and
check backend
"""
@classmethod
def resource_setup(cls):
super(FWaaSTestJSON, cls).resource_setup()
cls.fwaasv1_client = FWAASC.get_client(cls.manager)
if not test.is_extension_enabled('fwaas', 'network'):
msg = "FWaaS Extension not enabled."
raise cls.skipException(msg)
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.fw_rule = cls.fwaasv1_client.create_firewall_rule(action="allow",
protocol="tcp")
cls.fw_policy = cls.fwaasv1_client.create_firewall_policy()
def create_firewall_rule(self, **kwargs):
body = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
**kwargs)
fw_rule = body['firewall_rule']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.fwaasv1_client.delete_firewall_rule,
fw_rule['id'])
return fw_rule
def create_firewall_policy(self, **kwargs):
body = self.fwaasv1_client.create_firewall_policy(
name=data_utils.rand_name("fw-policy"),
**kwargs)
fw_policy = body['firewall_policy']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.fwaasv1_client.delete_firewall_policy,
fw_policy['id'])
return fw_policy
def delete_firewall_and_wait(self, firewall_id):
self.fwaasv1_client.delete_firewall(firewall_id)
self._wait_firewall_while(firewall_id, [nl_constants.PENDING_DELETE],
not_found_ok=True)
def create_firewall(self, **kwargs):
body = self.fwaasv1_client.create_firewall(
name=data_utils.rand_name("fw"),
**kwargs)
fw = body['firewall']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_firewall_and_wait,
fw['id'])
return fw
def _wait_firewall_while(self, firewall_id, statuses, not_found_ok=False):
start = int(time.time())
if not_found_ok:
expected_exceptions = (lib_exc.NotFound)
else:
expected_exceptions = ()
while True:
try:
fw = self.fwaasv1_client.show_firewall(firewall_id)
except expected_exceptions:
break
status = fw['firewall']['status']
if status not in statuses:
break
if int(time.time()) - start >= self.fwaasv1_client.build_timeout:
msg = ("Firewall %(firewall)s failed to reach "
"non PENDING status (current %(status)s)") % {
"firewall": firewall_id,
"status": status,
}
raise lib_exc.TimeoutException(msg)
time.sleep(constants.NSX_BACKEND_VERY_SMALL_TIME_INTERVAL)
def _wait_firewall_ready(self, firewall_id):
self._wait_firewall_while(firewall_id,
[nl_constants.PENDING_CREATE,
nl_constants.PENDING_UPDATE])
def _try_delete_router(self, router):
# delete router, if it exists
try:
self.delete_router(router)
# if router is not found, this means it was deleted in the test
except lib_exc.NotFound:
pass
def _try_delete_policy(self, policy_id):
# delete policy, if it exists
try:
self.fwaasv1_client.delete_firewall_policy(policy_id)
# if policy is not found, this means it was deleted in the test
except lib_exc.NotFound:
pass
def _try_delete_rule(self, rule_id):
# delete rule, if it exists
try:
self.fwaasv1_client.delete_firewall_rule(rule_id)
# if rule is not found, this means it was deleted in the test
except lib_exc.NotFound:
pass
def _try_delete_firewall(self, fw_id):
# delete firewall, if it exists
try:
self.fwaasv1_client.delete_firewall(fw_id)
# if firewall is not found, this means it was deleted in the test
except lib_exc.NotFound:
pass
self.fwaasv1_client.wait_for_resource_deletion(fw_id)
def _wait_until_ready(self, fw_id):
target_states = ('ACTIVE', 'CREATED')
def _wait():
firewall = self.fwaasv1_client.show_firewall(fw_id)
firewall = firewall['firewall']
return firewall['status'] in target_states
if not test_utils.call_until_true(_wait, CONF.network.build_timeout,
CONF.network.build_interval):
m = ("Timed out waiting for firewall %s to reach %s state(s)" %
(fw_id, target_states))
raise lib_exc.TimeoutException(m)
def _wait_until_deleted(self, fw_id):
def _wait():
try:
firewall = self.fwaasv1_client.show_firewall(fw_id)
except lib_exc.NotFound:
return True
fw_status = firewall['firewall']['status']
if fw_status == 'ERROR':
raise lib_exc.DeleteErrorException(resource_id=fw_id)
if not test_utils.call_until_true(_wait, CONF.network.build_timeout,
CONF.network.build_interval):
m = ("Timed out waiting for firewall %s deleted" % fw_id)
raise lib_exc.TimeoutException(m)
def _check_firewall_rule_exists_at_backend(self, rules,
firewall_rule_name):
for rule in rules:
if rule['name'] in firewall_rule_name:
self.assertIn(rule['name'], firewall_rule_name)
return True
return False
def _create_firewall_rule_name(self, body):
firewall_rule_name = body['firewall_rule']['name']
firewall_rule_name = "Fwaas-" + firewall_rule_name
return firewall_rule_name
def _create_firewall_advanced_topo(self, router_type):
fw_rule_id_list = []
router = self.create_router_by_type(router_type)
self.addCleanup(self._try_delete_router, router)
edges = self.vsm.get_all_edges()
for key in edges:
if router['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
rules_before = len(rules)
for rule_id in range(0, constants.NO_OF_ENTRIES):
if rule_id % 2 == 0:
action = "allow"
protocol = "tcp"
else:
action = "allow"
protocol = "udp"
firewall_rule = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action=action,
protocol=protocol)
fw_rule_id = firewall_rule['firewall_rule']['id']
firewall_name = self._create_firewall_rule_name(firewall_rule)
self.addCleanup(self._try_delete_rule, fw_rule_id)
fw_rule_id_list.append(fw_rule_id)
# Update firewall policy
body = self.fwaasv1_client.create_firewall_policy(
name=data_utils.rand_name("fw-policy"))
fw_policy_id = body['firewall_policy']['id']
self.addCleanup(self._try_delete_policy, fw_policy_id)
# Insert rule to firewall policy
for fw_rule_id in fw_rule_id_list:
self.fwaasv1_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id, '', '')
firewall_1 = self.fwaasv1_client.create_firewall(
name=data_utils.rand_name("firewall"),
firewall_policy_id=fw_policy_id,
router_ids=[router['id']])
created_firewall = firewall_1['firewall']
self.addCleanup(self._try_delete_firewall, created_firewall['id'])
# Wait for the firewall resource to become ready
self._wait_until_ready(created_firewall['id'])
firewall_topo = dict(router=router, firewall_name=firewall_name,
fw_policy_id=fw_policy_id,
firewall_id=created_firewall['id'],
rules_before=rules_before)
return firewall_topo
def _create_firewall_basic_topo(self, router_type, policy=None):
router = self.create_router_by_type(router_type)
self.addCleanup(self._try_delete_router, router)
body = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="tcp")
fw_rule_id1 = body['firewall_rule']['id']
firewall_name = self._create_firewall_rule_name(body)
self.addCleanup(self._try_delete_rule, fw_rule_id1)
# Create firewall policy
if not policy:
body = self.fwaasv1_client.create_firewall_policy(
name=data_utils.rand_name("fw-policy"))
fw_policy_id = body['firewall_policy']['id']
self.addCleanup(self._try_delete_policy, fw_policy_id)
# Insert rule to firewall policy
self.fwaasv1_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id1, '', '')
else:
fw_policy_id = policy
# Create firewall
firewall_1 = self.fwaasv1_client.create_firewall(
name=data_utils.rand_name("firewall"),
firewall_policy_id=fw_policy_id,
router_ids=[router['id']])
created_firewall = firewall_1['firewall']
self.addCleanup(self._try_delete_firewall, created_firewall['id'])
# Wait for the firewall resource to become ready
self._wait_until_ready(created_firewall['id'])
firewall_topo = dict(router=router, firewall_name=firewall_name,
fw_policy_id=fw_policy_id,
fw_rule_id1=fw_rule_id1,
firewall_id=created_firewall['id'])
return firewall_topo
def _get_list_fw_rule_ids(self, fw_policy_id):
fw_policy = self.fwaasv1_client.show_firewall_policy(
fw_policy_id)
return [ruleid for ruleid in fw_policy['firewall_policy']
['firewall_rules']]
def create_router_by_type(self, router_type, name=None, **kwargs):
routers_client = self.manager.routers_client
router_name = name or data_utils.rand_name('mtz-')
create_kwargs = dict(name=router_name, 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
kwargs.update(create_kwargs)
router = routers_client.create_router(**kwargs)
router = router['router'] if 'router' in router else router
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
routers_client.delete_router, router['id'])
self.assertEqual(router['name'], router_name)
return router
@decorators.attr(type='nsxv')
@decorators.idempotent_id('c72197f1-b5c6-453f-952e-007acea6df86')
def test_list_firewall_rules(self):
# List firewall rules
fw_rules = self.fwaasv1_client.list_firewall_rules()
fw_rules = fw_rules['firewall_rules']
self.assertEqual(self.fw_rule['firewall_rule']['id'],
fw_rules[0]['id'])
self.assertEqual(self.fw_rule['firewall_rule']['name'],
fw_rules[0]['name'])
self.assertEqual(self.fw_rule['firewall_rule']['action'],
fw_rules[0]['action'])
self.assertEqual(self.fw_rule['firewall_rule']['protocol'],
fw_rules[0]['protocol'])
self.assertEqual(self.fw_rule['firewall_rule']['enabled'],
fw_rules[0]['enabled'])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('ef92ba0d-f7c2-46cb-ad4b-21c62cfa85a0')
def test_create_update_delete_firewall_rule(self):
# Create firewall rule
body = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="tcp")
fw_rule_id = body['firewall_rule']['id']
self.addCleanup(self._try_delete_rule, fw_rule_id)
# Update firewall rule
body = self.fwaasv1_client.update_firewall_rule(fw_rule_id,
action="deny")
self.assertEqual("deny", body["firewall_rule"]['action'])
# Delete firewall rule
self.fwaasv1_client.delete_firewall_rule(fw_rule_id)
# Confirm deletion
fw_rules = self.fwaasv1_client.list_firewall_rules()
self.assertNotIn(fw_rule_id,
[m['id'] for m in fw_rules['firewall_rules']])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('264e8b67-a1ef-4ba1-8757-808b249a5320')
def test_show_firewall_rule(self):
# show a created firewall rule
fw_rule = self.fwaasv1_client.show_firewall_rule(
self.fw_rule['firewall_rule']['id'])
for key, value in six.iteritems(fw_rule['firewall_rule']):
self.assertEqual(self.fw_rule['firewall_rule'][key], value)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('029cd998-9dd4-4a0a-b79d-8bafd8223bda')
def test_list_firewall_policies(self):
fw_policies = self.fwaasv1_client.list_firewall_policies()
fw_policies = fw_policies['firewall_policies']
self.assertEqual(self.fw_policy['firewall_policy']['id'],
fw_policies[0]['id'])
self.assertEqual(self.fw_policy['firewall_policy']['name'],
fw_policies[0]['name'])
self.assertEqual(self.fw_policy['firewall_policy']['firewall_rules'],
fw_policies[0]['firewall_rules'])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('28c261c8-4fb3-4630-8a9b-707c93536a54')
def test_create_update_delete_firewall_policy(self):
# Create firewall policy
body = self.fwaasv1_client.create_firewall_policy(
name=data_utils.rand_name("fw-policy"))
fw_policy_id = body['firewall_policy']['id']
self.addCleanup(self._try_delete_policy, fw_policy_id)
# Update firewall policy
body = self.fwaasv1_client.update_firewall_policy(
fw_policy_id,
name="updated_policy")
updated_fw_policy = body["firewall_policy"]
self.assertEqual("updated_policy", updated_fw_policy['name'])
# Delete firewall policy
self.fwaasv1_client.delete_firewall_policy(fw_policy_id)
# Confirm deletion
fw_policies = self.fwaasv1_client.list_firewall_policies()
fw_policies = fw_policies['firewall_policies']
self.assertNotIn(fw_policy_id, [m['id'] for m in fw_policies])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('8bc7ad6d-4163-4def-9e1d-b9d24d9e8bf8')
def test_show_firewall_policy(self):
# show a created firewall policy
fw_policy = self.fwaasv1_client.show_firewall_policy(
self.fw_policy['firewall_policy']['id'])
fw_policy = fw_policy['firewall_policy']
for key, value in six.iteritems(fw_policy):
self.assertEqual(self.fw_policy['firewall_policy'][key], value)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('0c320840-f3e4-4960-987d-a6f06d327fe1')
def test_create_show_delete_firewall(self):
# Create tenant network resources required for an ACTIVE firewall
network = self.create_network()
subnet = self.create_subnet(network)
router = self.create_router_by_type('exclusive')
self.addCleanup(self._try_delete_router, router)
self.routers_client.add_router_interface(router['id'],
subnet_id=subnet['id'])
# Create firewall
body = self.fwaasv1_client.create_firewall(
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['firewall_policy']['id'])
created_firewall = body['firewall']
firewall_id = created_firewall['id']
self.addCleanup(self._try_delete_firewall, firewall_id)
# Wait for the firewall resource to become ready
self._wait_until_ready(firewall_id)
# show a created firewall
firewall = self.fwaasv1_client.show_firewall(firewall_id)
firewall = firewall['firewall']
for key, value in six.iteritems(firewall):
if key == 'status':
continue
self.assertEqual(created_firewall[key], value)
# list firewall
firewalls = self.fwaasv1_client.list_firewalls()
firewalls = firewalls['firewalls']
# Delete firewall
self.fwaasv1_client.delete_firewall(firewall_id)
# Wait for the firewall resource to be deleted
self._wait_until_deleted(firewall_id)
# Confirm deletion
firewalls = self.fwaasv1_client.list_firewalls()['firewalls']
self.assertNotIn(firewall_id, [m['id'] for m in firewalls])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('d9b23b3a-66ea-4591-9f8f-fa5a71fe0645')
def test_firewall_insertion_mode_add_remove_mix_router(self):
# Create legacy routers
router1 = self.create_router_by_type('exclusive')
self.addCleanup(self._try_delete_router, router1)
router2 = self.create_router_by_type('distributed')
self.addCleanup(self._try_delete_router, router2)
# Create firewall on a router1
body = self.fwaasv1_client.create_firewall(
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['firewall_policy']['id'],
router_ids=[router1['id']])
created_firewall = body['firewall']
firewall_id = created_firewall['id']
self.addCleanup(self._try_delete_firewall, firewall_id)
self.assertEqual([router1['id']], created_firewall['router_ids'])
# Legacy routers are scheduled on L3 agents on network plug events
# Hence firewall resource will not became ready at this stage
network = self.create_network()
subnet = self.create_subnet(network)
self.routers_client.add_router_interface(router1['id'],
subnet_id=subnet['id'])
# Wait for the firewall resource to become ready
self._wait_until_ready(firewall_id)
# Add router2 to the firewall
body = self.fwaasv1_client.update_firewall(
firewall_id, router_ids=[router1['id'], router2['id']])
updated_firewall = body['firewall']
self.assertIn(router2['id'], updated_firewall['router_ids'])
self.assertEqual(2, len(updated_firewall['router_ids']))
# Wait for the firewall resource to become ready
self._wait_until_ready(firewall_id)
# Remove router1 from the firewall
body = self.fwaasv1_client.update_firewall(
firewall_id, router_ids=[router2['id']])
updated_firewall = body['firewall']
self.assertNotIn(router1['id'], updated_firewall['router_ids'])
self.assertEqual(1, len(updated_firewall['router_ids']))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('964e0254-e7f2-4bbe-a4c8-db09da8d79ee')
def test_firewall_insertion_mode_add_remove_router(self):
# Create legacy routers
router1 = self.create_router_by_type('exclusive')
self.addCleanup(self._try_delete_router, router1)
router2 = self.create_router_by_type('exclusive')
self.addCleanup(self._try_delete_router, router2)
# Create firewall on a router1
body = self.fwaasv1_client.create_firewall(
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['firewall_policy']['id'],
router_ids=[router1['id']])
created_firewall = body['firewall']
firewall_id = created_firewall['id']
self.addCleanup(self._try_delete_firewall, firewall_id)
self.assertEqual([router1['id']], created_firewall['router_ids'])
# Legacy routers are scheduled on L3 agents on network plug events
# Hence firewall resource will not became ready at this stage
network = self.create_network()
subnet = self.create_subnet(network)
self.routers_client.add_router_interface(router1['id'],
subnet_id=subnet['id'])
# Wait for the firewall resource to become ready
self._wait_until_ready(firewall_id)
# Add router2 to the firewall
body = self.fwaasv1_client.update_firewall(
firewall_id, router_ids=[router1['id'], router2['id']])
updated_firewall = body['firewall']
self.assertIn(router2['id'], updated_firewall['router_ids'])
self.assertEqual(2, len(updated_firewall['router_ids']))
# Wait for the firewall resource to become ready
self._wait_until_ready(firewall_id)
# Remove router1 from the firewall
body = self.fwaasv1_client.update_firewall(
firewall_id, router_ids=[router2['id']])
updated_firewall = body['firewall']
self.assertNotIn(router1['id'], updated_firewall['router_ids'])
self.assertEqual(1, len(updated_firewall['router_ids']))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('662b252f-fa1b-49fe-8599-a37feab9fae8')
def test_firewall_insertion_one_policy_two_router_backend(self):
# Create router required for an ACTIVE firewall
edge_id_excl = 0
edge_id_dist = 0
firewall_topo1 = self._create_firewall_basic_topo('exclusive')
firewall_topo2 = \
self._create_firewall_basic_topo('distributed',
firewall_topo1['fw_policy_id'])
edges = self.vsm.get_all_edges()
firewall_topo2['router']['name'] += '-plr'
for key in edges:
if firewall_topo1['router']['name'] in key['name']:
edge_id_excl = key['id']
if firewall_topo2['router']['name'] in key['name']:
edge_id_dist = key['id']
if edge_id_excl and edge_id_dist:
break
rules = self.vsm.get_edge_firewall_rules(edge_id_excl)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo1['firewall_name']))
rules = self.vsm.get_edge_firewall_rules(edge_id_dist)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo1['firewall_name']))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('00330ef3-0a2e-4556-84d1-448d09c5ca2e')
def test_firewall_insertion_two_policy_two_router_backend(self):
# Create router required for an ACTIVE firewall
edge_id_excl = 0
edge_id_dist = 0
firewall_topo1 = self._create_firewall_basic_topo('exclusive')
firewall_topo2 = self._create_firewall_basic_topo('distributed')
edges = self.vsm.get_all_edges()
firewall_topo2['router']['name'] += '-plr'
for key in edges:
if firewall_topo1['router']['name'] in key['name']:
edge_id_excl = key['id']
if firewall_topo2['router']['name'] in key['name']:
edge_id_dist = key['id']
if edge_id_excl and edge_id_dist:
break
time.sleep(constants.NSX_BACKEND_SMALL_TIME_INTERVAL)
rules = self.vsm.get_edge_firewall_rules(edge_id_excl)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo1['firewall_name']))
time.sleep(constants.NSX_BACKEND_SMALL_TIME_INTERVAL)
rules = self.vsm.get_edge_firewall_rules(edge_id_dist)
time.sleep(constants.NSX_BACKEND_SMALL_TIME_INTERVAL)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo2['firewall_name']))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('8092bd48-e4c1-4709-8a3b-70e7bf6a78c9')
def test_firewall_insertion_mode_two_firewall_rules_check_backend(self):
rule_no = 1
# Create router required for an ACTIVE firewall
firewall_topo = self._create_firewall_basic_topo('exclusive')
# Create second firewall rule
firewall_rule_2 = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="deny",
protocol="icmp")
fw_rule_id2 = firewall_rule_2['firewall_rule']['id']
firewall_rule_name_2 = \
"Fwaas-" + firewall_rule_2['firewall_rule']['name']
self.addCleanup(self._try_delete_rule, fw_rule_id2)
self.addCleanup(self._try_delete_policy, firewall_topo['fw_policy_id'])
self.addCleanup(self._try_delete_firewall,
firewall_topo['firewall_id'])
# Insert rule-2 to firewall policy
self.fwaasv1_client.insert_firewall_rule_in_policy(
firewall_topo['fw_policy_id'], fw_rule_id2, '',
firewall_topo['fw_rule_id1'])
self._wait_firewall_ready(firewall_topo['firewall_id'])
edges = self.vsm.get_all_edges()
for key in edges:
if firewall_topo['router']['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
for rule in rules:
if rule['name'] in ('VSERule', 'MDServiceIP', 'MDInterEdgeNet'):
continue
if rule_no == 1:
self.assertIn(rule['name'], firewall_rule_name_2,
"Rule exists at position 1")
rule_no += rule_no
continue
if rule_no == 2:
self.assertIn(rule['name'], firewall_topo['firewall_name'],
"Rule exists at position 2")
break
@decorators.attr(type='nsxv')
@decorators.idempotent_id('da65de07-a60f-404d-ad1d-2d2c71a3b6a5')
def test_firewall_add_delete_between_routers(self):
firewall_topo = self._create_firewall_basic_topo('exclusive')
router = self.create_router_by_type('exclusive')
self.addCleanup(self._try_delete_router, router)
self.fwaasv1_client.update_firewall(
firewall_topo['firewall_id'],
router_ids=[router['id']])
self._wait_firewall_ready(firewall_topo['firewall_id'])
edges = self.vsm.get_all_edges()
for key in edges:
if router['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules,
firewall_topo['firewall_name']))
self.fwaasv1_client.update_firewall(
firewall_topo['firewall_id'],
router_ids=[router['id'], firewall_topo['router']['id']])
self._wait_firewall_ready(firewall_topo['firewall_id'])
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo['firewall_name']))
edges = self.vsm.get_all_edges()
for key in edges:
if firewall_topo['router']['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo['firewall_name']))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('c60ceff5-d51f-451d-b6e6-cb983d16ab6b')
def test_firewall_insertion_with_multiple_rules_check_backend(self):
# Create router required for an ACTIVE firewall
firewall_topo = self._create_firewall_basic_topo('exclusive')
edges = self.vsm.get_all_edges()
for key in edges:
if firewall_topo['router']['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo['firewall_name']))
firewall_rule_2 = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="tcp")
fw_rule_id2 = firewall_rule_2['firewall_rule']['id']
firewall_name_2 = self._create_firewall_rule_name(firewall_rule_2)
self.addCleanup(self._try_delete_rule, fw_rule_id2)
# Update firewall policy
self.fwaasv1_client.insert_firewall_rule_in_policy(
firewall_topo['fw_policy_id'], fw_rule_id2,
firewall_topo['fw_rule_id1'], '')
self._wait_firewall_ready(firewall_topo['firewall_id'])
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_name_2))
firewall_rule_3 = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="tcp")
fw_rule_id3 = firewall_rule_3['firewall_rule']['id']
firewall_name_3 = self._create_firewall_rule_name(firewall_rule_3)
self.addCleanup(self._try_delete_rule, fw_rule_id3)
# Update firewall policy
self.fwaasv1_client.insert_firewall_rule_in_policy(
firewall_topo['fw_policy_id'], fw_rule_id3, fw_rule_id2, '')
self._wait_firewall_ready(firewall_topo['firewall_id'])
self.addCleanup(self._try_delete_policy, firewall_topo['fw_policy_id'])
self.addCleanup(self._try_delete_firewall,
firewall_topo['firewall_id'])
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_name_3))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('a1734149-9c4b-46d3-86c8-d61f57458095')
def test_firewall_add_remove_rule_check_backend(self):
# Create router required for an ACTIVE firewall
firewall_topo = self._create_firewall_basic_topo('exclusive')
edges = self.vsm.get_all_edges()
for key in edges:
if firewall_topo['router']['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo['firewall_name']))
self.fwaasv1_client.remove_firewall_rule_from_policy(
firewall_topo['fw_policy_id'], firewall_topo['fw_rule_id1'])
self.delete_firewall_and_wait(firewall_topo['firewall_id'])
time.sleep(constants.NSX_BACKEND_SMALL_TIME_INTERVAL)
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
False, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo['firewall_name']))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('e1111959-c36a-41d6-86ee-ea6c0b927eb3')
def test_firewall_insertion_mode_one_firewall_rule_check_backend(self):
# Create router required for an ACTIVE firewall
firewall_topo = self._create_firewall_basic_topo('exclusive')
edges = self.vsm.get_all_edges()
for key in edges:
if firewall_topo['router']['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, firewall_topo['firewall_name']))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('e434b3c9-1148-499a-bb52-b094cdb0a186')
def test_firewall_insertion_mode_one_firewall_per_router(self):
# Create router required for an ACTIVE firewall
firewall_topo = self._create_firewall_basic_topo('exclusive')
# Try to create firewall with the same router
self.assertRaisesRegexp(
lib_exc.Conflict,
"already associated with other Firewall",
self.fwaasv1_client.create_firewall,
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['firewall_policy']['id'],
router_ids=[firewall_topo['router']['id']])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('d162abb2-9c14-45d6-bed1-06646a66803a')
def test_firewall_insertion_mode_one_firewall_per_dist_router(self):
# Create router required for an ACTIVE firewall
firewall_topo = self._create_firewall_basic_topo('distributed')
# Try to create firewall with the same router
self.assertRaisesRegexp(
lib_exc.Conflict,
"already associated with other Firewall",
self.fwaasv1_client.create_firewall,
name=data_utils.rand_name("firewall"),
firewall_policy_id=self.fw_policy['firewall_policy']['id'],
router_ids=[firewall_topo['router']['id']])
@decorators.attr(type='nsxv')
@decorators.idempotent_id('d5531558-9b18-40bc-9388-3eded0894a85')
def test_firewall_rule_insertion_position_removal_rule_from_policy(self):
# Create firewall rule
body = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="tcp")
fw_rule_id1 = body['firewall_rule']['id']
self.addCleanup(self._try_delete_rule, fw_rule_id1)
# Create firewall policy
body = self.fwaasv1_client.create_firewall_policy(
name=data_utils.rand_name("fw-policy"))
fw_policy_id = body['firewall_policy']['id']
self.addCleanup(self._try_delete_policy, fw_policy_id)
# Insert rule to firewall policy
self.fwaasv1_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id1, '', '')
# Verify insertion of rule in policy
self.assertIn(fw_rule_id1, self._get_list_fw_rule_ids(fw_policy_id))
# Create another firewall rule
body = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="icmp")
fw_rule_id2 = body['firewall_rule']['id']
self.addCleanup(self._try_delete_rule, fw_rule_id2)
# Insert rule to firewall policy after the first rule
self.fwaasv1_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id2, fw_rule_id1, '')
# Verify the position of rule after insertion
fw_rule = self.fwaasv1_client.show_firewall_rule(
fw_rule_id2)
self.assertEqual(int(fw_rule['firewall_rule']['position']), 2)
# Remove rule from the firewall policy
self.fwaasv1_client.remove_firewall_rule_from_policy(
fw_policy_id, fw_rule_id2)
# Insert rule to firewall policy before the first rule
self.fwaasv1_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id2, '', fw_rule_id1)
# Verify the position of rule after insertion
fw_rule = self.fwaasv1_client.show_firewall_rule(
fw_rule_id2)
self.assertEqual(int(fw_rule['firewall_rule']['position']), 1)
# Remove rule from the firewall policy
self.fwaasv1_client.remove_firewall_rule_from_policy(
fw_policy_id, fw_rule_id2)
# Verify removal of rule from firewall policy
self.assertNotIn(fw_rule_id2, self._get_list_fw_rule_ids(fw_policy_id))
# Remove rule from the firewall policy
self.fwaasv1_client.remove_firewall_rule_from_policy(
fw_policy_id, fw_rule_id1)
# Verify removal of rule from firewall policy
self.assertNotIn(fw_rule_id1, self._get_list_fw_rule_ids(fw_policy_id))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('901dae30-b148-43d9-ac86-09777aeaba20')
def test_update_firewall_name_at_backend_excl_edge(self):
firewall_topo = self._create_firewall_basic_topo('exclusive')
fw_rule_id = firewall_topo['fw_rule_id1']
body = self.fwaasv1_client.update_firewall_rule(fw_rule_id,
name="updated_rule")
updated_fw_rule = body["firewall_rule"]
self.assertEqual("updated_rule", updated_fw_rule['name'])
time.sleep(constants.NSX_FIREWALL_REALIZED_TIMEOUT)
edges = self.vsm.get_all_edges()
for key in edges:
if firewall_topo['router']['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
time.sleep(constants.NSX_BACKEND_VERY_SMALL_TIME_INTERVAL)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, "Fwaas-updated_rule"))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('471ebc13-8e3b-4aca-85b8-747935bf0559')
def test_update_firewall_name_at_backend_dist_edge(self):
firewall_topo = self._create_firewall_basic_topo('distributed')
fw_rule_id = firewall_topo['fw_rule_id1']
body = self.fwaasv1_client.update_firewall_rule(fw_rule_id,
name="updated_rule")
updated_fw_rule = body["firewall_rule"]
self.assertEqual("updated_rule", updated_fw_rule['name'])
time.sleep(constants.NSX_FIREWALL_REALIZED_TIMEOUT)
edges = self.vsm.get_all_edges()
firewall_topo['router']['name'] += '-plr'
for key in edges:
if firewall_topo['router']['name'] in key['name']:
edge_id = key['id']
break
rules = self.vsm.get_edge_firewall_rules(edge_id)
time.sleep(constants.NSX_BACKEND_VERY_SMALL_TIME_INTERVAL)
self.assertEqual(
True, self._check_firewall_rule_exists_at_backend(
rules, "Fwaas-updated_rule"))
@decorators.attr(type='nsxv')
@decorators.idempotent_id('0bdc9670-17b8-4dd5-80c8-dc6e956fc6ef')
def test_create_multiple_firewall_rules_check_at_backend(self):
firewall_topo = self._create_firewall_advanced_topo('exclusive')
edges = self.vsm.get_all_edges()
for key in edges:
if firewall_topo['router']['name'] in key['name']:
edge_id = key['id']
break
firewall_rules = self.vsm.get_edge_firewall_rules(edge_id)
total_rules = firewall_topo['rules_before'] + len(firewall_rules)
self.assertGreaterEqual(total_rules, constants.NO_OF_ENTRIES,
"Firewall Rules are greater than %s" %
constants.NO_OF_ENTRIES)
@decorators.attr(type='nsxv')
@decorators.idempotent_id('0249db39-6284-456a-9449-2adacdca4d3b')
def test_update_firewall_policy_audited_attribute(self):
# Create firewall rule
body = self.fwaasv1_client.create_firewall_rule(
name=data_utils.rand_name("fw-rule"),
action="allow",
protocol="icmp")
fw_rule_id = body['firewall_rule']['id']
self.addCleanup(self._try_delete_rule, fw_rule_id)
# Create firewall policy
body = self.fwaasv1_client.create_firewall_policy(
name=data_utils.rand_name('fw-policy'))
fw_policy_id = body['firewall_policy']['id']
self.addCleanup(self._try_delete_policy, fw_policy_id)
self.assertFalse(body['firewall_policy']['audited'])
# Update firewall policy audited attribute to true
self.fwaasv1_client.update_firewall_policy(fw_policy_id,
audited=True)
# Insert Firewall rule to firewall policy
self.fwaasv1_client.insert_firewall_rule_in_policy(
fw_policy_id, fw_rule_id, '', '')
body = self.fwaasv1_client.show_firewall_policy(
fw_policy_id)
self.assertFalse(body['firewall_policy']['audited'])

View File

@ -1,495 +0,0 @@
# Copyright 2013 OpenStack Foundation
# Copyright 2015 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 six
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.api.network import base
from tempest import config
from tempest import test
from vmware_nsx_tempest.services import load_balancer_v1_client as LBV1C
from vmware_nsx_tempest.services import network_client_base as base_client
CONF = config.CONF
class LoadBalancerTestJSON(base.BaseNetworkTest):
"""
Tests the following operations in the Neutron API using the REST client
for
Neutron:
create vIP, and Pool
show vIP
list vIP
update vIP
delete vIP
update pool
delete pool
show pool
list pool
health monitoring operations
"""
@classmethod
def skip_checks(cls):
super(LoadBalancerTestJSON, cls).skip_checks()
if not test.is_extension_enabled('lbaas', 'network'):
msg = "lbaas extension not enabled."
raise cls.skipException(msg)
if not test.is_extension_enabled('nsxv-router-type', 'network'):
msg = "nsxv-router-type extension is not enabled"
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
super(LoadBalancerTestJSON, cls).resource_setup()
_params = base_client.default_params_with_timeout_values.copy()
for p in _params.keys():
if p in ['service', 'region', 'endpoint_type']:
_params.pop(p)
cls.lbv1_client = LBV1C.get_client(cls.manager)
cls.network = cls.create_network()
cls.name = cls.network['name']
cls.subnet = cls.create_subnet(cls.network)
cls.ext_net_id = CONF.network.public_network_id
cls.router = cls.create_router(data_utils.rand_name('router-'),
admin_state_up=True,
external_network_id=cls.ext_net_id,
router_type='exclusive')
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
pool_name = data_utils.rand_name('pool-')
vip_name = data_utils.rand_name('vip-')
cls.pool = cls.lbv1_client.create_pool(
pool_name, "ROUND_ROBIN", "HTTP", cls.subnet['id'])['pool']
cls.vip = cls.lbv1_client.create_vip(cls.pool['id'],
subnet_id=cls.subnet['id'],
name=vip_name,
protocol="HTTP",
protocol_port=80)['vip']
cls.member = cls.lbv1_client.create_member(
80, cls.pool['id'], cls._ip_version)['member']
cls.member_address = ("10.0.9.47" if cls._ip_version == 4
else "2015::beef")
cls.health_monitor = cls.lbv1_client.create_health_monitor(
delay=4, max_retries=3, type="TCP", timeout=1)['health_monitor']
@classmethod
def resource_cleanup(cls):
"""
Cleanup the lb resources first and then call resource_cleanup
in BaseNetworkTest to cleanup other network resources. NSX-v
plugin requires the lb resources to be deleted before we can
delete subnet or remove interface from router.
"""
# Cleanup lb health monitors
if cls.health_monitor:
test_utils.call_and_ignore_notfound_exc(
cls.lbv1_client.delete_health_monitor,
cls.health_monitor['id'])
cls.health_monitor = None
# Cleanup members
if cls.member:
test_utils.call_and_ignore_notfound_exc(
cls.lbv1_client.delete_member, cls.member['id'])
cls.member = None
# Cleanup vips
if cls.vip:
test_utils.call_and_ignore_notfound_exc(
cls.lbv1_client.delete_vip, cls.vip['id'])
cls.vip = None
# Cleanup pool
if cls.pool:
test_utils.call_and_ignore_notfound_exc(
cls.lbv1_client.delete_pool, cls.pool['id'])
cls.pool = None
super(LoadBalancerTestJSON, cls).resource_cleanup()
def _check_list_with_filter(self, obj_name, attr_exceptions, **kwargs):
create_obj = getattr(self.lbv1_client, 'create_' + obj_name)
delete_obj = getattr(self.lbv1_client, 'delete_' + obj_name)
list_objs = getattr(self.lbv1_client, 'list_' + obj_name + 's')
body = create_obj(**kwargs)
obj = body[obj_name]
self.addCleanup(delete_obj, obj['id'])
for key, value in six.iteritems(obj):
# It is not relevant to filter by all arguments. That is why
# there is a list of attr to except
if key not in attr_exceptions:
body = list_objs(**{key: value})
objs = [v[key] for v in body[obj_name + 's']]
self.assertIn(value, objs)
@decorators.idempotent_id('1c959a37-feb3-4d58-b5fc-58ba653de065')
def test_list_vips(self):
# Verify the vIP exists in the list of all vIPs
body = self.lbv1_client.list_vips()
vips = body['vips']
self.assertIn(self.vip['id'], [v['id'] for v in vips])
@decorators.idempotent_id('687b7fd1-fd15-4ffd-8166-f376407a6081')
def test_list_vips_with_filter(self):
pool_name = data_utils.rand_name("pool-")
vip_name = data_utils.rand_name('vip-')
body = self.lbv1_client.create_pool(pool_name,
lb_method="ROUND_ROBIN",
protocol="HTTPS",
subnet_id=self.subnet['id'])
pool = body['pool']
self.addCleanup(self.lbv1_client.delete_pool, pool['id'])
attr_exceptions = ['status', 'session_persistence',
'status_description']
self._check_list_with_filter(
'vip', attr_exceptions, name=vip_name, protocol="HTTPS",
protocol_port=81, subnet_id=self.subnet['id'], pool_id=pool['id'],
description=data_utils.rand_name('description-'),
admin_state_up=False)
@decorators.idempotent_id('73dfc119-b64b-4e56-90d2-df61d7181098')
def test_create_update_delete_pool_vip(self):
# Creates a vip
pool_name = data_utils.rand_name("pool-")
vip_name = data_utils.rand_name('vip-')
address = self.subnet['allocation_pools'][0]['end']
body = self.lbv1_client.create_pool(
pool_name,
lb_method='ROUND_ROBIN',
protocol='HTTP',
subnet_id=self.subnet['id'])
pool = body['pool']
body = self.lbv1_client.create_vip(pool['id'],
name=vip_name,
protocol="HTTP",
protocol_port=80,
subnet_id=self.subnet['id'],
address=address)
vip = body['vip']
vip_id = vip['id']
# Confirm VIP's address correctness with a show
body = self.lbv1_client.show_vip(vip_id)
vip = body['vip']
self.assertEqual(address, vip['address'])
# Verification of vip update
new_name = "New_vip"
new_description = "New description"
persistence_type = "HTTP_COOKIE"
update_data = {"session_persistence": {
"type": persistence_type}}
body = self.lbv1_client.update_vip(vip_id,
name=new_name,
description=new_description,
connection_limit=10,
admin_state_up=False,
**update_data)
updated_vip = body['vip']
self.assertEqual(new_name, updated_vip['name'])
self.assertEqual(new_description, updated_vip['description'])
self.assertEqual(10, updated_vip['connection_limit'])
self.assertFalse(updated_vip['admin_state_up'])
self.assertEqual(persistence_type,
updated_vip['session_persistence']['type'])
self.lbv1_client.delete_vip(vip['id'])
self.lbv1_client.wait_for_resource_deletion('vip', vip['id'])
# Verification of pool update
new_name = "New_pool"
body = self.lbv1_client.update_pool(pool['id'],
name=new_name,
description="new_description",
lb_method='LEAST_CONNECTIONS')
updated_pool = body['pool']
self.assertEqual(new_name, updated_pool['name'])
self.assertEqual('new_description', updated_pool['description'])
self.assertEqual('LEAST_CONNECTIONS', updated_pool['lb_method'])
self.lbv1_client.delete_pool(pool['id'])
@decorators.idempotent_id('277a99ce-4b3e-451d-a18a-d26c0376d176')
def test_show_vip(self):
# Verifies the details of a vip
body = self.lbv1_client.show_vip(self.vip['id'])
vip = body['vip']
for key, value in six.iteritems(vip):
# 'status' should not be confirmed in api tests
if key != 'status':
self.assertEqual(self.vip[key], value)
@decorators.idempotent_id('432470dd-836b-4555-8388-af95a1c74d32')
def test_show_pool(self):
# Here we need to new pool without any dependence with vips
pool_name = data_utils.rand_name("pool-")
body = self.lbv1_client.create_pool(pool_name,
lb_method='ROUND_ROBIN',
protocol='HTTP',
subnet_id=self.subnet['id'])
pool = body['pool']
self.addCleanup(self.lbv1_client.delete_pool, pool['id'])
# Verifies the details of a pool
body = self.lbv1_client.show_pool(pool['id'])
shown_pool = body['pool']
for key, value in six.iteritems(pool):
# 'status' should not be confirmed in api tests
if key != 'status':
self.assertEqual(value, shown_pool[key])
@decorators.idempotent_id('c9951820-7b24-4e67-8c0c-41065ec66071')
def test_list_pools(self):
# Verify the pool exists in the list of all pools
body = self.lbv1_client.list_pools()
pools = body['pools']
self.assertIn(self.pool['id'], [p['id'] for p in pools])
@decorators.idempotent_id('55a1fb8e-e88e-4042-a46a-13a0282e4990')
def test_list_pools_with_filters(self):
attr_exceptions = ['status', 'vip_id', 'members', 'provider',
'status_description']
self._check_list_with_filter(
'pool', attr_exceptions, name=data_utils.rand_name("pool-"),
lb_method="ROUND_ROBIN", protocol="HTTPS",
subnet_id=self.subnet['id'],
description=data_utils.rand_name('description-'),
admin_state_up=False)
@decorators.idempotent_id('dd441433-de8f-4992-a721-0755dec737ff')
def test_list_members(self):
# Verify the member exists in the list of all members
body = self.lbv1_client.list_members()
members = body['members']
self.assertIn(self.member['id'], [m['id'] for m in members])
@decorators.idempotent_id('ccebe68a-f096-478d-b495-f17d5c0eac7b')
def test_list_members_with_filters(self):
attr_exceptions = ['status', 'status_description']
self._check_list_with_filter('member', attr_exceptions,
address=self.member_address,
protocol_port=80,
pool_id=self.pool['id'])
@decorators.idempotent_id('b4efe862-0439-4260-828c-cc09ff7e12a6')
def test_create_update_delete_member(self):
# Creates a member
body = self.lbv1_client.create_member(address=self.member_address,
protocol_port=80,
pool_id=self.pool['id'])
member = body['member']
# Verification of member update
body = self.lbv1_client.update_member(member['id'],
admin_state_up=False)
updated_member = body['member']
self.assertFalse(updated_member['admin_state_up'])
# Verification of member delete
self.lbv1_client.delete_member(member['id'])
@decorators.idempotent_id('4806ca47-b3a0-4280-9962-6631c6815e93')
def test_show_member(self):
# Verifies the details of a member
body = self.lbv1_client.show_member(self.member['id'])
member = body['member']
for key, value in six.iteritems(member):
# 'status' should not be confirmed in api tests
if key != 'status':
self.assertEqual(self.member[key], value)
@decorators.idempotent_id('65c4d817-d8d2-44df-9c15-86fc7b910044')
def test_list_health_monitors(self):
# Verify the health monitor exists in the list of all health monitors
body = self.lbv1_client.list_health_monitors()
health_monitors = body['health_monitors']
self.assertIn(self.health_monitor['id'],
[h['id'] for h in health_monitors])
@decorators.idempotent_id('a2c749a0-4eac-4acc-b729-6b469c3c616a')
def test_list_health_monitors_with_filters(self):
attr_exceptions = ['status', 'status_description', 'pools']
self._check_list_with_filter('health_monitor', attr_exceptions,
delay=5, max_retries=4, type="TCP",
timeout=2)
@decorators.idempotent_id('94f1e066-de6e-4cd8-b352-533d216956b7')
def test_create_update_delete_health_monitor(self):
# Creates a health_monitor
body = self.lbv1_client.create_health_monitor(delay=4,
max_retries=3,
type="TCP",
timeout=1)
health_monitor = body['health_monitor']
# Verification of health_monitor update
body = (self.lbv1_client.update_health_monitor
(health_monitor['id'],
admin_state_up=False))
updated_health_monitor = body['health_monitor']
self.assertFalse(updated_health_monitor['admin_state_up'])
# Verification of health_monitor delete
body = self.lbv1_client.delete_health_monitor(health_monitor['id'])
@decorators.idempotent_id('82943dcf-d424-43f0-890f-4b796f5043dc')
def test_create_health_monitor_http_type(self):
hm_type = "HTTP"
body = self.lbv1_client.create_health_monitor(delay=4,
max_retries=3,
type=hm_type,
timeout=1)
health_monitor = body['health_monitor']
self.addCleanup(self.lbv1_client.delete_health_monitor,
health_monitor['id'])
self.assertEqual(hm_type, health_monitor['type'])
@decorators.idempotent_id('b1279c46-822a-4406-bb16-6a6ce7bf4e4e')
def test_update_health_monitor_http_method(self):
body = self.lbv1_client.create_health_monitor(delay=4,
max_retries=3,
type="HTTP",
timeout=1)
health_monitor = body['health_monitor']
self.addCleanup(self.lbv1_client.delete_health_monitor,
health_monitor['id'])
body = (self.lbv1_client.update_health_monitor
(health_monitor['id'],
http_method="POST",
url_path="/home/user",
expected_codes="290"))
updated_health_monitor = body['health_monitor']
self.assertEqual("POST", updated_health_monitor['http_method'])
self.assertEqual("/home/user", updated_health_monitor['url_path'])
self.assertEqual("290", updated_health_monitor['expected_codes'])
@decorators.idempotent_id('7beabd44-0200-4cc4-b18d-5fb1f44cf36c')
def test_show_health_monitor(self):
# Verifies the details of a health_monitor
body = self.lbv1_client.show_health_monitor(self.health_monitor['id'])
health_monitor = body['health_monitor']
for key, value in six.iteritems(health_monitor):
# 'status' should not be confirmed in api tests
if key != 'status':
self.assertEqual(self.health_monitor[key], value)
@decorators.idempotent_id('5386d600-1372-4f99-b0f2-316401718ac4')
def test_associate_disassociate_health_monitor_with_pool(self):
# Verify that a health monitor can be associated with a pool
self.lbv1_client.associate_health_monitor_with_pool(
self.health_monitor['id'], self.pool['id'])
body = self.lbv1_client.show_health_monitor(
self.health_monitor['id'])
health_monitor = body['health_monitor']
body = self.lbv1_client.show_pool(self.pool['id'])
pool = body['pool']
self.assertIn(pool['id'],
[p['pool_id'] for p in health_monitor['pools']])
self.assertIn(health_monitor['id'], pool['health_monitors'])
# Verify that a health monitor can be disassociated from a pool
(self.lbv1_client.disassociate_health_monitor_with_pool
(self.health_monitor['id'], self.pool['id']))
body = self.lbv1_client.show_pool(self.pool['id'])
pool = body['pool']
body = self.lbv1_client.show_health_monitor(
self.health_monitor['id'])
health_monitor = body['health_monitor']
self.assertNotIn(health_monitor['id'], pool['health_monitors'])
self.assertNotIn(pool['id'],
[p['pool_id'] for p in health_monitor['pools']])
@decorators.idempotent_id('17a6b730-0780-46c9-bca0-cec67387e469')
def test_get_lb_pool_stats(self):
# Verify the details of pool stats
body = self.lbv1_client.list_lb_pool_stats(self.pool['id'])
stats = body['stats']
self.assertIn("bytes_in", stats)
self.assertIn("total_connections", stats)
self.assertIn("active_connections", stats)
self.assertIn("bytes_out", stats)
@decorators.idempotent_id('a113c740-6194-4622-a187-8343ad3e5208')
def test_update_list_of_health_monitors_associated_with_pool(self):
(self.lbv1_client.associate_health_monitor_with_pool
(self.health_monitor['id'], self.pool['id']))
self.lbv1_client.update_health_monitor(
self.health_monitor['id'], admin_state_up=False)
body = self.lbv1_client.show_pool(self.pool['id'])
health_monitors = body['pool']['health_monitors']
for health_monitor_id in health_monitors:
body = self.lbv1_client.show_health_monitor(health_monitor_id)
self.assertFalse(body['health_monitor']['admin_state_up'])
(self.lbv1_client.disassociate_health_monitor_with_pool
(self.health_monitor['id'], self.pool['id']))
@decorators.idempotent_id('a2843ec6-80d8-4617-b985-8c8565daac8d')
def test_update_admin_state_up_of_pool(self):
self.lbv1_client.update_pool(self.pool['id'],
admin_state_up=False)
body = self.lbv1_client.show_pool(self.pool['id'])
pool = body['pool']
self.assertFalse(pool['admin_state_up'])
@decorators.idempotent_id('fd45c684-b847-472f-a7e8-a3f70e8e08e0')
def test_show_vip_associated_with_pool(self):
body = self.lbv1_client.show_pool(self.pool['id'])
pool = body['pool']
body = self.lbv1_client.show_vip(pool['vip_id'])
vip = body['vip']
self.assertEqual(self.vip['name'], vip['name'])
self.assertEqual(self.vip['id'], vip['id'])
@decorators.idempotent_id('1ac0ca5f-7d6a-4ac4-b286-d68c92a98405')
def test_show_members_associated_with_pool(self):
body = self.lbv1_client.show_pool(self.pool['id'])
members = body['pool']['members']
for member_id in members:
body = self.lbv1_client.show_member(member_id)
self.assertIsNotNone(body['member']['status'])
self.assertEqual(member_id, body['member']['id'])
self.assertIsNotNone(body['member']['admin_state_up'])
@decorators.idempotent_id('4fa308fa-ac2b-4acf-87db-adfe2ee4739c')
def test_update_pool_related_to_member(self):
# Create new pool
pool_name = data_utils.rand_name("pool-")
body = self.lbv1_client.create_pool(
pool_name,
lb_method='ROUND_ROBIN',
protocol='HTTP',
subnet_id=self.subnet['id'])
new_pool = body['pool']
self.addCleanup(self.lbv1_client.delete_pool, new_pool['id'])
# Update member with new pool's id
body = self.lbv1_client.update_member(self.member['id'],
pool_id=new_pool['id'])
# Confirm with show that pool_id change
body = self.lbv1_client.show_member(self.member['id'])
member = body['member']
self.assertEqual(member['pool_id'], new_pool['id'])
# Update member with old pool id, this is needed for clean up
body = self.lbv1_client.update_member(self.member['id'],
pool_id=self.pool['id'])
@decorators.idempotent_id('0af2ff6b-a896-433d-8107-3c76262a9dfa')
def test_update_member_weight(self):
self.lbv1_client.update_member(self.member['id'],
weight=2)
body = self.lbv1_client.show_member(self.member['id'])
member = body['member']
self.assertEqual(2, member['weight'])
@decorators.skip_because(bug="1402007")
class LoadBalancerIpV6TestJSON(LoadBalancerTestJSON):
_ip_version = 6

View File

@ -1,169 +0,0 @@
# Copyright 2015 OpenStack Foundation
# 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 random
from tempest import config
from oslo_log import log as logging
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import test_subnets as SNET
CONF = config.CONF
LOG = logging.getLogger(__name__)
VLAN_PHYSICAL_NETWORK = CONF.nsxv.vlan_physical_network or None
VLAN_ID_PROVIDER = CONF.nsxv.provider_vlan_id
class VlanNetworksTestJSON(SNET.SubnetTestJSON):
_interface = 'json'
_vlanid = int(VLAN_ID_PROVIDER)
_provider_network_body = {
'name': data_utils.rand_name('VLAN-%04d-network' % _vlanid),
'provider:network_type': 'vlan',
'provider:physical_network': VLAN_PHYSICAL_NETWORK,
'provider:segmentation_id': _vlanid}
@classmethod
def resource_setup(cls):
cls.vlan_range = (2001, 2999)
cls.vlan_assigned = []
super(VlanNetworksTestJSON, cls).resource_setup()
def get_next_vlan(self):
next_vlan = self.next_vlan
self.next_vlan += 1
if self.next_vlan > self.vlan_range[1]:
self.next_vlan = self.vlan_range[0]
return next_vlan
def get_vlan(self):
for x in range(0, 10):
next_vlan = random.randint(*self.vlan_range)
if next_vlan in self.vlan_assigned:
continue
else:
self.vlan_assigned.append(next_vlan)
return next_vlan
return 3000
def _create_network(self, _auto_clean_up=True, network_name=None,
**kwargs):
segmentation_id = kwargs.pop('provider:segmentation_id', None)
if not segmentation_id:
segmentation_id = self.get_vlan()
network_name = (network_name or
data_utils.rand_name(
'vlan-' + str(segmentation_id) + '-netwk'))
post_body = {'name': network_name,
'provider:network_type': 'vlan',
'provider:physical_network': VLAN_PHYSICAL_NETWORK,
'provider:segmentation_id': segmentation_id}
post_body.update(kwargs)
for k, v in post_body.items():
if not v:
post_body.pop(k)
LOG.debug("create VLAN network: %s", str(post_body))
body = self.create_network(**post_body)
network = body['network']
if _auto_clean_up:
self.addCleanup(self._try_delete_network, network['id'])
return network
@decorators.idempotent_id('c5f98016-dee3-42f1-8c23-b9cd1e625561')
def test_create_network(self):
# Create a network as an admin user specifying the
# vlan network type attribute
provider_attrs = {
'provider:network_type': 'vlan',
'provider:physical_network': VLAN_PHYSICAL_NETWORK,
'provider:segmentation_id': 1002}
network = self._create_network(_auto_clean_up=False, **provider_attrs)
# Verifies parameters
self.assertIsNotNone(network['id'])
self.assertEqual(network.get('provider:network_type'), 'vlan')
if VLAN_PHYSICAL_NETWORK:
self.assertEqual(network.get('provider:physical_network'),
VLAN_PHYSICAL_NETWORK)
self.assertEqual(network.get('provider:segmentation_id'), 1002)
self._delete_network(network['id'])
@decorators.idempotent_id('714e69eb-bb31-4cfc-9804-8e988f04ca65')
def test_update_network(self):
# Update flat network as an admin user specifying the
# flat network attribute
net_profile = {'shared': True, '_auto_clean_up': False,
'provider:segmentation_id': 1003}
network = self._create_network(**net_profile)
self.assertEqual(network.get('shared'), True)
new_name = network['name'] + "-updated"
update_body = {'shared': False, 'name': new_name}
body = self.update_network(network['id'], **update_body)
updated_network = body['network']
# Verify that name and shared parameters were updated
self.assertEqual(updated_network['shared'], False)
self.assertEqual(updated_network['name'], new_name)
# get flat network attributes and verify them
body = self.show_network(network['id'])
updated_network = body['network']
# Verify that name and shared parameters were updated
self.assertEqual(updated_network['shared'], False)
self.assertEqual(updated_network['name'], new_name)
self.assertEqual(updated_network['status'], network['status'])
self.assertEqual(updated_network['subnets'], network['subnets'])
self._delete_network(network['id'])
@decorators.idempotent_id('8a8b9f2c-37f8-4c53-b8e3-0c9c0910380f')
def test_list_networks(self):
# Create flat network
net_profile = {'shared': True, '_auto_clean_up': False,
'provider:segmentation_id': 1004}
network = self._create_network(**net_profile)
# List networks as a normal user and confirm it is available
body = self.list_networks(client=self.networks_client)
networks_list = [net['id'] for net in body['networks']]
self.assertIn(network['id'], networks_list)
update_body = {'shared': False}
body = self.update_network(network['id'], **update_body)
# List networks as a normal user and confirm it is not available
body = self.list_networks(client=self.networks_client)
networks_list = [net['id'] for net in body['networks']]
self.assertNotIn(network['id'], networks_list)
self._delete_network(network['id'])
@decorators.idempotent_id('5807958d-9ee2-48a5-937e-ddde092956a6')
def test_show_network_attributes(self):
# Create flat network
net_profile = {'shared': True, '_auto_clean_up': False,
'provider:segmentation_id': 1005}
network = self._create_network(**net_profile)
# Show a flat network as a normal user and confirm the
# flat network attribute is returned.
body = self.show_network(network['id'], client=self.networks_client)
show_net = body['network']
self.assertEqual(network['name'], show_net['name'])
self.assertEqual(network['id'], show_net['id'])
# provider attributes are for admin only
body = self.show_network(network['id'])
show_net = body['network']
net_attr_list = show_net.keys()
for attr in ('admin_state_up', 'port_security_enabled', 'shared',
'status', 'subnets', 'tenant_id', 'router:external',
'provider:network_type', 'provider:physical_network',
'provider:segmentation_id'):
self.assertIn(attr, net_attr_list)
self._delete_network(network['id'])

View File

@ -1,818 +0,0 @@
# Copyright 2015 OpenStack Foundation
# 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 collections
import os
import re
import shlex
import subprocess
import time
import traceback
from tempest.common.utils.linux import remote_client
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 exceptions
from tempest import test
from vmware_nsx_tempest.tests.nsxv.scenario import (
network_addon_methods as HELO)
from vmware_nsx_tempest.tests.scenario import manager
CONF = config.CONF
LOG = manager.log.getLogger(__name__)
Floating_IP_tuple = collections.namedtuple(
'Floating_IP_tuple', ['floating_ip', 'server'])
Z_VM2_DEST = "VM[%(h_ipaddr)s] %(msg)s [%(helper)s %(d_ipaddr)s]"
# Before checking for floatingIP and server connectivity, we need to wait
# x seconds for the control-plane to push configuration to data-plane
# prior to process add/update/delete requests.
WAITTIME_AFTER_DISASSOC_FLOATINGIP = CONF.scenario.waitfor_disassoc
WAITTIME_AFTER_ASSOC_FLOATINGIP = CONF.scenario.waitfor_assoc
WAITTIME_FOR_CONNECTIVITY = CONF.scenario.waitfor_connectivity
DNS_SERVERS_IPV4 = CONF.network.dns_servers
OUTSIDE_WORLD_SERVERS = CONF.scenario.outside_world_servers
# iptype
IPTYPE_FLOATING = 'floating-ip'
IPTYPE_FIXED = 'fixed-ip'
IPTYPE_OUTSIDE_SERVER = 'outside-server'
class TopoDeployScenarioManager(manager.NetworkScenarioTest):
"""Purposes for TopoDeployScenarionManager:
1. Each deployment scenarion create its network resources, so
call set_network_resource at setup_credentials() to overwrite it.
2. setUp() is for test framework. Test case topology is part of
test and is configured during test() cycle.
3. net_resources.py overwrite resourses.py so the method to add
interfaces to routers are inline with CLI, and support router
owned by admin, but subnets are primary/alt clients.
-- mechanism removed with patch 320495
-- we are relaying on the test framework to delete resources
in the reverse order of creating.
4. Ping is used for Data-plane testing. OUTSIDE_WORLD_SERVERS ping
test make sense when tenant's DNS is pirvate to provider.
5. Teardown is high cost, each test should perform its un-config to
complete the whole tenant life-cycle.
WARNING: you need to increase your quota to run in parallel as
you might run out of quota when things went wrong.
"""
# defined at test.py; used to create client managers
credentials = ['admin', 'primary', 'alt']
# router attributes used to create the tenant's router
tenant_router_attrs = {}
@classmethod
def skip_checks(cls):
super(TopoDeployScenarioManager, cls).skip_checks()
for ext in ['router', 'security-group']:
if not test.is_extension_enabled(ext, 'network'):
msg = "%s extension not enabled." % ext
raise cls.skipException(msg)
@classmethod
def check_preconditions(cls):
super(TopoDeployScenarioManager, cls).check_preconditions()
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.')
cls.enabled = False
raise cls.skipException(msg)
@classmethod
def setup_credentials(cls):
# Each client's network is created when client manager is created,
# and client manager is created at setup_credentials.
# topo-deploy scenarion manager asks not to create network resources.
cls.set_network_resources(False, False, False, False)
super(TopoDeployScenarioManager, cls).setup_credentials()
@classmethod
def resource_setup(cls):
super(TopoDeployScenarioManager, cls).resource_setup()
cls.namestart = 'topo-deploy-tenant'
cls.public_network_id = CONF.network.public_network_id
# The creation of the 2nd tenant is defined by class.credentials
# cls.alt_manager = clients.Manager(credentials=cls.alt_credentials())
cls.alt_tenant_id = cls.alt_manager.identity_client.tenant_id
@classmethod
def resource_cleanup(cls):
super(TopoDeployScenarioManager, cls).resource_cleanup()
def setUp(self):
super(TopoDeployScenarioManager, self).setUp()
self.cleanup_waits = []
self.addCleanup(self._wait_for_cleanups)
self.servers_on_net = {}
def tearDown(self):
super(TopoDeployScenarioManager, self).tearDown()
def addCleanup_with_wait(self, waiter_callable, thing_id, thing_id_param,
cleanup_callable, cleanup_args=None,
cleanup_kwargs=None, waiter_client=None):
"""Adds wait for async resource deletion at the end of cleanups
@param waiter_callable: callable to wait for the resource to delete
with the following waiter_client if specified.
@param thing_id: the id of the resource to be cleaned-up
@param thing_id_param: the name of the id param in the waiter
@param cleanup_callable: method to load pass to self.addCleanup with
the following *cleanup_args, **cleanup_kwargs.
usually a delete method.
"""
if cleanup_args is None:
cleanup_args = []
if cleanup_kwargs is None:
cleanup_kwargs = {}
self.addCleanup(cleanup_callable, *cleanup_args, **cleanup_kwargs)
wait_dict = {
'waiter_callable': waiter_callable,
thing_id_param: thing_id
}
if waiter_client:
wait_dict['client'] = waiter_client
self.cleanup_waits.append(wait_dict)
def _wait_for_cleanups(self):
# To handle async delete actions, a list of waits is added
# which will be iterated over as the last step of clearing the
# cleanup queue. That way all the delete calls are made up front
# and the tests won't succeed unless the deletes are eventually
# successful. This is the same basic approach used in the api tests to
# limit cleanup execution time except here it is multi-resource,
# because of the nature of the scenario tests.
for wait in self.cleanup_waits:
waiter_callable = wait.pop('waiter_callable')
waiter_callable(**wait)
# overwrite parent class which does not accept NSX-v extension
def _create_router(self, client_mgr=None, tenant_id=None,
namestart='topo-deploy', **kwargs):
client_mgr = client_mgr or self.manager
routers_client = getattr(client_mgr, "routers_client")
router = HELO.router_create(self, client=routers_client,
tenant_id=tenant_id,
namestart=namestart,
**kwargs)
return router
def _router_set_gateway(self, router_id, network_id, client=None):
routers_client = client or self.routers_client
return HELO.router_gateway_set(self, router_id, network_id,
client=routers_client)
def _router_clear_gateway(self, router_id, client=None):
routers_client = client or self.routers_client
return HELO.router_gateway_clear(self, router_id,
client=routers_client)
def _router_update_extra_routes(self, router_id, routes, client=None):
routers_client = client or self.routers_client
router = routers_client.update_route(self, router_id,
routes=routes)
return router['router']
def _router_delete_extra_routes(self, router_id, client=None):
routers_client = client or self.routers_client
return HELO.router_delete_extra_routes(self, router_id,
routers_client)
def _router_add_interface(self, net_router, net_subnet, client_mgr):
routers_client = client_mgr.routers_client
return HELO.router_interface_add(self, net_router['id'],
net_subnet['id'], routers_client)
def router_interface_add(self, router_id, subnet_id, client=None):
routers_client = client or self.routers_client
return HELO.router_interface_add(self, router_id, subnet_id,
routers_client)
def router_interface_delete(self, router_id, subnet_id, client=None):
routers_client = client or self.routers_client
return HELO.router_interface_delete(self, router_id, subnet_id,
routers_client)
def create_server_on_network(self, networks, security_groups=None,
name=None, image=None, wait_on_boot=True,
flavor=None, servers_client=None,
key_name=None, tenant_id=None):
name = name or data_utils.rand_name('topo-deploy-vm')
if security_groups is None:
security_groups = [{'name': 'default'}]
if type(networks) in (list, tuple):
network_ifs = [{'uuid': nw['id']} for nw in networks]
else:
network_ifs = [{'uuid': networks['id']}]
create_kwargs = {
'networks': network_ifs,
'security_groups': security_groups,
}
if key_name:
create_kwargs['key_name'] = key_name
if tenant_id:
if not (servers_client and servers_client.tenant_id == tenant_id):
create_kwargs['tenant_id'] = tenant_id
LOG.debug("TopoDeploy Create server name=%(name)s"
", create_kwargs=%(create_kwargs)s",
{'name': name, 'create_kwargs': str(create_kwargs)})
server = self.create_server(
name=name, image=image, wait_on_boot=wait_on_boot,
servers_client=servers_client, flavor=flavor,
tenant_id=tenant_id, create_kwargs=create_kwargs)
return server
# overwrite parent classes; add servers_client
# BUG https://bugs.launchpad.net/tempest/+bug/1416175
def create_server(self, name=None, image=None, flavor=None,
wait_on_boot=True, wait_on_delete=True,
servers_client=None, tenant_id=None,
create_kwargs=None):
"""Creates VM instance.
@param image: image from which to create the instance
@param wait_on_boot: wait for status ACTIVE before continue
@param wait_on_delete: force synchronous delete on cleanup
@param servers_client: the servers_client to create VM
@param create_kwargs: additional details for instance creation
@return: server dict
"""
name = name or data_utils.rand_name('topo-deploy-vm')
image = image or CONF.compute.image_ref
flavor = flavor or CONF.compute.flavor_ref
servers_client = servers_client or self.servers_client
create_kwargs = create_kwargs or {}
if type(tenant_id) in (str, unicode):
if servers_client.tenant_id != tenant_id:
create_kwargs['tenant_id'] = tenant_id
xmsg = ("Creating a server name=%(name)s, image=%(image)s"
", flavor=%(flavor)s, create_kwargs=%(create_kwargs)s" %
{'name': name, 'image': image, 'flavor': flavor,
'create_kwargs': str(create_kwargs)})
LOG.debug(xmsg)
server_resp = servers_client.create_server(
name=name, imageRef=image, flavorRef=flavor, **create_kwargs)
server = server_resp['server']
if wait_on_delete:
self.addCleanup(
waiters.wait_for_server_termination,
servers_client, server['id'])
self.addCleanup_with_wait(
waiter_callable=waiters.wait_for_server_termination,
thing_id=server['id'], thing_id_param='server_id',
waiter_client=servers_client,
cleanup_callable=test_utils.call_and_ignore_notfound_exc,
cleanup_args=[servers_client.delete_server, server['id']])
if wait_on_boot:
waiters.wait_for_server_status(
client=servers_client,
server_id=server['id'], status='ACTIVE')
# The instance retrieved on creation is missing network
# details, necessitating retrieval after it becomes active to
# ensure correct details.
server_resp = servers_client.show_server(server['id'])
server = server_resp['server']
self.assertEqual(server['name'], name)
self.servers_on_net[server['id']] = server
return server
def create_provider_network(self, client_mgr=None, create_body=None):
name = create_body.get('name', None) or data_utils.rand_name('P-net')
create_body['name'] = name
client_mgr = client_mgr or self.admin_manager
net_network = HELO.create_network(
self, client=client_mgr.networks_client, **create_body)
return net_network
def create_provider_subnet(self, client_mgr=None, create_body=None):
client_mgr = client_mgr or self.admin_manager
subnets_client = client_mgr.subnets_client
body = subnets_client.create_subnet(**create_body)
net_subnet = body['subnet']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
subnets_client.delete_subnet,
net_subnet['id'])
return net_subnet
def setup_project_network(self, external_network_id,
client_mgr=None,
namestart=None, client=None,
tenant_id=None, cidr_offset=0,
**kwargs):
"""NOTE:
Refer to create_networks@scenario/manager.py which might refer
to public_router_id which we dont' want to use.
The test class can define class variable tenant_router_attrs
to create different type of routers, or overwrite with kwargs.
"""
name = namestart or data_utils.rand_name('topo-deploy-tenant')
client_mgr = client_mgr or self.manager
# _create_router() edits distributed and router_type
# Child classes use class var tenant_router_attrs to define
# tenant's router type, however, caller can overwrite it with kwargs.
distributed = kwargs.get('distributed',
self.tenant_router_attrs.get('distributed'))
router_type = kwargs.get('router_type',
self.tenant_router_attrs.get('router_type'))
net_router = self._create_router(
client_mgr=client_mgr, tenant_id=tenant_id,
namestart=name,
distributed=distributed, router_type=router_type)
self._router_set_gateway(net_router['id'], external_network_id,
client=client_mgr.routers_client)
net_network, net_subnet = self.create_network_subnet(
client_mgr=client_mgr, name=net_router['name'],
tenant_id=tenant_id, cidr_offset=cidr_offset)
self._router_add_interface(net_router, net_subnet, client_mgr)
return net_network, net_subnet, net_router
def create_network_subnet(self, client_mgr=None,
tenant_id=None, name=None, cidr_offset=0):
client_mgr = client_mgr or self.manager
tenant_id = tenant_id or _g_tenant_id(client_mgr.networks_client)
name = name or data_utils.rand_name('topo-deploy-network')
net_network = self.create_network(
client=client_mgr.networks_client,
tenant_id=tenant_id, name=name)
net_subnet = self.create_subnet(
client=client_mgr.subnets_client,
network=net_network,
cidr_offset=cidr_offset, name=net_network['name'])
return net_network, net_subnet
# cloned from _create_network@manager.py. Allow name parameter
def create_network(self, client=None, tenant_id=None, name=None,
**kwargs):
networks_client = client or self.networks_client
tenant_id = tenant_id or _g_tenant_id(networks_client)
name = name or data_utils.rand_name('topo-deploy-network')
return HELO.create_network(self, client=networks_client,
tenant_id=tenant_id, name=name,
**kwargs)
def create_subnet(self, network, client=None,
gateway='', cidr=None, mask_bits=None,
ip_version=None, cidr_offset=0,
allocation_pools=None, dns_nameservers=None,
**kwargs):
subnets_client = client or self.subnets_client
kwargs.update(client=subnets_client, gateway=gateway,
cidr=cidr, cidr_offset=cidr_offset,
mask_bits=mask_bits, ip_version=ip_version,
allocation_pools=allocation_pools,
dns_nameservers=dns_nameservers)
return HELO.create_subnet(self, network, **kwargs)
def create_floatingip_for_server(self, server, external_network_id=None,
port_id=None, client_mgr=None,
and_check_assigned=True):
client_mgr = client_mgr or self.manager
net_floatingip = self.create_floating_ip(
server,
external_network_id=external_network_id,
port_id=port_id,
client=client_mgr.floating_ips_client)
if port_id:
# attached to port, will not check ip assignement & reachability
return net_floatingip
serv_fip = net_floatingip['floating_ip_address']
# in some condiction, remove the serv_fip from your local known_hosts
# can solve the ssh "Connection refused" problem.
rm_sshkey(serv_fip)
if not and_check_assigned:
# caller will do the floatingip assigned to server and ping tests
return net_floatingip
self._waitfor_floatingip_assigned_to_server(client_mgr.servers_client,
server.get('id'))
server_pingable = self._waitfor_associated_floatingip(net_floatingip)
STEPINTO_DEBUG_IF_TRUE(not server_pingable)
self.assertTrue(
server_pingable,
msg=("Expect server to be reachable after"
" floating-ip[%s] assigned." % serv_fip))
return net_floatingip
def _waitfor_floatingip_assigned_to_server(self, server_client, server_id,
on_network=None,
extra_timeout=60):
timeout = server_client.build_timeout + extra_timeout
interval = server_client.build_interval
start_time = time.time()
while time.time() - start_time < timeout:
sv = server_client.show_server(server_id)
sv = sv.get('server', sv)
fip = self.get_server_ip_address(sv, 'floating')
if fip:
elapse_time = time.time() - start_time
xmsg = ("%s Take %d seconds to assign floatingip to server[%s]"
% ("OS-STATS:", int(elapse_time), sv.get('name')))
LOG.debug(xmsg)
return fip
time.sleep(interval)
raise Exception(
"Server[%s] did not get its floatingip in %s seconds" %
(server_id, timeout))
def get_server_ip_address(self, server, ip_type='fixed',
network_name=None):
if network_name and server['addresses'].get(network_name):
s_if = network_name
else:
s_if = server['addresses'].keys()[0]
for s_address in server['addresses'][s_if]:
if s_address['OS-EXT-IPS:type'] == ip_type:
return s_address.get('addr')
return None
def _waitfor_associated_floatingip(self, net_floatingip):
host_ip = net_floatingip['floating_ip_address']
return self.waitfor_host_connected(host_ip)
def waitfor_host_connected(self, host_ip, ping_timeout=5, msg=None):
PING_START = 'ping-progress-start'
PING_INSESSION = 'ping-progress-in-session'
PING_DONE = 'ping-progress-completed'
PING_TIMEOUT = 'ping-progress-timeout'
if msg and type(msg) in (str, unicode):
xmsg = ("waitfor_host_connected ip=%(ip)s! %(msg)s" %
{'ip': host_ip, 'msg': msg})
LOG.debug(xmsg)
t0 = time.time()
t1 = time.time() + WAITTIME_FOR_CONNECTIVITY
LOG.debug("VM-IP[%(ip)s] %(msg)s: %(t1)s.",
{'ip': host_ip, 'msg': PING_START, 't1': t0})
while (time.time() < t1):
# waitfor backend to create floatingip & linkages
time.sleep(WAITTIME_AFTER_ASSOC_FLOATINGIP)
server_pingable = self.ping_ip_address(
host_ip, ping_timeout=ping_timeout)
if server_pingable:
xmsg = ("VM-IP[%(ip)s] %(msg)s: %(t1)s (%(t2)s)." %
{'ip': host_ip, 'msg': PING_DONE,
't1': time.time(), 't2': (time.time() - t0)})
LOG.debug(xmsg)
break
xmsg = ("VM-IP[%(ip)s] %(msg)s, redo after %(t1)s seconds." %
{'ip': host_ip, 'msg': PING_INSESSION,
't1': WAITTIME_AFTER_ASSOC_FLOATINGIP})
LOG.debug(xmsg)
if not server_pingable:
xmsg = ("VM-IP[%(ip)s] %(msg)s: %(t1)s (%(t2)s)." %
{'ip': host_ip, 'msg': PING_TIMEOUT,
't1': time.time(), 't2': (time.time() - t0)})
LOG.debug(xmsg)
return server_pingable
def disassociate_floatingip(self, net_floatingip, client=None,
and_delete=False):
floating_ips_client = client or self.floating_ips_client
kwargs = dict(port_id=None)
floating_ip = floating_ips_client.update_floatingip(
net_floatingip['id'], **kwargs)
floating_ip = floating_ip.get('floatingip', floating_ip)
self.assertIsNone(floating_ip['port_id'])
if and_delete:
floating_ips_client.delete_floatingip(floating_ip['id'])
return floating_ip
def associate_floatingip(self, net_floatingip, to_server, client=None):
floating_ips_client = client or self.floating_ips_client
port_id, _ = self._get_server_port_id_and_ip4(to_server)
kwargs = dict(port_id=port_id)
floating_ip = floating_ips_client.update_floatingip(
net_floatingip['id'], **kwargs)['floatingip']
self.assertEqual(port_id, floating_ip['port_id'])
return floating_ip
def check_networks(self, net_network, net_subnet=None, net_router=None):
return HELO.check_networks(self, net_network, net_subnet, net_router)
# use this carefully, as it expect existence of floating_ip_tuple
def check_public_network_connectivity(self, should_connect=True,
msg=None, ping_timeout=30):
"""Verifies connectivty
To a VM via public network and floating IP, and verifies
floating IP has resource status is correct.
@param should_connect: bool. determines if connectivity check is
negative or positive.
@param msg: Failure message to add to Error message. Should describe
the place in the test scenario where the method was called,
to indicate the context of the failure
"""
floating_ip, server = self.floating_ip_tuple
return self._check_floatingip_connectivity(
floating_ip, server, should_connect, msg, ping_timeout)
def _check_floatingip_connectivity(self, floating_ip, server,
should_connect=True,
msg=None, ping_timeout=30,
floating_ips_client=None):
ip_address = floating_ip['floating_ip_address']
floatingip_status = 'ACTIVE' if should_connect else 'DOWN'
is_pingable = self.ping_ip_address(ip_address,
ping_timeout=ping_timeout)
msg = msg if msg else (
"Timeout out waiting for %s to become reachable" % ip_address)
if should_connect:
self.assertTrue(is_pingable, msg=msg)
else:
self.assertFalse(is_pingable, msg=msg)
self.check_floating_ip_status(floating_ip, floatingip_status,
floating_ips_client)
def check_floating_ip_status(self, floating_ip, status,
floating_ips_client=None):
"""Verifies floatingip reaches the given status
:param dict floating_ip: floating IP dict to check status
:param status: target status
:raises: AssertionError if status doesn't match
"""
floating_ips_client = floating_ips_client or self.floating_ips_client
floatingip_id = floating_ip['id']
def refresh():
result = (floating_ips_client.
show_floatingip(floatingip_id)['floatingip'])
return status == result['status']
test_utils.call_until_true(refresh,
CONF.network.build_timeout,
CONF.network.build_interval)
floating_ip = floating_ips_client.show_floatingip(
floatingip_id)['floatingip']
self.assertEqual(status, floating_ip['status'],
message="FloatingIP: {fp} is at status: {cst}. "
"failed to reach status: {st}"
.format(fp=floating_ip, cst=floating_ip['status'],
st=status))
LOG.info("FloatingIP: {fp} is at status: {st}"
.format(fp=floating_ip, st=status))
def get_image_userpass(self):
return (CONF.validation.image_ssh_user,
CONF.validation.image_ssh_password)
def get_server_image(self):
return CONF.compute.image_ref
def get_server_flavor(self):
return CONF.compute.flavor_ref
# common utilities
def make_node_info(net_floatingip, username, password,
include_outside_servers=False):
floating_ip_address = net_floatingip['floating_ip_address']
fixed_ip_address = net_floatingip['fixed_ip_address']
node = dict(ipaddr=floating_ip_address,
username=username, password=password)
node['dest'] = [dict(ipaddr=floating_ip_address,
reachable=None, helper=IPTYPE_FLOATING),
dict(ipaddr=fixed_ip_address,
reachable=None, helper=IPTYPE_FIXED)]
if include_outside_servers:
outside_servers = dict(ipaddr=OUTSIDE_WORLD_SERVERS[0],
reachable=None, helper=IPTYPE_OUTSIDE_SERVER)
node['dest'].append(outside_servers)
return node
# we want to check the dest[iptype] is not reachable for
# at least (x_contd=2+=1 to make it is not really reachable.
def check_host_not_reachable(host, dest_list, iptype_list,
time_out=10, repeat_cnt=12,
x_contd=2):
not_connected = 0
for x in range(0, 12):
not_reachable = check_host_is_reachable(
host, dest_list, iptype_list, time_out=time_out)
if not_reachable:
not_connected += 1
else:
not_connected = 0
if not_connected > x_contd:
return True
return False
# check_hosts_connectivity
def check_host_is_reachable(host, dest_list, iptype_list, time_out=120):
rm_sshkey(host['ipaddr'])
ssh_client = get_remote_client_by_password(host['ipaddr'],
host['username'],
host['password'])
n_not_reachable = 0
for dest in dest_list:
for iptype in iptype_list:
if not dest_has_iptype(dest, iptype):
dest['reachable'] = None
continue
dest['reachable'] = is_reachable(
ssh_client, dest['ipaddr'], time_out=time_out)
if not dest['reachable']:
n_not_reachable += 1
xmsg = {'h_ipaddr': host['ipaddr'],
'msg': "can-not-reach-dest",
'helper': dest['helper'],
'd_ipaddr': dest['ipaddr']}
LOG.debug(Z_VM2_DEST, xmsg)
else:
xmsg = {'h_ipaddr': host['ipaddr'],
'msg': "can-not-dest",
'helper': dest['helper'],
'd_ipaddr': dest['ipaddr']}
LOG.debug(Z_VM2_DEST, xmsg)
return (False if n_not_reachable else True)
def dest_has_iptype(dest, iptype):
if ('helper' in dest and
re.search(iptype, dest['helper'], re.I)):
return True
return False
def check_hosts_connectivity(host, dest_list, ignore_helper=None,
time_out=120):
rm_sshkey(host['ipaddr'])
ssh_client = get_remote_client_by_password(host['ipaddr'],
host['username'],
host['password'])
n_not_reachable = 0
for dest in dest_list:
# caller can say to ignore dest ipaddr
if ('helper' in dest and type(ignore_helper) in (str, unicode) and
re.search(ignore_helper, dest['helper'], re.I)):
dest['reachable'] = None
continue
dest['reachable'] = is_reachable(ssh_client, dest['ipaddr'],
time_out=time_out)
if not dest['reachable']:
n_not_reachable += 1
xmsg = {'h_ipaddr': host['ipaddr'],
'msg': "can-not-reach-dest",
'helper': dest['helper'],
'd_ipaddr': dest['ipaddr']}
LOG.debug(Z_VM2_DEST, xmsg)
else:
xmsg = {'h_ipaddr': host['ipaddr'],
'msg': "can-reach-dest",
'helper': dest['helper'],
'd_ipaddr': dest['ipaddr']}
LOG.debug(Z_VM2_DEST, xmsg)
return n_not_reachable
def rm_sshkey(ip_addr):
# ssh-keygen -f "/home/stack/.ssh/known_hosts" -R 10.34.57.3
kh_file = os.path.join(os.environ.get('HOME', '/home/stack'),
'.ssh/known_hosts')
cmd = ['ssh-keygen', '-f', kh_file, '-R', ip_addr]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
proc.communicate()
return proc.returncode
def is_reachable(ssh_client, dest_ip, time_out=60.0, ping_timeout=5.0):
for now in run_till_timeout(time_out, ping_timeout):
reachable = dest_is_reachable(ssh_client, dest_ip)
if reachable:
return True
LOG.debug("DEST[%(ip)s] NOT-REACHABLE, retry in %(t1)s seconds.",
{'ip': dest_ip, 't1': time_out})
return False
def isnot_reachable(ssh_client, dest_ip, time_out=60.0, ping_timeout=5.0,
idle_time=2.0):
if idle_time > 0.0:
time.sleep(idle_time)
for now in run_till_timeout(time_out, ping_timeout):
reachable = dest_is_reachable(ssh_client, dest_ip)
if not reachable:
return True
LOG.debug("DEST[%(ip)s] IS-REACHABLE, retry in %(t1)s seconds.",
{'ip': dest_ip, 't1': time_out})
return False
def dest_is_reachable(ssh_client, dest_ip):
XPTN = r"(\d+).*transmit.*(\d+).*receive.*(\d+).*loss"
try:
result = ssh_client.ping_host(dest_ip)
m = re.search(XPTN, result, (re.I | re.M))
if m and int(m.group(1)) > 0 and int(m.group(3)) == 0:
return True
else:
return False
except Exception:
tb_str = traceback.format_exc()
mesg = ("ERROR on testing dest_ip[%s] is reachable:\n%s" %
(dest_ip, tb_str))
LOG.debug(mesg)
return False
def run_till_timeout(seconds_to_try, interval=5.0):
now, end_time = time.time(), time.time() + seconds_to_try
while now < end_time:
yield now
time.sleep(interval)
now = time.time()
def _g_tenant_id(os_client):
try:
return os_client.tenant_id
except Exception:
return os_client.rest_client.tenant_id
def get_remote_client_by_password(client_ip, username, password):
ssh_client = remote_client.RemoteClient(client_ip, username, password)
return ssh_client
def delete_all_servers(tenant_servers_client, trys=5):
# try at least trys+1 time to delete servers, otherwise
# network resources can not be deleted
for s in tenant_servers_client.list_servers()['servers']:
tenant_servers_client.delete_server(s['id'])
for x in range(0, trys):
try:
waitfor_servers_terminated(tenant_servers_client)
return
except Exception:
pass
# last try
waitfor_servers_terminated(tenant_servers_client)
def waitfor_servers_terminated(tenant_servers_client, pause=2.0):
while (True):
s_list = tenant_servers_client.list_servers()['servers']
if len(s_list) < 1:
return
time.sleep(pause)
def copy_file_to_host(file_from, dest, host, username, pkey):
dest = "%s@%s:%s" % (username, host, dest)
cmd = "scp -v -o UserKnownHostsFile=/dev/null " \
"-o StrictHostKeyChecking=no " \
"-i %(pkey)s %(file1)s %(dest)s" % {'pkey': pkey,
'file1': file_from,
'dest': dest}
args = shlex.split(cmd.encode('utf-8'))
subprocess_args = {'stdout': subprocess.PIPE,
'stderr': subprocess.STDOUT}
proc = subprocess.Popen(args, **subprocess_args)
stdout, stderr = proc.communicate()
if proc.returncode != 0:
raise exceptions.SSHExecCommandFailed(cmd,
proc.returncode,
stdout,
stderr)
return stdout
def STEPINTO_DEBUG_IF_TRUE(want2debug=False):
"""Betting you are not set OS_TEST_TIMEOUT=24-hours running tempest"""
t_timeout = int(os.environ.get('OS_TEST_TIMEOUT', 0))
if want2debug and t_timeout > 86400:
# uncomment following statements to turn on debuggging
# import pdb
# pdb.set_trace()
pass

View File

@ -1,286 +0,0 @@
# 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.
#
# This module contains the methods added to test class that to be shared by
# scenario tests that are inherent from tempest/scneario/manager.py or
# manager_topo_deployment.py
import netaddr
from oslo_log import log
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions
CONF = config.CONF
LOG = log.getLogger(__name__)
NO_ROUTER_TYPE = CONF.nsxv.no_router_type
# following router methods are not support by upstream tempest,
def router_create(SELF, client=None, tenant_id=None,
namestart='nsxv-router',
admin_state_up=True, **kwargs):
routers_client = client or SELF.routers_client
no_router_type = kwargs.pop('no_router_type', False)
if tenant_id:
if routers_client.tenant_id != tenant_id:
kwargs['tenant_id'] = tenant_id
distributed = kwargs.pop('distributed', None)
router_type = kwargs.pop('router_type', None)
if distributed:
kwargs['distributed'] = True
elif router_type in ('shared', 'exclusive'):
kwargs['router_type'] = router_type
name = kwargs.pop('name', None) or data_utils.rand_name(namestart)
kwargs['name'] = name
kwargs['admin_state_up'] = admin_state_up
if NO_ROUTER_TYPE or no_router_type:
# router_type is NSX-v extension.
# caller can set no_router_type=True to remove it
kwargs.pop('router_type', None)
result = routers_client.create_router(**kwargs)
router = result['router']
SELF.addCleanup(test_utils.call_and_ignore_notfound_exc,
routers_client.delete_router, router['id'])
SELF.assertEqual(router['name'], name)
return router
def router_delete(SELF, router_id):
routers_client = SELF.routers_client
routers_client.delete_router(router_id)
def router_gateway_set(SELF, router_id, network_id, client=None):
routers_client = client or SELF.routers_client
routers_client.update_router(
router_id,
external_gateway_info=dict(network_id=network_id))
SELF.addCleanup(test_utils.call_and_ignore_notfound_exc,
router_gateway_clear, SELF,
router_id, client=routers_client)
router = routers_client.show_router(router_id)
return router.get('router', router)
def router_gateway_clear(SELF, router_id, client=None):
routers_client = client or SELF.routers_client
routers_client.update_router(
router_id,
external_gateway_info=dict())
router = routers_client.show_router(router_id)
return router.get('router', router)
def router_update_extra_routes(SELF, router_id, routes, client=None):
routers_client = client or SELF.routers_client
router = routers_client.update_route(router_id, routes=routes)
return router.get('router', router)
def router_delete_extra_routes(SELF, router_id, client=None):
routers_client = client or SELF.routers_client
router = routers_client.update_route(router_id, routes=None)
return router.get('router', router)
def router_interface_add(SELF, router_id, subnet_id, client=None):
routers_client = client or SELF.routers_client
routers_client.add_router_interface(router_id,
subnet_id=subnet_id)
SELF.addCleanup(test_utils.call_and_ignore_notfound_exc,
routers_client.remove_router_interface,
router_id, subnet_id=subnet_id)
def router_interface_delete(SELF, router_id, subnet_id, client=None):
routers_client = client or SELF.routers_client
routers_client.remove_router_interface(router_id, subnet_id=subnet_id)
def router_add_interface(SELF, net_router, net_subnet, client_mgr):
routers_client = client_mgr.routers_client
return router_interface_add(SELF, net_router['id'], net_subnet['id'],
routers_client)
def router_port_interface_add(SELF, router_id, port_id, client=None):
routers_client = client or SELF.routers_client
routers_client.add_router_interface(router_id,
port_id=port_id)
SELF.addCleanup(test_utils.call_and_ignore_notfound_exc,
routers_client.remove_router_interface,
router_id, port_id=port_id)
def router_add_port_interface(SELF, net_router, net_port, client_mgr):
routers_client = client_mgr.routers_client
return router_port_interface_add(SELF, net_router['id'], net_port['id'],
routers_client)
def check_networks(SELF, t_network, t_subnet=None, t_router=None):
"""Checks that we see the newly created network/subnet/router.
checking the result of list_[networks,routers,subnets]
"""
seen_nets = SELF.admin_manager.networks_client.list_networks()['networks']
seen_names = [n['name'] for n in seen_nets]
seen_ids = [n['id'] for n in seen_nets]
SELF.assertIn(t_network['name'], seen_names)
SELF.assertIn(t_network['id'], seen_ids)
if t_subnet:
seen_subnets = SELF.admin_manager.subnets_client.list_subnets()
seen_net_ids = [n['network_id'] for n in seen_subnets['subnets']]
seen_subnet_ids = [n['id'] for n in seen_subnets['subnets']]
SELF.assertIn(t_network['id'], seen_net_ids)
SELF.assertIn(t_subnet['id'], seen_subnet_ids)
if t_router:
seen_routers = SELF.admin_manager.routers_client.list_routers()
seen_router_ids = [n['id'] for n in seen_routers['routers']]
seen_router_names = [n['name'] for n in seen_routers['routers']]
SELF.assertIn(t_router['name'],
seen_router_names)
SELF.assertIn(t_router['id'],
seen_router_ids)
def create_network_subnet(SELF, client_mgr=None, name=None,
tenant_id=None, cidr_offset=0):
client_mgr = client_mgr or SELF.manager
networks_client = client_mgr.networks_client
subnets_client = client_mgr.subnets_client
tenant_id = tenant_id or networks_client.tenant_id
name = name or data_utils.rand_name('network')
net_network = create_network(SELF, client=networks_client,
tenant_id=tenant_id, name=name)
net_subnet = create_subnet(SELF, client=subnets_client,
network=net_network,
name=net_network['name'],
cidr_offset=cidr_offset)
return net_network, net_subnet
# cloned from _create_network@manager.py. Allow name parameter
def create_network(SELF, client=None, tenant_id=None, name=None, **kwargs):
networks_client = client or SELF.networks_client
tenant_id = tenant_id or networks_client.tenant_id
name = name or data_utils.rand_name('network')
body = networks_client.create_network(name=name,
tenant_id=tenant_id,
**kwargs)
net_network = body['network']
SELF.addCleanup(test_utils.call_and_ignore_notfound_exc,
networks_client.delete_network,
net_network['id'])
SELF.assertEqual(net_network['name'], name)
return net_network
def create_port(SELF, client=None, **kwargs):
if not client:
client = SELF.port_client
result = client.create_port(**kwargs)
net_port = result['port']
SELF.assertIsNotNone(result, 'Unable to allocate port')
SELF.addCleanup(test_utils.call_and_ignore_notfound_exc,
client.delete_port,
net_port['id'])
return net_port
# gateway=None means don't set gateway_ip in subnet
def create_subnet(SELF, network, client=None,
gateway='', cidr=None, mask_bits=None,
ip_version=None, cidr_offset=0,
allocation_pools=None, dns_nameservers=None,
**kwargs):
subnets_client = client or SELF.subnets_client
network_id = network['id']
ip_version = ip_version or 4
post_body = get_subnet_create_options(
network_id, ip_version,
gateway=gateway, cidr=cidr, cidr_offset=cidr_offset,
mask_bits=mask_bits, **kwargs)
if allocation_pools:
post_body['allocation_pools'] = allocation_pools
if dns_nameservers:
post_body['dns_nameservers'] = dns_nameservers
LOG.debug("create_subnet args: %s", post_body)
body = subnets_client.create_subnet(**post_body)
net_subnet = body['subnet']
SELF.addCleanup(test_utils.call_and_ignore_notfound_exc,
subnets_client.delete_subnet,
net_subnet['id'])
return net_subnet
# utilities
def get_subnet_create_options(network_id, ip_version=4,
gateway='', cidr=None, mask_bits=None,
num_subnet=1, gateway_offset=1, cidr_offset=0,
**kwargs):
"""When cidr_offset>0 it request only one subnet-options:
subnet = get_subnet_create_options('abcdefg', 4, num_subnet=4)[3]
subnet = get_subnet_create_options('abcdefg', 4, cidr_offset=3)
"""
gateway_not_set = (gateway == '')
if ip_version == 4:
cidr = cidr or netaddr.IPNetwork(CONF.network.project_network_cidr)
mask_bits = mask_bits or CONF.network.project_network_mask_bits
elif ip_version == 6:
cidr = (
cidr or netaddr.IPNetwork(CONF.network.project_network_v6_cidr))
mask_bits = mask_bits or CONF.network.project_network_v6_mask_bits
# Find a cidr that is not in use yet and create a subnet with it
subnet_list = []
if cidr_offset > 0:
num_subnet = cidr_offset + 1
for subnet_cidr in cidr.subnet(mask_bits):
if gateway_not_set:
gateway_ip = gateway or (
str(netaddr.IPAddress(subnet_cidr) + gateway_offset))
else:
gateway_ip = gateway
try:
subnet_body = dict(network_id=network_id,
cidr=str(subnet_cidr),
ip_version=ip_version,
gateway_ip=gateway_ip,
**kwargs)
if num_subnet <= 1:
return subnet_body
subnet_list.append(subnet_body)
if len(subnet_list) >= num_subnet:
if cidr_offset > 0:
# user request the 'cidr_offset'th of cidr
return subnet_list[cidr_offset]
# user request list of cidr
return subnet_list
except exceptions.BadRequest as e:
is_overlapping_cidr = 'overlaps with another subnet' in str(e)
if not is_overlapping_cidr:
raise
else:
message = 'Available CIDR for subnet creation could not be found'
raise exceptions.BuildErrorException(message)
return {}

View File

@ -1,594 +0,0 @@
# 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 time
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.tests.nsxv.scenario import (
manager_topo_deployment as dmgr)
from vmware_nsx_tempest.tests.nsxv.scenario import (
network_addon_methods as HELO)
CONF = config.CONF
LOG = dmgr.manager.log.getLogger(__name__)
class TestAdminPolicyBasicOps(dmgr.TopoDeployScenarioManager):
"""Test VMs with security-group-policy traffic is managed by NSX
Test topology:
TOPO:
logical-router nasa-router] -- [ public GW]
|
+--- [Tenant jpl interface/subnet x.y.34.0/24]
| | |
| + [vm-nasa-jpl-3] + [vm-nasa-jpl-4]
|
+--- [Tenant ames interface/subnet x.y.12.0/24]
| | |
| + [vm-nasa-ames-1] + [vm-nasa-ames-2]
Test topology setup and traffic forwarding validation:
1. 2 tenants (ames, jpl) each tenant has 2 VMs, and boot with
security-group with policy==policy_AA which must allow
ping and ssh services as automation relys on this to make
sure test environment network connectivity is an OK.
NOTE:
primary user: ames -- NASA Ames Research Center
alt user: jpl -- NASA Jet Propulsion Laboratory
2. Admin create router (nasa-router) with both tenants' network
so tenant:ames and tenant:jpl can talk to each other
according to policy_AA.
3. under policy_AA, all servers can be ping and ssh from anywhere
4. Admin change tenant:jpl's policy to policy_BB
5. Tenant jpl's VMs are not pingable, ssh still OK
Tenant ames's MVs, both ping and ssh are OK
6. Admin change tenant:ames's policy to policy_BB
VMs from ames and jpl are not pingalbe; ssh is OK
ATTENTION:
config nsxv.default_policy_id is policy_AA
config nsxv.alt_policy_is is policy_BB
The testbed needs to have policy_AA and policy_BB created
and matched with the default_policy_id & alt_plicy_id under
session nsxv of tempest.conf or devstack local.conf.
Test Configuration setup:
please refer to vmware_nsx_tempest/doc/README-AdminPolicy.rst
"""
@classmethod
def skip_checks(cls):
super(TestAdminPolicyBasicOps, cls).skip_checks()
if not test.is_extension_enabled('security-group-policy', 'network'):
msg = "Extension security-group-policy is not enabled."
raise cls.skipException(msg)
if not (CONF.nsxv.alt_policy_id.startswith('policy-') and
CONF.nsxv.default_policy_id.startswith('policy-')):
msg = "default and alt policy ids not set correctly."
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(TestAdminPolicyBasicOps, cls).setup_clients()
cls.cmgr_adm = cls.get_client_manager('admin')
cls.cmgr_ames = cls.get_client_manager('primary')
cls.cmgr_jpl = cls.get_client_manager('alt')
@classmethod
def resource_setup(cls):
super(TestAdminPolicyBasicOps, cls).resource_setup()
cls.policy_AA = CONF.nsxv.default_policy_id
cls.policy_BB = CONF.nsxv.alt_policy_id
cls.conn_timeout = CONF.scenario.waitfor_connectivity
@classmethod
def resource_cleanup(cls):
super(TestAdminPolicyBasicOps, cls).resource_cleanup()
def setUp(self):
super(TestAdminPolicyBasicOps, self).setUp()
self.server_id_list = []
self.exc_step = 0
self.exc_msg = ("Admin-Policy-Traffic-Forwarding"
" Validation Steps:\n")
def tearDown(self):
# delete all servers and make sure they are terminated
servers_client = self.cmgr_adm.servers_client
server_id_list = getattr(self, 'server_id_list', [])
for server_id in server_id_list:
servers_client.delete_server(server_id)
for server_id in server_id_list:
waiters.wait_for_server_termination(servers_client, server_id)
# delete all floating-ips
if hasattr(self, 'fip_nasa_ames_1'):
self.delete_floatingip(self.cmgr_ames, self.fip_nasa_ames_1)
if hasattr(self, 'fip_nasa_jpl_3'):
self.delete_floatingip(self.cmgr_jpl, self.fip_nasa_jpl_3)
super(TestAdminPolicyBasicOps, self).tearDown()
def log_exc_msg(self, msg):
self.exc_step += 1
self.exc_msg += ("#%02d %s %s\n" %
(self.exc_step, time.strftime("%H:%M:%S"), msg))
def delete_floatingip(self, cmgr, net_floatingip):
test_utils.call_and_ignore_notfound_exc(
cmgr.floating_ips_client.delete_floatingip,
net_floatingip.get('id'))
def delete_security_group(self, sg_client, sg_id):
sg_client.delete_security_group(sg_id)
def update_security_group_policy(self, sg_id, policy_id):
sg_client = self.cmgr_adm.security_groups_client
sg = sg_client.update_security_group(sg_id, policy=policy_id)
sg = sg.get('security_group', sg)
self.assertEqual(policy_id, sg.get('policy'))
return sg
def create_security_group_policy(self, policy_id, tenant_id,
name_prefix=None):
sg_name = data_utils.rand_name(name_prefix or 'admin-policy')
sg_client = self.cmgr_adm.security_groups_client
sg_dict = dict(name=sg_name, policy=policy_id)
if tenant_id:
sg_dict['tenant_id'] = tenant_id
sg = sg_client.create_security_group(**sg_dict)
sg = sg.get('security_group', sg)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.delete_security_group,
sg_client, sg.get('id'))
return sg
def create_networks(self, cmgr,
name_prefix=None, cidr_offset=0):
net_name = data_utils.rand_name(name_prefix or 'admin-policy')
network = self.create_network(client=cmgr.networks_client,
name=net_name)
network = network.get('network', network)
subnet_kwargs = dict(name=net_name, cidr_offset=cidr_offset)
subnet = self.create_subnet(network,
client=cmgr.subnets_client,
**subnet_kwargs)
subnet = subnet.get('subnet', subnet)
return (network, subnet)
def create_router_by_type(self, router_type, client=None, **kwargs):
routers_client = client or self.cmgr_adm.routers_client
create_kwargs = dict(namestart='nasa-router', 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, subnet_list):
routers_client = self.cmgr_adm.routers_client
router = self.create_router_by_type(router_type)
for subnet in subnet_list:
HELO.router_interface_add(self, router['id'], subnet['id'],
client=routers_client)
# check interfaces/subnets are added to router
router_port_list = self.get_router_port_list(self.cmgr_adm,
router['id'])
for subnet in subnet_list:
added = self.rports_have_subnet_id(router_port_list, subnet['id'])
self.assertTrue(
added,
"subnet_id:%s is not added to router" % subnet['id'])
return router
def rports_have_subnet_id(self, router_port_list, subnet_id):
for rport in router_port_list:
for fips in rport.get('fixed_ips', []):
if subnet_id == fips['subnet_id']:
return True
return False
def get_router_port_list(self, cmgr, router_id):
device_owner = u'network:router_interface'
ports_client = cmgr.ports_client
port_list = ports_client.list_ports(device_id=router_id,
device_owner=device_owner)
port_list = port_list.get('ports', port_list)
return port_list
def create_servers_on_networks(self, cmgr, sv_name, networks_info):
network = networks_info.get('network')
security_group = networks_info.get('security_group')
security_groups = [{'name': security_group['id']}]
svr = self.create_server_on_network(
network, security_groups, name=sv_name,
wait_on_boot=False,
servers_client=cmgr.servers_client)
self.server_id_list.append(svr.get('id'))
return svr
def get_server_info(self, cmgr, server_id):
"""Get server's ip addresses"""
svr = cmgr.servers_client.show_server(server_id)
svr = svr.get('server', svr)
sinfo = dict(id=svr['id'], name=svr['name'],
security_gropus=svr['security_groups'],
fixed_ip_address=None, floating_ip_address=None)
addresses = svr.get('addresses')
for n_addresses in six.itervalues(addresses):
for n_addr in n_addresses:
if n_addr['OS-EXT-IPS:type'] == 'fixed':
if not sinfo['fixed_ip_address']:
sinfo['fixed_ip_address'] = n_addr['addr']
elif n_addr['OS-EXT-IPS:type'] == 'floating':
if not sinfo['floating_ip_address']:
sinfo['floating_ip_address'] = n_addr['addr']
return sinfo
def create_floatingip_for_server(self, cmgr, server):
username, password = self.get_image_userpass()
try:
floatingip = super(
TestAdminPolicyBasicOps,
self).create_floatingip_for_server(
server, client_mgr=cmgr, and_check_assigned=True)
except Exception as ex:
floatingip = None
msg = (self.exc_msg +
("\n**FAIL to associate floatingip to server[%s]\n%s"
% (server['name'], str(ex))))
self.assertTrue(floatingip, msg)
fix_ip = floatingip['fixed_ip_address']
float_ip = floatingip['floating_ip_address']
self.log_exc_msg((" floatingip[%s] created for server[%s,%s]"
" and is pingable." %
(float_ip, server.get('name'), fix_ip)))
return floatingip
def wait_for_servers_become_active(self):
servers_client = self.cmgr_adm.servers_client
for server_id in self.server_id_list:
waiters.wait_for_server_status(
servers_client, server_id, 'ACTIVE')
def find_servers_ips(self):
self.server_ips = {}
self.jpl_ips = {}
self.server_ips['1'] = self.get_server_info(
self.cmgr_ames, self.vm_nasa_ames_1['id'])
self.server_ips['2'] = self.get_server_info(
self.cmgr_ames, self.vm_nasa_ames_2['id'])
self.server_ips['3'] = self.get_server_info(
self.cmgr_jpl, self.vm_nasa_jpl_3['id'])
self.server_ips['4'] = self.get_server_info(
self.cmgr_jpl, self.vm_nasa_jpl_4['id'])
def create_nasa_ames_network_and_servers(self, security_group=None):
sg = security_group or self.sg_ames
net, subnet = self.create_networks(self.cmgr_ames, 'nasa-ames', 1)
self.netinfo_ames = dict(network=net, subnet=subnet,
security_group=sg)
self.vm_nasa_ames_1 = self.create_servers_on_networks(
self.cmgr_ames, 'vm-nasa-ames-1', self.netinfo_ames)
self.vm_nasa_ames_2 = self.create_servers_on_networks(
self.cmgr_ames, 'vm-nasa-ames-2', self.netinfo_ames)
def create_nasa_jpl_network_and_servers(self, security_group=None):
sg = security_group or self.sg_jpl
# jpl and ames attached to the same router, CIDR cannot overlap
net, subnet = self.create_networks(self.cmgr_jpl, 'nasa-jpl', 3)
self.netinfo_jpl = dict(network=net, subnet=subnet,
security_group=sg)
self.vm_nasa_jpl_3 = self.create_servers_on_networks(
self.cmgr_jpl, 'vm-nasa-jpl-3', self.netinfo_jpl)
self.vm_nasa_jpl_4 = self.create_servers_on_networks(
self.cmgr_jpl, 'vm-nasa-jpl-4', self.netinfo_jpl)
def create_nasa_topo(self, router_type=None):
router_type = router_type or 'shared'
self.sg_ames = self.create_security_group_policy(
self.policy_AA,
self.cmgr_ames.networks_client.tenant_id,
name_prefix='nasa-ames')
self.sg_jpl = self.create_security_group_policy(
self.policy_AA,
self.cmgr_jpl.networks_client.tenant_id,
name_prefix='nasa-jpl')
self.create_nasa_ames_network_and_servers(self.sg_ames)
self.create_nasa_jpl_network_and_servers(self.sg_jpl)
subnet_list = [self.netinfo_ames.get('subnet'),
self.netinfo_jpl.get('subnet')]
self.nasa_router = self.create_router_and_add_interfaces(
router_type, subnet_list)
self.wait_for_servers_become_active()
# associate floating-ip to servers and pingable
self.fip_nasa_ames_1 = self.create_floatingip_for_server(
self.cmgr_ames, self.vm_nasa_ames_1)
self.fip_nasa_jpl_3 = self.create_floatingip_for_server(
self.cmgr_jpl, self.vm_nasa_jpl_3)
self.find_servers_ips()
def host_ssh_reachable(self, host_id, host_ip):
username, password = self.get_image_userpass()
try:
ssh_client = dmgr.get_remote_client_by_password(
host_ip, username, password)
except Exception as ex:
ssh_client = None
msg = (self.exc_msg +
("\n**FAIL to ssh to host[%s=%s]\n%s" %
(host_id, str(ex))))
self.assertTrue(ssh_client, msg)
self.log_exc_msg(
(" SSH host[%s] floatingip[%s] OK" % (host_id, host_ip)))
return ssh_client
def host_can_reach_ips(self, host_id, host_ssh, ip_type, ip_list):
for dest_ip in ip_list:
reachable = dmgr.is_reachable(host_ssh, dest_ip,
time_out=self.conn_timeout)
msg = (self.exc_msg +
("\n *FAILURE* VM[%s] cannot PING %s[%s]" %
(host_id, ip_type, dest_ip)))
if not reachable:
reachable = dmgr.is_reachable(host_ssh, dest_ip,
time_out=self.conn_timeout)
dmgr.STEPINTO_DEBUG_IF_TRUE(not reachable)
self.assertTrue(reachable, msg)
self.log_exc_msg(
(" VM[%s] can PING %s[%s]" % (host_id, ip_type, dest_ip)))
def host_cannot_reach_ips(self, host_id, host_ssh, ip_type, ip_list):
for dest_ip in ip_list:
not_reachable = dmgr.isnot_reachable(host_ssh, dest_ip,
time_out=self.conn_timeout,
ping_timeout=5.0)
msg = (self.exc_msg +
("\n *FAILURE* VM[%s] shouldn't able to PING %s[%s]" %
(host_id, ip_type, dest_ip)))
if not not_reachable:
not_reachable = dmgr.isnot_reachable(
host_ssh, dest_ip, time_out=self.conn_timeout,
ping_timeout=5.0)
dmgr.STEPINTO_DEBUG_IF_TRUE(not not_reachable)
self.assertTrue(not_reachable, msg)
self.log_exc_msg(
(" VM[%s] is not able to PING %s[%s]" %
(host_id, ip_type, dest_ip)))
def ican_reach_ip(self, ip_addr, ping_timeout=5):
ip_type = 'floating-ip'
for x in range(int(self.conn_timeout / ping_timeout)):
reachable = self.ping_ip_address(ip_addr,
ping_timeout=ping_timeout)
if reachable:
break
time.sleep(2.0)
msg = (self.exc_msg +
("\n *FAILURE* Tempest cannot PING %s[%s]" %
(ip_type, ip_addr)))
if not reachable:
reachable = self.ping_ip_address(ip_addr,
ping_timeout=ping_timeout)
dmgr.STEPINTO_DEBUG_IF_TRUE(not reachable)
self.assertTrue(reachable, msg)
self.log_exc_msg(" Tempest can PING %s[%s]" % (ip_type, ip_addr))
def icannot_reach_ip(self, ip_addr, ping_timeout=5):
ip_type = 'floating-ip'
for x in range(int(self.conn_timeout / ping_timeout)):
reachable = self.ping_ip_address(ip_addr,
ping_timeout=ping_timeout)
if not reachable:
break
time.sleep(ping_timeout)
msg = (self.exc_msg +
("\n *FAILURE* Tempest should not PING %s[%s]" %
(ip_type, ip_addr)))
if reachable:
reachable = self.ping_ip_address(ip_addr,
ping_timeout=ping_timeout)
dmgr.STEPINTO_DEBUG_IF_TRUE(reachable)
self.assertFalse(reachable, msg)
self.log_exc_msg((" Tempest isnot able to PING %s[%s]" %
(ip_type, ip_addr)))
def run_admin_policy_op_scenario(self, router_type):
self.log_exc_msg(("Setup admin-policy test with router-type[%s]" %
router_type))
self.create_nasa_topo(router_type)
self.jpl_private_ips = [y['fixed_ip_address']
for x, y in six.iteritems(self.server_ips)
if x > '2']
self.ames_private_ips = [y['fixed_ip_address']
for x, y in six.iteritems(self.server_ips)
if x < '3']
self.run_policy_AA_on_ames_AA_on_jpl()
self.run_policy_AA_on_ames_BB_on_jpl()
self.run_policy_BB_on_ames_BB_on_jpl()
dmgr.LOG.debug(self.exc_msg)
def run_policy_AA_on_ames_AA_on_jpl(self):
self.log_exc_msg(("### tenant:jpl=policy_AA[%s]"
", tenant:ames=policy_AA[%s]" %
(self.policy_AA, self.policy_AA)))
# at the beginning, can ssh to VM with floating-ip
self.log_exc_msg(
"Tempest can ping & ssh vm-nasa-ames-1's floatingip")
self.ican_reach_ip(self.fip_nasa_ames_1['floating_ip_address'])
ames_1_ssh = self.host_ssh_reachable(
"nasa-ames-1",
self.fip_nasa_ames_1['floating_ip_address'])
# from vm-nasa-ames-1 can ping all other private-ips
self.log_exc_msg(("vm-nasa-ames-1[%s] can ping all private-ips"
% (self.server_ips['1']['fixed_ip_address'])))
self.host_can_reach_ips('nasa-ames-1', ames_1_ssh,
'ame-private-ip', self.ames_private_ips)
self.host_can_reach_ips('nasa-ames-1', ames_1_ssh,
'jp-private-ip', self.jpl_private_ips)
# from vm-nasa-jpl_3 can ping all other private-ips
self.log_exc_msg(
"Tempest can ping & ssh vm-nasa-jpl-3's floatingip")
self.ican_reach_ip(self.fip_nasa_jpl_3['floating_ip_address'])
jpl_3_ssh = self.host_ssh_reachable(
"nasa-jpl-3",
self.fip_nasa_jpl_3['floating_ip_address'])
self.log_exc_msg(("vm-nasa-jpl-3[%s] can ping all private-ips"
% (self.server_ips['3']['fixed_ip_address'])))
self.host_can_reach_ips('nasa-jpl-3', jpl_3_ssh,
'jp-private-ip', self.jpl_private_ips)
self.host_can_reach_ips('nasa-jpl-3', jpl_3_ssh,
'ames-private-ip', self.ames_private_ips)
# within VM can ping both tanants' floating-ips
self.log_exc_msg(
"vm-nasa-ames-1 can ping vm-nasa-jpl-1's floatingip")
self.host_can_reach_ips(
'nasa-ames-1', ames_1_ssh, 'jpl-floating-ip',
[self.fip_nasa_jpl_3['floating_ip_address']])
self.log_exc_msg(
"vm-nasa-jpl-3 can ping vm-nasa-ames-3's floatingip")
self.host_can_reach_ips(
'nasa-jpl-3', jpl_3_ssh, 'nasa-floating-ip',
[self.fip_nasa_ames_1['floating_ip_address']])
def run_policy_AA_on_ames_BB_on_jpl(self):
# from vm-nasa-ames-1 can ping all other private-ips
self.log_exc_msg(
("Update tenant:jpl to use policy_BB[%s] with group-ping"
% self.policy_BB))
# admin update jpl to policy_BB_GP
self.update_security_group_policy(self.sg_jpl['id'], self.policy_BB)
# cannot ping vm-nasa-jpl-3, can ssh to both tenants' floating-ips
self.log_exc_msg(("### tenant:jpl=policy_BB[%s]"
", tenant:ames=policy_AA[%s]" %
(self.policy_BB, self.policy_AA)))
self.log_exc_msg(
"Tempest can ping & ssh vm-nasa-ames-1's floatingip")
self.ican_reach_ip(self.fip_nasa_ames_1['floating_ip_address'])
ames_1_ssh = self.host_ssh_reachable(
"nasa-ames-1",
self.fip_nasa_ames_1['floating_ip_address'])
self.log_exc_msg("Tempest can ssh vm-nasa-jpl-3's floatingip"
", but not ping")
self.icannot_reach_ip(self.fip_nasa_jpl_3['floating_ip_address'])
jpl_3_ssh = self.host_ssh_reachable(
"nasa-jpl-3",
self.fip_nasa_jpl_3['floating_ip_address'])
# vm-nasa-jpl_3 can ping its private-ips, not other tenants
self.log_exc_msg(("vm-nasa-jpl-3[%s] can reach all private-ips"
% (self.server_ips['3']['fixed_ip_address'])))
self.host_can_reach_ips('nasa-jpl-3', jpl_3_ssh,
'jpl-private-ip', self.jpl_private_ips)
self.host_can_reach_ips('nasa-jpl-3', jpl_3_ssh,
'ames-private-ip', self.ames_private_ips)
# nasa_ames_1 can not ping private-ips of tenant jpl
# as policy_BB:ping only allowed from the same security-group
self.log_exc_msg(("vm-nasa-ames-1[%s] can reach ames's rivate-ips"
", not jpl's private-ips"
% (self.server_ips['1']['fixed_ip_address'])))
self.host_can_reach_ips('nasa-ames-1', ames_1_ssh,
'ames-private-ip', self.ames_private_ips)
self.host_cannot_reach_ips('nasa-ames-1', ames_1_ssh,
'jpl-private-ip', self.jpl_private_ips)
self.log_exc_msg(
"vm-nasa-ames-1 cannot ping vm-nasa-jpl-1's floatingip")
self.host_cannot_reach_ips(
'nasa-ames-1', ames_1_ssh, 'jpl-floating-ip',
[self.fip_nasa_jpl_3['floating_ip_address']])
self.log_exc_msg(
"vm-nasa-jpl-3 cannot ping vm-nasa-ames-3's floatingip")
self.host_cannot_reach_ips(
'nasa-jpl-3', jpl_3_ssh, 'ames-floating-ip',
[self.fip_nasa_ames_1['floating_ip_address']])
def run_policy_BB_on_ames_BB_on_jpl(self):
### tenant jpl:policy_BB_GP, tenant ames:policy_BB_GP
self.log_exc_msg(
("Update tenant:ames to use policy_BB[%s] with group-ping"
% self.policy_BB))
# admin update ames to policy_BB
self.update_security_group_policy(self.sg_ames['id'], self.policy_BB)
# cannot ping all VMs, but can ssh to both tenants' floating-ips
self.log_exc_msg(("### tenant:jpl=policy_BB[%s]"
", tenant:ames=policy_BB[%s]" %
(self.policy_BB, self.policy_BB)))
self.log_exc_msg("Tempest can ssh vvm-nasa-ames-1's floatingip &"
" vm-nasa-jpl-3's floatingip, but not ping.")
self.icannot_reach_ip(self.fip_nasa_ames_1['floating_ip_address'])
self.icannot_reach_ip(self.fip_nasa_jpl_3['floating_ip_address'])
ames_1_ssh = self.host_ssh_reachable(
"nasa-ames-1",
self.fip_nasa_ames_1['floating_ip_address'])
jpl_3_ssh = self.host_ssh_reachable(
"nasa-jpl-3",
self.fip_nasa_jpl_3['floating_ip_address'])
self.log_exc_msg(("vm-nasa-jpl-3[%s] can reach jpl private-ips"
", not ames"
% (self.server_ips['3']['fixed_ip_address'])))
self.host_can_reach_ips('nasa-jpl-3', jpl_3_ssh,
'private-ip', self.jpl_private_ips)
self.host_cannot_reach_ips('nasa-jpl-3', jpl_3_ssh,
'private-ip', self.ames_private_ips)
self.log_exc_msg(("vm-nasa-ames-1[%s] can reach ames private-ips"
", not jpl"
% (self.server_ips['1']['fixed_ip_address'])))
self.host_can_reach_ips('nasa-ames-1', ames_1_ssh,
'private-ip', self.ames_private_ips)
self.host_cannot_reach_ips('nasa-ames-1', ames_1_ssh,
'private-ip', self.jpl_private_ips)
self.log_exc_msg(
"vm-nasa-ames-1 cannot ping vm-nasa-jpl-1's floatingip")
self.host_cannot_reach_ips(
'nasa-ames-1', ames_1_ssh, 'floating-ip',
[self.fip_nasa_jpl_3['floating_ip_address']])
self.log_exc_msg(
"vm-nasa-jpl-3 cannot ping vm-nasa-ames-3's floatingip")
self.host_cannot_reach_ips(
'nasa-jpl-3', jpl_3_ssh, 'floating-ip',
[self.fip_nasa_ames_1['floating_ip_address']])
class TestAdminPolicySharedRouter(TestAdminPolicyBasicOps):
@decorators.idempotent_id('78f45717-5f95-4ef5-b2a4-a1b4700ef688')
def test_admin_policy_ops_with_shared_router(self):
self.run_admin_policy_op_scenario('shared')
class TestAdminPolicyExclusiveRouter(TestAdminPolicyBasicOps):
@decorators.idempotent_id('68345852-da2e-4f46-816b-0afc59470a45')
def test_admin_policy_ops_with_exclusive_router(self):
self.run_admin_policy_op_scenario('exclusive')
class TestAdminPolicyDistributedRouter(TestAdminPolicyBasicOps):
@decorators.idempotent_id('76adbfbb-a2e5-40fa-8930-84e7ece87bd5')
def test_admin_policy_ops_with_distributed_router(self):
self.run_admin_policy_op_scenario('distributed')

Some files were not shown because too many files have changed in this diff Show More