diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | INFO.yaml | 44 | ||||
-rw-r--r-- | docs/conf.py | 1 | ||||
-rw-r--r-- | docs/conf.yaml | 3 | ||||
-rw-r--r-- | docs/how-to-use/IntegrationTests.rst | 16 | ||||
-rw-r--r-- | docs/index.rst | 16 | ||||
-rw-r--r-- | docs/requirements.txt | 2 | ||||
-rw-r--r-- | examples/launch.py | 4 | ||||
-rw-r--r-- | requirements.txt | 4 | ||||
-rw-r--r-- | setup.cfg | 4 | ||||
-rw-r--r-- | snaps/config/network.py | 3 | ||||
-rw-r--r-- | snaps/openstack/create_instance.py | 7 | ||||
-rw-r--r-- | snaps/openstack/tests/create_instance_tests.py | 1 | ||||
-rw-r--r-- | snaps/openstack/tests/create_router_tests.py | 113 | ||||
-rw-r--r-- | snaps/openstack/tests/create_stack_tests.py | 1 | ||||
-rw-r--r-- | snaps/openstack/tests/create_user_tests.py | 5 | ||||
-rw-r--r-- | snaps/openstack/tests/heat/floating_ip_heat_template.yaml | 6 | ||||
-rw-r--r-- | snaps/openstack/utils/launch_utils.py | 16 | ||||
-rw-r--r-- | snaps/openstack/utils/neutron_utils.py | 9 | ||||
-rw-r--r-- | snaps/playbook_runner.py | 3 | ||||
-rw-r--r-- | snaps/provisioning/ansible_utils.py | 78 | ||||
-rw-r--r-- | snaps/provisioning/tests/ansible_utils_tests.py | 8 | ||||
-rw-r--r-- | snaps/test_runner.py | 30 | ||||
-rw-r--r-- | snaps/test_suite_builder.py | 7 | ||||
-rw-r--r-- | tox.ini | 17 |
25 files changed, 319 insertions, 81 deletions
@@ -3,3 +3,5 @@ *.*project build dist +.tox +docs/_build/* diff --git a/INFO.yaml b/INFO.yaml new file mode 100644 index 0000000..b29addf --- /dev/null +++ b/INFO.yaml @@ -0,0 +1,44 @@ +--- +project: 'SNAPS-OO' +project_creation_date: '07.02.2017' +project_category: '' +lifecycle_state: 'Incubation' +project_lead: &opnfv_snaps_ptl + name: 'Steven Pisarski' + email: 's.pisarski@cablelabs.com' + id: 'spisarski' + company: 'cablelabs.com' + timezone: 'Unknown' +primary_contact: *opnfv_snaps_ptl +issue_tracking: + type: 'jira' + url: 'https://jira.opnfv.org/projects/SNAPS' + key: 'SNAPS' +mailing_list: + type: 'mailman2' + url: 'opnfv-tech-discuss@lists.opnfv.org' + tag: '[snaps]' +realtime_discussion: + type: irc + server: 'freenode.net' + channel: '#opnfv-snaps' +meetings: + - type: 'gotomeeting+irc' + agenda: # eg: 'https://wiki.opnfv.org/display/' + url: # eg: 'https://global.gotomeeting.com/join/819733085' + server: 'freenode.net' + channel: '#opnfv-meeting' + repeats: 'weekly' + time: # eg: '16:00 UTC' +repositories: + - 'snaps' +committers: + - <<: *opnfv_snaps_ptl + - name: 'Randy Levensalor' + email: 'r.levensalor@cablelabs.com' + company: 'cablelabs.com' + id: 'RandyL' +tsc: + # yamllint disable rule:line-length + approval: 'http//meetbot.opnfv.org/meetings/opnfv-meeting/2017/opnfv-meeting.2017-02-07-15.00.html' + # yamllint enable rule:line-length diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..3c4453e --- /dev/null +++ b/docs/conf.py @@ -0,0 +1 @@ +from docs_conf.conf import * diff --git a/docs/conf.yaml b/docs/conf.yaml new file mode 100644 index 0000000..0bb596d --- /dev/null +++ b/docs/conf.yaml @@ -0,0 +1,3 @@ +--- +project_cfg: opnfv +project: SNAPS diff --git a/docs/how-to-use/IntegrationTests.rst b/docs/how-to-use/IntegrationTests.rst index bc4b706..79ef8ef 100644 --- a/docs/how-to-use/IntegrationTests.rst +++ b/docs/how-to-use/IntegrationTests.rst @@ -324,6 +324,22 @@ create_router_tests.py - CreateRouterSecurityGroupTests | | | applied to it | +---------------------------------------+---------------+-----------------------------------------------------------+ +create_router_tests.py - CreateRouterSharedNetworksTests +-------------------------------------------------------- + ++---------------------------------------+---------------+-----------------------------------------------------------+ +| Test Name | Neutron API | Description | ++=======================================+===============+===========================================================+ +| test_create_router_external | 2 | Ensures that a router can be joined to an external network| +| | | that was created by an admin user | ++---------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_router_port_external | 2 | Ensures that a router can have a port created to an | +| | | external network that was created by an admin user | ++---------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_router_port_shared | 2 | Ensures that a router can have a port created to an | +| | | shared network that was created by an admin user | ++---------------------------------------+---------------+-----------------------------------------------------------+ + create_qos_tests.py - CreateQoSTests ------------------------------------ diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..aceb2fc --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,16 @@ +.. _snaps: + +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. SPDX-License-Identifier CC-BY-4.0 +.. (c) Open Platform for NFV Project, Inc. and its contributors + +********************************* +OPNFV Snaps +********************************* + +.. toctree:: + :numbered: + :maxdepth: 3 + + /how-to-use/index diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..9fde2df --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +lfdocs-conf +sphinx_opnfv_theme diff --git a/examples/launch.py b/examples/launch.py index 04bc5d6..cfd7f65 100644 --- a/examples/launch.py +++ b/examples/launch.py @@ -32,6 +32,10 @@ logger = logging.getLogger('snaps_launcher') ARG_NOT_SET = "argument not set" +from warnings import warn +warn('This script will be removed in a subsequent release', + DeprecationWarning) + def main(arguments): """ diff --git a/requirements.txt b/requirements.txt index 160d591..6721540 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,8 +8,10 @@ python-glanceclient>=2.8.0 # Apache-2.0 python-heatclient>=1.10.0 # Apache-2.0 python-cinderclient>=3.3.0 # Apache-2.0 python-magnumclient>=2.1.0,<2.3 # Apache-2.0 -ansible<2.4,>=2.1.0 +ansible>=2.4 wrapt>=1.7.0 # BSD License scp cryptography>=2.1 # BSD/Apache-2.0 concurrencytest +Jinja2 # BSD License (3 clause) +keystoneauth1 # Apache-2.0 @@ -1,6 +1,6 @@ [metadata] -name = snaps -version = 1.0 +name = snaps-oo +version = 7.0.0 home-page = https://gerrit.opnfv.org/gerrit/gitweb?p=snaps.git;a=summary author = Steve Pisarski author-email = s.pisarski@cablelabs.com diff --git a/snaps/config/network.py b/snaps/config/network.py index 620640f..b142480 100644 --- a/snaps/config/network.py +++ b/snaps/config/network.py @@ -449,7 +449,6 @@ class PortConfig(object): TODO - expand automated testing to exercise all parameters :param neutron: the Neutron client - :param keystone: the Keystone client :param os_creds: the OpenStack credentials :return: the dictionary object """ @@ -463,7 +462,7 @@ class PortConfig(object): try: network = neutron_utils.get_network( neutron, keystone, network_name=self.network_name) - if network and not network.shared: + if network and not (network.shared or network.external): network = neutron_utils.get_network( neutron, keystone, network_name=self.network_name, project_name=project_name) diff --git a/snaps/openstack/create_instance.py b/snaps/openstack/create_instance.py index 16bd0ce..b158a25 100644 --- a/snaps/openstack/create_instance.py +++ b/snaps/openstack/create_instance.py @@ -474,9 +474,12 @@ class OpenStackVmInstance(OpenStackComputeObject): playbook :param fip_name: the name of the floating IP to use for applying the playbook (default - will take the first) - :return: the return value from ansible """ - return ansible_utils.apply_playbook( + from warnings import warn + warn('This method will be removed in a subsequent release', + DeprecationWarning) + + ansible_utils.apply_playbook( pb_file_loc, [self.get_floating_ip(fip_name=fip_name).ip], self.get_image_user(), ssh_priv_key_file_path=self.keypair_settings.private_filepath, diff --git a/snaps/openstack/tests/create_instance_tests.py b/snaps/openstack/tests/create_instance_tests.py index 0becbf4..17831b3 100644 --- a/snaps/openstack/tests/create_instance_tests.py +++ b/snaps/openstack/tests/create_instance_tests.py @@ -1364,6 +1364,7 @@ class CreateInstanceIPv6NetworkTests(OSIntegrationTestCase): keypair_settings=self.keypair_creator.keypair_settings) self.inst_creator.create(block=True) + self.inst_creator.cloud_init_complete(block=True) ssh_client = self.inst_creator.ssh_client() self.assertIsNotNone(ssh_client) diff --git a/snaps/openstack/tests/create_router_tests.py b/snaps/openstack/tests/create_router_tests.py index 80e9078..a305cf8 100644 --- a/snaps/openstack/tests/create_router_tests.py +++ b/snaps/openstack/tests/create_router_tests.py @@ -21,8 +21,8 @@ from snaps.config.security_group import SecurityGroupConfig from snaps.openstack import create_network from snaps.openstack import create_router from snaps.openstack.create_network import OpenStackNetwork -from snaps.openstack.create_router import (RouterSettings, OpenStackRouter, - RouterCreationError) +from snaps.openstack.create_router import ( + RouterSettings, OpenStackRouter, RouterCreationError) from snaps.openstack.create_security_group import OpenStackSecurityGroup from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase from snaps.openstack.utils import neutron_utils, settings_utils, keystone_utils @@ -31,6 +31,7 @@ __author__ = 'mmakati' cidr1 = '10.200.201.0/24' cidr2 = '10.200.202.0/24' +cidr3 = '10.200.203.0/24' static_gateway_ip1 = '10.200.201.1' static_gateway_ip2 = '10.200.202.1' @@ -285,7 +286,7 @@ class CreateRouterSuccessTests(OSIntegrationTestCase): self.os_creds, self.router_settings) with self.assertRaises(RouterCreationError): - created_router = self.router_creator.create() + self.router_creator.create() def test_create_router_admin_state_false(self): """ @@ -764,3 +765,109 @@ class CreateRouterSecurityGroupTests(OSIntegrationTestCase): self.router_creator = create_router.OpenStackRouter( self.os_creds, router_settings) self.router_creator.create() + + +class CreateRouterSharedNetworksTests(OSIntegrationTestCase): + """ + Class for testing routers external and/or shared networks + """ + + def setUp(self): + """ + Initializes objects used for router testing + """ + super(self.__class__, self).__start__() + + self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) + self.router_creator = None + + ext_network_settings = NetworkConfig( + name=self.guid + '-ext-net', + external=True, + subnet_settings=[ + create_network.SubnetConfig( + cidr=cidr1, name=self.guid + '-ext-subnet1')]) + self.ext_network_creator = OpenStackNetwork( + self.admin_os_creds, ext_network_settings) + self.ext_network_creator.create() + + shared_network_settings = NetworkConfig( + name=self.guid + '-shared-net', + shared=True, + subnet_settings=[ + create_network.SubnetConfig( + cidr=cidr2, name=self.guid + '-shared-subnet1')]) + self.shared_network_creator = OpenStackNetwork( + self.admin_os_creds, shared_network_settings) + self.shared_network_creator.create() + + overlay_network_settings = NetworkConfig( + name=self.guid + '-overlay-net', + subnet_settings=[ + create_network.SubnetConfig( + cidr=cidr3, name=self.guid + '-overlay-subnet1')]) + self.overlay_network_creator = OpenStackNetwork( + self.os_creds, overlay_network_settings) + self.overlay_network_creator.create() + + self.neutron = neutron_utils.neutron_client( + self.os_creds, self.os_session) + + def tearDown(self): + """ + Cleans the remote OpenStack objects used for router testing + """ + if self.router_creator: + self.router_creator.clean() + + if self.overlay_network_creator: + self.overlay_network_creator.clean() + + if self.shared_network_creator: + self.shared_network_creator.clean() + + if self.ext_network_creator: + self.ext_network_creator.clean() + + super(self.__class__, self).__clean__() + + def test_create_router_external(self): + """ + Test creation of a router with a custom external network created by + admin. + """ + router_settings = RouterConfig( + name=self.guid + '-pub-router', + external_gateway=self.ext_network_creator.get_network().name) + self.router_creator = create_router.OpenStackRouter( + self.os_creds, router_settings) + self.router_creator.create() + + def test_create_router_port_external(self): + """ + Test creation of a router with a port to an custom external network + created by admin. + """ + router_settings = RouterConfig( + name=self.guid + '-pub-router', + network_name=self.ext_network_creator.get_network().name) + self.router_creator = create_router.OpenStackRouter( + self.os_creds, router_settings) + self.router_creator.create() + + def test_create_router_port_shared(self): + """ + Test creation of a router with a port to an custom shared network + created by admin. + """ + port_settings = [ + create_network.PortConfig( + name=self.guid + '-port1', + network_name=self.shared_network_creator.get_network().name)] + + router_settings = RouterConfig( + name=self.guid + '-pub-router', + port_settings=port_settings) + self.router_creator = create_router.OpenStackRouter( + self.os_creds, router_settings) + self.router_creator.create() diff --git a/snaps/openstack/tests/create_stack_tests.py b/snaps/openstack/tests/create_stack_tests.py index be4d6ea..7da5bc7 100644 --- a/snaps/openstack/tests/create_stack_tests.py +++ b/snaps/openstack/tests/create_stack_tests.py @@ -448,6 +448,7 @@ class CreateStackFloatingIpTests(OSIntegrationTestCase): 'image2_name': self.image_creator.image_settings.name, 'flavor1_name': self.flavor1_name, 'flavor2_name': self.flavor2_name, + 'flavor_extra_specs': self.flavor_metadata, 'net_name': self.network_name, 'subnet_name': self.subnet_name, 'inst1_name': self.vm_inst1_name, diff --git a/snaps/openstack/tests/create_user_tests.py b/snaps/openstack/tests/create_user_tests.py index 718d5a3..c15a71f 100644 --- a/snaps/openstack/tests/create_user_tests.py +++ b/snaps/openstack/tests/create_user_tests.py @@ -106,7 +106,8 @@ class CreateUserSuccessTests(OSComponentTestCase): self.user_settings = UserConfig( name=guid + '-name', password=guid + '-password', - roles={'admin': self.os_creds.project_name}, + roles={'admin': self.os_creds.project_name, + 'Admin': self.os_creds.project_name}, domain_name=self.os_creds.user_domain_name) self.keystone = keystone_utils.keystone_client(self.os_creds, self.os_session) @@ -183,6 +184,8 @@ class CreateUserSuccessTests(OSComponentTestCase): self.assertEqual(created_user, retrieved_user) role = keystone_utils.get_role_by_name(self.keystone, 'admin') + if not role: + role = keystone_utils.get_role_by_name(self.keystone, 'Admin') self.assertIsNotNone(role) os_proj = keystone_utils.get_project( diff --git a/snaps/openstack/tests/heat/floating_ip_heat_template.yaml b/snaps/openstack/tests/heat/floating_ip_heat_template.yaml index 40626b9..e64c7fc 100644 --- a/snaps/openstack/tests/heat/floating_ip_heat_template.yaml +++ b/snaps/openstack/tests/heat/floating_ip_heat_template.yaml @@ -41,6 +41,10 @@ parameters: label: Instance Flavor for second VM description: Flavor name for the second instance default: m1.med + flavor_extra_specs: + type: json + description: Instance Flavor extra specs + default: {} net_name: type: string label: Test network name @@ -88,12 +92,14 @@ resources: ram: 1024 vcpus: 2 disk: 2 + extra_specs: { get_param: flavor_extra_specs } flavor2: type: OS::Nova::Flavor properties: ram: 1024 vcpus: 2 disk: 2 + extra_specs: { get_param: flavor_extra_specs } network: type: OS::Neutron::Net diff --git a/snaps/openstack/utils/launch_utils.py b/snaps/openstack/utils/launch_utils.py index 00ea822..ddaad12 100644 --- a/snaps/openstack/utils/launch_utils.py +++ b/snaps/openstack/utils/launch_utils.py @@ -53,6 +53,10 @@ from snaps.openstack.utils import deploy_utils, neutron_utils, keystone_utils from snaps.openstack.utils.nova_utils import RebootType from snaps.provisioning import ansible_utils +from warnings import warn +warn('This utility will be removed in a subsequent release', + DeprecationWarning) + logger = logging.getLogger('lanuch_utils') DEFAULT_CREDS_KEY = 'admin' @@ -464,17 +468,13 @@ def __apply_ansible_playbook(ansible_config, os_creds_dict, vm_dict, ansible_config.get('variables'), os_creds_dict, vm_dict, image_dict, flavor_dict, networks_dict, routers_dict) - retval = ansible_utils.apply_playbook( + ansible_utils.apply_playbook( ansible_config['playbook_location'], floating_ips, remote_user, ssh_priv_key_file_path=private_key_filepath, variables=variables, proxy_setting=proxy_settings) - if retval != 0: - # Not a fatal type of event - raise Exception( - 'Error applying playbook found at location - %s', - ansible_config.get('playbook_location')) - elif ansible_config.get('post_processing'): + + if 'post_processing' in ansible_config: post_proc_config = ansible_config['post_processing'] if 'sleep' in post_proc_config: time.sleep(post_proc_config['sleep']) @@ -484,8 +484,6 @@ def __apply_ansible_playbook(ansible_config, os_creds_dict, vm_dict, logger.info('Rebooting VM - %s', vm_name) vm_dict[vm_name].reboot(RebootType.hard) - return retval - def __get_connection_info(ansible_config, vm_dict): """ diff --git a/snaps/openstack/utils/neutron_utils.py b/snaps/openstack/utils/neutron_utils.py index d82bbf6..f1a5ac2 100644 --- a/snaps/openstack/utils/neutron_utils.py +++ b/snaps/openstack/utils/neutron_utils.py @@ -544,8 +544,11 @@ def get_port(neutron, keystone, port_settings=None, port_name=None, project_name = port_settings.project_name if port_settings.network_name: network = get_network( - neutron, keystone, network_name=port_settings.network_name, - project_name=project_name) + neutron, keystone, network_name=port_settings.network_name) + if network and not (network.shared or network.external): + network = get_network( + neutron, keystone, network_name=port_settings.network_name, + project_name=project_name) if network: port_filter['network_id'] = network.id elif port_name: @@ -887,7 +890,7 @@ def __get_os_floating_ip(neutron, floating_ip): """ logger.debug('Attempting to retrieve existing floating ip with IP - %s', floating_ip.ip) - fips = neutron.list_floatingips(ip=floating_ip.id) + fips = neutron.list_floatingips(floating_ip_address=floating_ip.ip) for fip in fips['floatingips']: if fip['id'] == floating_ip.id: diff --git a/snaps/playbook_runner.py b/snaps/playbook_runner.py index 03b7006..7b10390 100644 --- a/snaps/playbook_runner.py +++ b/snaps/playbook_runner.py @@ -67,12 +67,11 @@ def main(parsed_args): if not variables.get('env_file'): variables['env_file'] = parsed_args.env_file - retval = ansible_utils.apply_playbook( + ansible_utils.apply_playbook( parsed_args.playbook, [parsed_args.ip_addr], parsed_args.host_user, ssh_priv_key_file_path=parsed_args.priv_key, password=parsed_args.password, variables=variables, proxy_setting=proxy_settings) - exit(retval) if __name__ == '__main__': diff --git a/snaps/provisioning/ansible_utils.py b/snaps/provisioning/ansible_utils.py index 83fe449..019a8e7 100644 --- a/snaps/provisioning/ansible_utils.py +++ b/snaps/provisioning/ansible_utils.py @@ -21,49 +21,58 @@ import paramiko try: from ansible.parsing.dataloader import DataLoader - from ansible.vars import VariableManager - from ansible.inventory import Inventory + from ansible.vars.manager import VariableManager + from ansible.inventory.manager import InventoryManager from ansible.executor.playbook_executor import PlaybookExecutor except: pass __author__ = 'spisarski' +from warnings import warn +warn('This utility will be removed in a subsequent release', + DeprecationWarning) + logger = logging.getLogger('ansible_utils') -def apply_playbook(playbook_path, hosts_inv, host_user, +def apply_playbook(playbook_path, hosts_inv=None, host_user=None, ssh_priv_key_file_path=None, password=None, variables=None, proxy_setting=None): """ Executes an Ansible playbook to the given host :param playbook_path: the (relative) path to the Ansible playbook :param hosts_inv: a list of hostnames/ip addresses to which to apply the - Ansible playbook + Ansible playbook (not required when PB is configured for + localhost) :param host_user: A user for the host instances (must be a password-less - sudo user if playbook has "sudo: yes" + sudo user if playbook has "sudo: yes") (not required when + PB is configured for localhost) :param ssh_priv_key_file_path: the file location of the ssh key. Required - if password is None + if password is None (not required when PB is + configured for localhost) :param password: the file location of the ssh key. Required if - ssh_priv_key_file_path is None + ssh_priv_key_file_path is None (not required when PB is + configured for localhost) :param variables: a dictionary containing any substitution variables needed by the Jinga 2 templates :param proxy_setting: instance of os_credentials.ProxySettings class - :return: the results + :raises AnsibleException when the return code from the Ansible library is + not 0 + :return: the return code from the Ansible library only when 0. + Implementation now raises an exception otherwise """ if not os.path.isfile(playbook_path): - raise AnsibleException('Requested playbook not found - ' + playbook_path) + raise AnsibleException( + 'Requested playbook not found - ' + playbook_path) pk_file_path = None if ssh_priv_key_file_path: pk_file_path = os.path.expanduser(ssh_priv_key_file_path) if not password: if not os.path.isfile(pk_file_path): - raise AnsibleException('Requested private SSH key not found - ' + - pk_file_path) - - if not ssh_priv_key_file_path and not password: - raise AnsibleException('Invalid credentials, no priv key or password') + raise AnsibleException( + 'Requested private SSH key not found - ' + pk_file_path) passwords = None if password: @@ -72,15 +81,20 @@ def apply_playbook(playbook_path, hosts_inv, host_user, import ansible.constants ansible.constants.HOST_KEY_CHECKING = False - variable_manager = VariableManager() + loader = DataLoader() + inventory = InventoryManager(loader=loader) + if hosts_inv: + for host in hosts_inv: + inventory.add_host(host=host, group='ungrouped') + connection = 'ssh' + else: + connection = 'local' + + variable_manager = VariableManager(loader=loader, inventory=inventory) + if variables: variable_manager.extra_vars = variables - loader = DataLoader() - inventory = Inventory(loader=loader, variable_manager=variable_manager, - host_list=hosts_inv) - variable_manager.set_inventory(inventory) - ssh_extra_args = None if proxy_setting and proxy_setting.ssh_proxy_cmd: ssh_extra_args = '-o ProxyCommand=\'%s\'' % proxy_setting.ssh_proxy_cmd @@ -90,14 +104,15 @@ def apply_playbook(playbook_path, hosts_inv, host_user, 'connection', 'module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'become', 'become_method', 'become_user', 'verbosity', - 'check', 'timeout']) + 'check', 'timeout', 'diff']) ansible_opts = options( listtags=False, listtasks=False, listhosts=False, syntax=False, - connection='ssh', module_path=None, forks=100, remote_user=host_user, - private_key_file=pk_file_path, ssh_common_args=None, - ssh_extra_args=ssh_extra_args, become=None, become_method=None, - become_user=None, verbosity=11111, check=False, timeout=30) + connection=connection, module_path=None, forks=100, + remote_user=host_user, private_key_file=pk_file_path, + ssh_common_args=None, ssh_extra_args=ssh_extra_args, become=None, + become_method=None, become_user=None, verbosity=11111, check=False, + timeout=30, diff=None) logger.debug('Setting up Ansible Playbook Executor for playbook - ' + playbook_path) @@ -110,7 +125,15 @@ def apply_playbook(playbook_path, hosts_inv, host_user, passwords=passwords) logger.debug('Executing Ansible Playbook - ' + playbook_path) - return executor.run() + ret_val = executor.run() + + if ret_val != 0: + raise AnsibleException( + 'Error applying playbook [{}] with value [{}] using the connection' + ' type of [{}]'.format( + playbook_path, ret_val, connection)) + + return ret_val def ssh_client(ip, user, private_key_filepath=None, password=None, @@ -143,9 +166,10 @@ def ssh_client(ip, user, private_key_filepath=None, password=None, ssh.connect( ip, username=user, key_filename=pk_abs_path, password=password, sock=proxy_cmd) + logger.info('Obtained SSH connection to %s', ip) return ssh except Exception as e: - logger.warning('Unable to connect via SSH with message - ' + str(e)) + logger.debug('Unable to connect via SSH with message - ' + str(e)) class AnsibleException(Exception): diff --git a/snaps/provisioning/tests/ansible_utils_tests.py b/snaps/provisioning/tests/ansible_utils_tests.py index 209b1e0..b6ace31 100644 --- a/snaps/provisioning/tests/ansible_utils_tests.py +++ b/snaps/provisioning/tests/ansible_utils_tests.py @@ -91,7 +91,7 @@ class AnsibleProvisioningTests(OSIntegrationTestCase): self.pub_net_config = openstack_tests.get_pub_net_config( project_name=self.os_creds.project_name, net_name=guid + '-pub-net', - mtu=1450, subnet_name=guid + '-pub-subnet', + mtu=1442, subnet_name=guid + '-pub-subnet', router_name=guid + '-pub-router', external_net=self.ext_net_name) @@ -265,8 +265,7 @@ class AnsibleProvisioningTests(OSIntegrationTestCase): relative_pb_path = pkg_resources.resource_filename( 'snaps.provisioning.tests.playbooks', 'simple_playbook.yml') - retval = self.inst_creator.apply_ansible_playbook(relative_pb_path) - self.assertEqual(0, retval) + self.inst_creator.apply_ansible_playbook(relative_pb_path) ssh = ansible_utils.ssh_client( ip, user, private_key_filepath=priv_key, @@ -332,9 +331,8 @@ class AnsibleProvisioningTests(OSIntegrationTestCase): relative_pb_path = pkg_resources.resource_filename( 'snaps.provisioning.tests.playbooks', 'template_playbook.yml') - retval = self.inst_creator.apply_ansible_playbook( + self.inst_creator.apply_ansible_playbook( relative_pb_path, variables={'name': 'Foo'}) - self.assertEqual(0, retval) ssh = ansible_utils.ssh_client( ip, user, private_key_filepath=priv_key, diff --git a/snaps/test_runner.py b/snaps/test_runner.py index cddfdef..d46fe86 100644 --- a/snaps/test_runner.py +++ b/snaps/test_runner.py @@ -13,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. import argparse -import json import logging import unittest from concurrencytest import ConcurrentTestSuite, fork_for_tests @@ -36,8 +35,7 @@ def __create_concurrent_test_suite( source_filename, ext_net_name, proxy_settings, ssh_proxy_cmd, run_unit_tests, run_connection_tests, run_api_tests, run_integration_tests, run_staging_tests, flavor_metadata, - image_metadata, use_keystone, use_floating_ips, continuous_integration, - log_level): + image_metadata, use_floating_ips, continuous_integration, log_level): """ Compiles the tests that can be run concurrently :param source_filename: the OpenStack credentials file (required) @@ -58,9 +56,6 @@ def __create_concurrent_test_suite( created for test VM instance :param image_metadata: dict() object containing the metadata for overriding default images within the tests - :param use_keystone: when true, tests creating users and projects will be - exercised and must be run on a host that - has access to the cloud's administrative network :param use_floating_ips: when true, tests requiring floating IPs will be executed :param continuous_integration: when true, tests for CI will be run @@ -81,20 +76,20 @@ def __create_concurrent_test_suite( if run_connection_tests: tsb.add_openstack_client_tests( suite=suite, os_creds=os_creds, ext_net_name=ext_net_name, - use_keystone=use_keystone, log_level=log_level) + use_keystone=True, log_level=log_level) # Tests the OpenStack API calls if run_api_tests: tsb.add_openstack_api_tests( suite=suite, os_creds=os_creds, ext_net_name=ext_net_name, - use_keystone=use_keystone, flavor_metadata=flavor_metadata, + use_keystone=True, flavor_metadata=flavor_metadata, image_metadata=image_metadata, log_level=log_level) # Long running integration type tests if run_integration_tests: tsb.add_openstack_integration_tests( suite=suite, os_creds=os_creds, ext_net_name=ext_net_name, - use_keystone=use_keystone, flavor_metadata=flavor_metadata, + use_keystone=True, flavor_metadata=flavor_metadata, image_metadata=image_metadata, use_floating_ips=use_floating_ips, log_level=log_level) @@ -106,7 +101,7 @@ def __create_concurrent_test_suite( if continuous_integration: tsb.add_openstack_ci_tests( suite=suite, os_creds=os_creds, ext_net_name=ext_net_name, - use_keystone=use_keystone, flavor_metadata=flavor_metadata, + use_keystone=True, flavor_metadata=flavor_metadata, image_metadata=image_metadata, use_floating_ips=use_floating_ips, log_level=log_level) return suite @@ -114,7 +109,7 @@ def __create_concurrent_test_suite( def __create_sequential_test_suite( source_filename, ext_net_name, proxy_settings, ssh_proxy_cmd, - run_integration_tests, flavor_metadata, image_metadata, use_keystone, + run_integration_tests, flavor_metadata, image_metadata, use_floating_ips, log_level): """ Compiles the tests that cannot be run in parallel @@ -129,9 +124,6 @@ def __create_sequential_test_suite( created for test VM instance :param image_metadata: dict() object containing the metadata for overriding default images within the tests - :param use_keystone: when true, tests creating users and projects will be - exercised and must be run on a host that - has access to the cloud's administrative network :param use_floating_ips: when true, tests requiring floating IPs will be executed :param log_level: the logging level @@ -146,7 +138,7 @@ def __create_sequential_test_suite( tsb.add_ansible_integration_tests( suite=suite, os_creds=os_creds, ext_net_name=ext_net_name, - use_keystone=use_keystone, flavor_metadata=flavor_metadata, + use_keystone=True, flavor_metadata=flavor_metadata, image_metadata=image_metadata, log_level=log_level) return suite @@ -213,7 +205,6 @@ def main(arguments): arguments.env, arguments.ext_net, arguments.proxy, arguments.ssh_proxy_cmd, unit, connection, api, integration, staging, flavor_metadata, image_metadata, - arguments.use_keystone != ARG_NOT_SET, arguments.floating_ips != ARG_NOT_SET, ci, log_level) @@ -223,7 +214,6 @@ def main(arguments): arguments.env, arguments.ext_net, arguments.proxy, arguments.ssh_proxy_cmd, integration, flavor_metadata, image_metadata, - arguments.use_keystone != ARG_NOT_SET, arguments.floating_ips != ARG_NOT_SET, log_level) else: logger.error('Environment file or external network not defined') @@ -315,12 +305,6 @@ if __name__ == '__main__': nargs='?', help='When argument is set, all integration tests requiring' ' Floating IPs will be executed') parser.add_argument( - '-k', '--use-keystone', dest='use_keystone', default=ARG_NOT_SET, - nargs='?', - help='When argument is set, the tests will exercise the keystone APIs ' - 'and must be run on a machine that has access to the admin ' - 'network and is able to create users and groups') - parser.add_argument( '-fm', '--flavor-meta', dest='flavor_metadata', help='hw:mem_page_size flavor setting value (i.e. large). ' 'Required for DPDK') diff --git a/snaps/test_suite_builder.py b/snaps/test_suite_builder.py index 1fe1f8a..52008a6 100644 --- a/snaps/test_suite_builder.py +++ b/snaps/test_suite_builder.py @@ -86,7 +86,7 @@ from snaps.openstack.tests.create_qos_tests import ( from snaps.openstack.tests.create_router_tests import ( CreateRouterSuccessTests, CreateRouterNegativeTests, RouterSettingsUnitTests, CreateMultipleRouterTests, - CreateRouterSecurityGroupTests) + CreateRouterSecurityGroupTests, CreateRouterSharedNetworksTests) from snaps.openstack.tests.create_security_group_tests import ( CreateSecurityGroupTests, SecurityGroupRuleSettingsUnitTests, SecurityGroupSettingsUnitTests, CreateMultipleSecurityGroupTests) @@ -546,6 +546,11 @@ def add_openstack_integration_tests(suite, os_creds, ext_net_name, flavor_metadata=flavor_metadata, image_metadata=image_metadata, log_level=log_level)) suite.addTest(OSIntegrationTestCase.parameterize( + CreateRouterSharedNetworksTests, os_creds=os_creds, + ext_net_name=ext_net_name, use_keystone=use_keystone, + flavor_metadata=flavor_metadata, image_metadata=image_metadata, + log_level=log_level)) + suite.addTest(OSIntegrationTestCase.parameterize( CreateQoSTests, os_creds=os_creds, ext_net_name=ext_net_name, use_keystone=use_keystone, flavor_metadata=flavor_metadata, image_metadata=image_metadata, @@ -0,0 +1,17 @@ +[tox] +minversion = 1.6 +envlist = + docs, + docs-linkcheck +skipsdist = true + +[testenv:docs] +deps = -rdocs/requirements.txt +commands = + sphinx-build -b html -n -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html + echo "Generated docs available in {toxinidir}/docs/_build/html" +whitelist_externals = echo + +[testenv:docs-linkcheck] +deps = -rdocs/requirements.txt +commands = sphinx-build -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck |