From 2bff1a133a7534ed487bc8ef43466d2f7636175e Mon Sep 17 00:00:00 2001 From: ghanshyam Date: Tue, 26 Jul 2016 18:27:45 +0900 Subject: [PATCH] Remove deprecated Javelin CLI utilities from Tempest Javelin CLI utilities has been deprecated in Jan 2016 - Ie4ab5258946271a16e96a070abeedfafa5423714 which is over 6 months of Tempest deprecation period. This patch removes the javelin CLI and corresponding doc/sample files etc. Change-Id: Ia59d3e81f245f29a7bf0f56b690586dfc55f16a0 --- doc/source/index.rst | 1 - doc/source/javelin.rst | 5 - etc/javelin-resources.yaml.sample | 63 - .../remove-javelin-276f62d04f7e4a1d.yaml | 5 + setup.cfg | 1 - tempest/cmd/javelin.py | 1131 ----------------- tempest/cmd/resources.yaml | 95 -- tempest/tests/cmd/test_javelin.py | 422 ------ 8 files changed, 5 insertions(+), 1718 deletions(-) delete mode 100644 doc/source/javelin.rst delete mode 100644 etc/javelin-resources.yaml.sample create mode 100644 releasenotes/notes/remove-javelin-276f62d04f7e4a1d.yaml delete mode 100755 tempest/cmd/javelin.py delete mode 100644 tempest/cmd/resources.yaml delete mode 100644 tempest/tests/cmd/test_javelin.py diff --git a/doc/source/index.rst b/doc/source/index.rst index f1ede06bff..6abe9dc4b7 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -50,7 +50,6 @@ Command Documentation account_generator cleanup - javelin subunit_describe_calls workspace run diff --git a/doc/source/javelin.rst b/doc/source/javelin.rst deleted file mode 100644 index 01090caa5a..0000000000 --- a/doc/source/javelin.rst +++ /dev/null @@ -1,5 +0,0 @@ ----------------------------------------------------------- -Javelin2 - How to check that resources survived an upgrade ----------------------------------------------------------- - -.. automodule:: tempest.cmd.javelin diff --git a/etc/javelin-resources.yaml.sample b/etc/javelin-resources.yaml.sample deleted file mode 100644 index 1565686b51..0000000000 --- a/etc/javelin-resources.yaml.sample +++ /dev/null @@ -1,63 +0,0 @@ -tenants: - - javelin - - discuss - -users: - - name: javelin - pass: gungnir - tenant: javelin - - name: javelin2 - pass: gungnir2 - tenant: discuss - -secgroups: - - name: secgroup1 - owner: javelin - description: SecurityGroup1 - rules: - - 'icmp -1 -1 0.0.0.0/0' - - 'tcp 22 22 0.0.0.0/0' - - name: secgroup2 - owner: javelin2 - description: SecurityGroup2 - rules: - - 'tcp 80 80 0.0.0.0/0' - -images: - - name: cirros1 - owner: javelin - imgdir: images - file: cirros.img - container_format: bare - disk_format: qcow2 - - name: cirros2 - owner: javelin2 - imgdir: files/images/cirros-0.3.2-x86_64-uec - file: cirros-0.3.2-x86_64-blank.img - container_format: ami - disk_format: ami - aki: cirros-0.3.2-x86_64-vmlinuz - ari: cirros-0.3.2-x86_64-initrd - -networks: - - name: network1 - owner: javelin - - name: network2 - owner: javelin2 - -subnets: - - name: net1-subnet1 - range: 10.1.0.0/24 - network: network1 - owner: javelin - - name: net2-subnet2 - range: 192.168.1.0/24 - network: network2 - owner: javelin2 - -objects: - - container: container1 - name: object1 - owner: javelin - file: /etc/hosts - swift_role: Member diff --git a/releasenotes/notes/remove-javelin-276f62d04f7e4a1d.yaml b/releasenotes/notes/remove-javelin-276f62d04f7e4a1d.yaml new file mode 100644 index 0000000000..8e893b8dcd --- /dev/null +++ b/releasenotes/notes/remove-javelin-276f62d04f7e4a1d.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - The previously deprecated Javelin utility has been removed from Tempest. + As an alternative Ansible can be used to construct similar yaml workflows + to what Javelin used to provide. diff --git a/setup.cfg b/setup.cfg index 2a3000dad0..91ede20158 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,7 +27,6 @@ data_files = [entry_points] console_scripts = verify-tempest-config = tempest.cmd.verify_tempest_config:main - javelin2 = tempest.cmd.javelin:main run-tempest-stress = tempest.cmd.run_stress:main tempest-cleanup = tempest.cmd.cleanup:main tempest-account-generator = tempest.cmd.account_generator:main diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py deleted file mode 100755 index a9e5167c59..0000000000 --- a/tempest/cmd/javelin.py +++ /dev/null @@ -1,1131 +0,0 @@ -#!/usr/bin/env python -# -# 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. - -"""Javelin is a tool for creating, verifying, and deleting a small set of -resources in a declarative way. - -Javelin is meant to be used as a way to validate quickly that resources can -survive an upgrade process. - -Authentication --------------- - -Javelin will be creating (and removing) users and tenants so it needs the admin -credentials of your cloud to operate properly. The corresponding info can be -given the usual way, either through CLI options or environment variables. - -You're probably familiar with these, but just in case:: - - +----------+------------------+----------------------+ - | Param | CLI | Environment Variable | - +----------+------------------+----------------------+ - | Username | --os-username | OS_USERNAME | - | Password | --os-password | OS_PASSWORD | - | Tenant | --os-tenant-name | OS_TENANT_NAME | - +----------+------------------+----------------------+ - - -Runtime Arguments ------------------ - -**-m/--mode**: (Required) Has to be one of 'check', 'create' or 'destroy'. It -indicates which actions javelin is going to perform. - -**-r/--resources**: (Required) The path to a YAML file describing the resources -used by Javelin. - -**-d/--devstack-base**: (Required) The path to the devstack repo used to -retrieve artefacts (like images) that will be referenced in the resource files. - -**-c/--config-file**: (Optional) The path to a valid Tempest config file -describing your cloud. Javelin may use this to determine if certain services -are enabled and modify its behavior accordingly. - - -Resource file -------------- - -The resource file is a valid YAML file describing the resources that will be -created, checked and destroyed by javelin. Here's a canonical example of a -resource file:: - - tenants: - - javelin - - discuss - - users: - - name: javelin - pass: gungnir - tenant: javelin - - name: javelin2 - pass: gungnir2 - tenant: discuss - - # resources that we want to create - images: - - name: javelin_cirros - owner: javelin - file: cirros-0.3.2-x86_64-blank.img - disk_format: ami - container_format: ami - aki: cirros-0.3.2-x86_64-vmlinuz - ari: cirros-0.3.2-x86_64-initrd - - servers: - - name: peltast - owner: javelin - flavor: m1.small - image: javelin_cirros - floating_ip_pool: public - - name: hoplite - owner: javelin - flavor: m1.medium - image: javelin_cirros - - -An important piece of the resource definition is the *owner* field, which is -the user (that we've created) that is the owner of that resource. All -operations on that resource will happen as that regular user to ensure that -admin level access does not mask issues. - -The check phase will act like a unit test, using well known assert methods to -verify that the correct resources exist. - -""" - -import argparse -import collections -import datetime -import os -import sys -import unittest - -import netaddr -from oslo_log import log as logging -import six -import yaml - -from tempest.common import identity -from tempest.common import waiters -from tempest import config -from tempest.lib import auth -from tempest.lib import exceptions as lib_exc -from tempest.lib.services.compute import flavors_client -from tempest.lib.services.compute import floating_ips_client -from tempest.lib.services.compute import security_group_rules_client -from tempest.lib.services.compute import security_groups_client -from tempest.lib.services.compute import servers_client -from tempest.lib.services.identity.v2 import roles_client -from tempest.lib.services.identity.v2 import tenants_client -from tempest.lib.services.identity.v2 import users_client -from tempest.lib.services.image.v2 import images_client -from tempest.lib.services.network import networks_client -from tempest.lib.services.network import ports_client -from tempest.lib.services.network import routers_client -from tempest.lib.services.network import subnets_client -from tempest.services.identity.v2.json import identity_client -from tempest.services.object_storage import container_client -from tempest.services.object_storage import object_client -from tempest.services.volume.v1.json import volumes_client - -CONF = config.CONF -OPTS = {} -USERS = {} -RES = collections.defaultdict(list) - -LOG = None - -JAVELIN_START = datetime.datetime.utcnow() - - -class OSClient(object): - _creds = None - identity = None - servers = None - - def __init__(self, user, pw, tenant): - default_params = { - 'disable_ssl_certificate_validation': - CONF.identity.disable_ssl_certificate_validation, - 'ca_certs': CONF.identity.ca_certificates_file, - 'trace_requests': CONF.debug.trace_requests - } - default_params_with_timeout_values = { - 'build_interval': CONF.compute.build_interval, - 'build_timeout': CONF.compute.build_timeout - } - default_params_with_timeout_values.update(default_params) - - compute_params = { - 'service': CONF.compute.catalog_type, - 'region': CONF.compute.region or CONF.identity.region, - 'endpoint_type': CONF.compute.endpoint_type, - 'build_interval': CONF.compute.build_interval, - 'build_timeout': CONF.compute.build_timeout - } - compute_params.update(default_params) - - object_storage_params = { - 'service': CONF.object_storage.catalog_type, - 'region': CONF.object_storage.region or CONF.identity.region, - 'endpoint_type': CONF.object_storage.endpoint_type - } - object_storage_params.update(default_params) - - _creds = auth.KeystoneV2Credentials( - username=user, - password=pw, - tenant_name=tenant) - auth_provider_params = { - 'disable_ssl_certificate_validation': - CONF.identity.disable_ssl_certificate_validation, - 'ca_certs': CONF.identity.ca_certificates_file, - 'trace_requests': CONF.debug.trace_requests - } - _auth = auth.KeystoneV2AuthProvider( - _creds, CONF.identity.uri, **auth_provider_params) - self.identity = identity_client.IdentityClient( - _auth, - CONF.identity.catalog_type, - CONF.identity.region, - endpoint_type='adminURL', - **default_params_with_timeout_values) - self.tenants = tenants_client.TenantsClient( - _auth, - CONF.identity.catalog_type, - CONF.identity.region, - endpoint_type='adminURL', - **default_params_with_timeout_values) - self.roles = roles_client.RolesClient( - _auth, - CONF.identity.catalog_type, - CONF.identity.region, - endpoint_type='adminURL', - **default_params_with_timeout_values) - self.users = users_client.UsersClient( - _auth, - CONF.identity.catalog_type, - CONF.identity.region, - endpoint_type='adminURL', - **default_params_with_timeout_values) - self.servers = servers_client.ServersClient(_auth, - **compute_params) - self.flavors = flavors_client.FlavorsClient(_auth, - **compute_params) - self.floating_ips = floating_ips_client.FloatingIPsClient( - _auth, **compute_params) - self.secgroups = security_groups_client.SecurityGroupsClient( - _auth, **compute_params) - self.secrules = security_group_rules_client.SecurityGroupRulesClient( - _auth, **compute_params) - self.objects = object_client.ObjectClient(_auth, - **object_storage_params) - self.containers = container_client.ContainerClient( - _auth, **object_storage_params) - self.images = images_client.ImagesClient( - _auth, - CONF.image.catalog_type, - CONF.image.region or CONF.identity.region, - endpoint_type=CONF.image.endpoint_type, - build_interval=CONF.image.build_interval, - build_timeout=CONF.image.build_timeout, - **default_params) - self.volumes = volumes_client.VolumesClient( - _auth, - CONF.volume.catalog_type, - CONF.volume.region or CONF.identity.region, - endpoint_type=CONF.volume.endpoint_type, - build_interval=CONF.volume.build_interval, - build_timeout=CONF.volume.build_timeout, - **default_params) - self.networks = networks_client.NetworksClient( - _auth, - CONF.network.catalog_type, - CONF.network.region or CONF.identity.region, - endpoint_type=CONF.network.endpoint_type, - build_interval=CONF.network.build_interval, - build_timeout=CONF.network.build_timeout, - **default_params) - self.ports = ports_client.PortsClient( - _auth, - CONF.network.catalog_type, - CONF.network.region or CONF.identity.region, - endpoint_type=CONF.network.endpoint_type, - build_interval=CONF.network.build_interval, - build_timeout=CONF.network.build_timeout, - **default_params) - self.routers = routers_client.RoutersClient( - _auth, - CONF.network.catalog_type, - CONF.network.region or CONF.identity.region, - endpoint_type=CONF.network.endpoint_type, - build_interval=CONF.network.build_interval, - build_timeout=CONF.network.build_timeout, - **default_params) - self.subnets = subnets_client.SubnetsClient( - _auth, - CONF.network.catalog_type, - CONF.network.region or CONF.identity.region, - endpoint_type=CONF.network.endpoint_type, - build_interval=CONF.network.build_interval, - build_timeout=CONF.network.build_timeout, - **default_params) - - -def load_resources(fname): - """Load the expected resources from a yaml file.""" - return yaml.load(open(fname, 'r')) - - -def keystone_admin(): - return OSClient(OPTS.os_username, OPTS.os_password, OPTS.os_tenant_name) - - -def client_for_user(name): - LOG.debug("Entering client_for_user") - if name in USERS: - user = USERS[name] - LOG.debug("Created client for user %s" % user) - return OSClient(user['name'], user['pass'], user['tenant']) - else: - LOG.error("%s not found in USERS: %s" % (name, USERS)) - - -################### -# -# TENANTS -# -################### - - -def create_tenants(tenants): - """Create tenants from resource definition. - - Don't create the tenants if they already exist. - """ - admin = keystone_admin() - body = admin.tenants.list_tenants()['tenants'] - existing = [x['name'] for x in body] - for tenant in tenants: - if tenant not in existing: - admin.tenants.create_tenant(name=tenant)['tenant'] - else: - LOG.warning("Tenant '%s' already exists in this environment" - % tenant) - - -def destroy_tenants(tenants): - admin = keystone_admin() - for tenant in tenants: - tenant_id = identity.get_tenant_by_name(admin.tenant, tenant)['id'] - admin.tenants.delete_tenant(tenant_id) - -############## -# -# USERS -# -############## - - -def _users_for_tenant(users, tenant): - u_for_t = [] - for user in users: - for n in user: - if user[n]['tenant'] == tenant: - u_for_t.append(user[n]) - return u_for_t - - -def _tenants_from_users(users): - tenants = set() - for user in users: - for n in user: - tenants.add(user[n]['tenant']) - return tenants - - -def _assign_swift_role(user, swift_role): - admin = keystone_admin() - roles = admin.roles.list_roles() - role = next(r for r in roles if r['name'] == swift_role) - LOG.debug(USERS[user]) - try: - admin.roles.create_user_role_on_project( - USERS[user]['tenant_id'], - USERS[user]['id'], - role['id']) - except lib_exc.Conflict: - # don't care if it's already assigned - pass - - -def create_users(users): - """Create tenants from resource definition. - - Don't create the tenants if they already exist. - """ - global USERS - LOG.info("Creating users") - admin = keystone_admin() - for u in users: - try: - tenant = identity.get_tenant_by_name(admin.tenants, u['tenant']) - except lib_exc.NotFound: - LOG.error("Tenant: %s - not found" % u['tenant']) - continue - try: - identity.get_user_by_username(admin.tenants, - tenant['id'], u['name']) - LOG.warning("User '%s' already exists in this environment" - % u['name']) - except lib_exc.NotFound: - admin.users.create_user( - name=u['name'], password=u['pass'], - tenantId=tenant['id'], - email="%s@%s" % (u['name'], tenant['id']), - enabled=True) - - -def destroy_users(users): - admin = keystone_admin() - for user in users: - tenant_id = identity.get_tenant_by_name(admin.tenants, - user['tenant'])['id'] - user_id = identity.get_user_by_username(admin.tenants, - tenant_id, user['name'])['id'] - admin.users.delete_user(user_id) - - -def collect_users(users): - global USERS - LOG.info("Collecting users") - admin = keystone_admin() - for u in users: - tenant = identity.get_tenant_by_name(admin.tenants, u['tenant']) - u['tenant_id'] = tenant['id'] - USERS[u['name']] = u - body = identity.get_user_by_username(admin.tenants, - tenant['id'], u['name']) - USERS[u['name']]['id'] = body['id'] - - -class JavelinCheck(unittest.TestCase): - def __init__(self, users, resources): - super(JavelinCheck, self).__init__() - self.users = users - self.res = resources - - def runTest(self, *args): - pass - - def _ping_ip(self, ip_addr, count, namespace=None): - if namespace is None: - ping_cmd = "ping -c1 " + ip_addr - else: - ping_cmd = "sudo ip netns exec %s ping -c1 %s" % (namespace, - ip_addr) - for current in range(count): - return_code = os.system(ping_cmd) - if return_code is 0: - break - self.assertNotEqual(current, count - 1, - "Server is not pingable at %s" % ip_addr) - - def check(self): - self.check_users() - self.check_objects() - self.check_servers() - self.check_volumes() - self.check_secgroups() - - # validate neutron is enabled and ironic disabled: - # Tenant network isolation is not supported when using ironic. - # "admin" has set up a neutron flat network environment within a shared - # fixed network for all tenants to use. - # In this case, network/subnet/router creation can be skipped and the - # server booted the same as nova network. - if (CONF.service_available.neutron and - not CONF.baremetal.driver_enabled): - self.check_networking() - - def check_users(self): - """Check that the users we expect to exist, do. - - We don't use the resource list for this because we need to validate - that things like tenantId didn't drift across versions. - """ - LOG.info("checking users") - for name, user in six.iteritems(self.users): - client = keystone_admin() - found = client.users.show_user(user['id'])['user'] - self.assertEqual(found['name'], user['name']) - self.assertEqual(found['tenantId'], user['tenant_id']) - - # also ensure we can auth with that user, and do something - # on the cloud. We don't care about the results except that it - # remains authorized. - client = client_for_user(user['name']) - client.servers.list_servers() - - def check_objects(self): - """Check that the objects created are still there.""" - if not self.res.get('objects'): - return - LOG.info("checking objects") - for obj in self.res['objects']: - client = client_for_user(obj['owner']) - r, contents = client.objects.get_object( - obj['container'], obj['name']) - source = _file_contents(obj['file']) - self.assertEqual(contents, source) - - def check_servers(self): - """Check that the servers are still up and running.""" - if not self.res.get('servers'): - return - LOG.info("checking servers") - for server in self.res['servers']: - client = client_for_user(server['owner']) - found = _get_server_by_name(client, server['name']) - self.assertIsNotNone( - found, - "Couldn't find expected server %s" % server['name']) - - found = client.servers.show_server(found['id'])['server'] - # validate neutron is enabled and ironic disabled: - if (CONF.service_available.neutron and - not CONF.baremetal.driver_enabled): - _floating_is_alive = False - for network_name, body in found['addresses'].items(): - for addr in body: - ip = addr['addr'] - # Use floating IP, fixed IP or other type to - # reach the server. - # This is useful in multi-node environment. - if CONF.validation.connect_method == 'floating': - if addr.get('OS-EXT-IPS:type', - 'floating') == 'floating': - self._ping_ip(ip, 60) - _floating_is_alive = True - elif CONF.validation.connect_method == 'fixed': - if addr.get('OS-EXT-IPS:type', - 'fixed') == 'fixed': - namespace = _get_router_namespace(client, - network_name) - self._ping_ip(ip, 60, namespace) - else: - self._ping_ip(ip, 60) - # If CONF.validation.connect_method is floating, validate - # that the floating IP is attached to the server and the - # the server is pingable. - if CONF.validation.connect_method == 'floating': - self.assertTrue(_floating_is_alive, - "Server %s has no floating IP." % - server['name']) - else: - addr = found['addresses']['private'][0]['addr'] - self._ping_ip(addr, 60) - - def check_secgroups(self): - """Check that the security groups still exist.""" - LOG.info("Checking security groups") - for secgroup in self.res['secgroups']: - client = client_for_user(secgroup['owner']) - found = _get_resource_by_name(client.secgroups, 'security_groups', - secgroup['name']) - self.assertIsNotNone( - found, - "Couldn't find expected secgroup %s" % secgroup['name']) - - def check_volumes(self): - """Check that the volumes are still there and attached.""" - if not self.res.get('volumes'): - return - LOG.info("checking volumes") - for volume in self.res['volumes']: - client = client_for_user(volume['owner']) - vol_body = _get_volume_by_name(client, volume['name']) - self.assertIsNotNone( - vol_body, - "Couldn't find expected volume %s" % volume['name']) - - # Verify that a volume's attachment retrieved - server_id = _get_server_by_name(client, volume['server'])['id'] - attachment = client.volumes.get_attachment_from_volume(vol_body) - self.assertEqual(vol_body['id'], attachment['volume_id']) - self.assertEqual(server_id, attachment['server_id']) - - def check_networking(self): - """Check that the networks are still there.""" - for res_type in ('networks', 'subnets', 'routers'): - for res in self.res[res_type]: - client = client_for_user(res['owner']) - found = _get_resource_by_name(client.networks, res_type, - res['name']) - self.assertIsNotNone( - found, - "Couldn't find expected resource %s" % res['name']) - - -####################### -# -# OBJECTS -# -####################### - - -def _file_contents(fname): - with open(fname, 'r') as f: - return f.read() - - -def create_objects(objects): - if not objects: - return - LOG.info("Creating objects") - for obj in objects: - LOG.debug("Object %s" % obj) - swift_role = obj.get('swift_role', 'Member') - _assign_swift_role(obj['owner'], swift_role) - client = client_for_user(obj['owner']) - client.containers.create_container(obj['container']) - client.objects.create_object( - obj['container'], obj['name'], - _file_contents(obj['file'])) - - -def destroy_objects(objects): - for obj in objects: - client = client_for_user(obj['owner']) - r, body = client.objects.delete_object(obj['container'], obj['name']) - if not (200 <= int(r['status']) < 299): - raise ValueError("unable to destroy object: [%s] %s" % (r, body)) - - -####################### -# -# IMAGES -# -####################### - - -def _resolve_image(image, imgtype): - name = image[imgtype] - fname = os.path.join(OPTS.devstack_base, image['imgdir'], name) - return name, fname - - -def _get_image_by_name(client, name): - body = client.images.list_images() - for image in body: - if name == image['name']: - return image - return None - - -def create_images(images): - if not images: - return - LOG.info("Creating images") - for image in images: - client = client_for_user(image['owner']) - - # DEPRECATED: 'format' was used for ami images - # Use 'disk_format' and 'container_format' instead - if 'format' in image: - LOG.warning("Deprecated: 'format' is deprecated for images " - "description. Please use 'disk_format' and 'container_" - "format' instead.") - image['disk_format'] = image['format'] - image['container_format'] = image['format'] - - # only upload a new image if the name isn't there - if _get_image_by_name(client, image['name']): - LOG.info("Image '%s' already exists" % image['name']) - continue - - # special handling for 3 part image - extras = {} - if image['disk_format'] == 'ami': - name, fname = _resolve_image(image, 'aki') - aki = client.images.create_image( - 'javelin_' + name, 'aki', 'aki') - client.images.store_image_file(aki.get('id'), open(fname, 'r')) - extras['kernel_id'] = aki.get('id') - - name, fname = _resolve_image(image, 'ari') - ari = client.images.create_image( - 'javelin_' + name, 'ari', 'ari') - client.images.store_image_file(ari.get('id'), open(fname, 'r')) - extras['ramdisk_id'] = ari.get('id') - - _, fname = _resolve_image(image, 'file') - body = client.images.create_image( - image['name'], image['container_format'], - image['disk_format'], **extras) - image_id = body.get('id') - client.images.store_image_file(image_id, open(fname, 'r')) - - -def destroy_images(images): - if not images: - return - LOG.info("Destroying images") - for image in images: - client = client_for_user(image['owner']) - - response = _get_image_by_name(client, image['name']) - if not response: - LOG.info("Image '%s' does not exist" % image['name']) - continue - client.images.delete_image(response['id']) - - -####################### -# -# NETWORKS -# -####################### - -def _get_router_namespace(client, network): - network_id = _get_resource_by_name(client.networks, - 'networks', network)['id'] - n_body = client.routers.list_routers() - for router in n_body['routers']: - router_id = router['id'] - r_body = client.ports.list_ports(device_id=router_id) - for port in r_body['ports']: - if port['network_id'] == network_id: - return "qrouter-%s" % router_id - - -def _get_resource_by_name(client, resource, name): - get_resources = getattr(client, 'list_%s' % resource) - if get_resources is None: - raise AttributeError("client doesn't have method list_%s" % resource) - # Until all tempest client methods are changed to return only one value, - # we cannot assume they all have the same signature so we need to discard - # the unused response first value it two values are being returned. - body = get_resources() - if isinstance(body, tuple): - body = body[1] - if isinstance(body, dict): - body = body[resource] - for res in body: - if name == res['name']: - return res - raise ValueError('%s not found in %s resources' % (name, resource)) - - -def create_networks(networks): - LOG.info("Creating networks") - for network in networks: - client = client_for_user(network['owner']) - - # only create a network if the name isn't here - body = client.networks.list_networks() - if any(item['name'] == network['name'] for item in body['networks']): - LOG.warning("Duplicated network name: %s" % network['name']) - continue - - client.networks.create_network(name=network['name']) - - -def destroy_networks(networks): - LOG.info("Destroying subnets") - for network in networks: - client = client_for_user(network['owner']) - network_id = _get_resource_by_name(client.networks, 'networks', - network['name'])['id'] - client.networks.delete_network(network_id) - - -def create_subnets(subnets): - LOG.info("Creating subnets") - for subnet in subnets: - client = client_for_user(subnet['owner']) - - network = _get_resource_by_name(client.networks, 'networks', - subnet['network']) - ip_version = netaddr.IPNetwork(subnet['range']).version - # ensure we don't overlap with another subnet in the network - try: - client.networks.create_subnet(network_id=network['id'], - cidr=subnet['range'], - name=subnet['name'], - ip_version=ip_version) - except lib_exc.BadRequest as e: - is_overlapping_cidr = 'overlaps with another subnet' in str(e) - if not is_overlapping_cidr: - raise - - -def destroy_subnets(subnets): - LOG.info("Destroying subnets") - for subnet in subnets: - client = client_for_user(subnet['owner']) - subnet_id = _get_resource_by_name(client.subnets, - 'subnets', subnet['name'])['id'] - client.subnets.delete_subnet(subnet_id) - - -def create_routers(routers): - LOG.info("Creating routers") - for router in routers: - client = client_for_user(router['owner']) - - # only create a router if the name isn't here - body = client.routers.list_routers() - if any(item['name'] == router['name'] for item in body['routers']): - LOG.warning("Duplicated router name: %s" % router['name']) - continue - - client.networks.create_router(name=router['name']) - - -def destroy_routers(routers): - LOG.info("Destroying routers") - for router in routers: - client = client_for_user(router['owner']) - router_id = _get_resource_by_name(client.networks, - 'routers', router['name'])['id'] - for subnet in router['subnet']: - subnet_id = _get_resource_by_name(client.networks, - 'subnets', subnet)['id'] - client.routers.remove_router_interface(router_id, - subnet_id=subnet_id) - client.routers.delete_router(router_id) - - -def add_router_interface(routers): - for router in routers: - client = client_for_user(router['owner']) - router_id = _get_resource_by_name(client.networks, - 'routers', router['name'])['id'] - - for subnet in router['subnet']: - subnet_id = _get_resource_by_name(client.networks, - 'subnets', subnet)['id'] - # connect routers to their subnets - client.routers.add_router_interface(router_id, - subnet_id=subnet_id) - # connect routers to external network if set to "gateway" - if router['gateway']: - if CONF.network.public_network_id: - ext_net = CONF.network.public_network_id - client.routers.update_router( - router_id, set_enable_snat=True, - external_gateway_info={"network_id": ext_net}) - else: - raise ValueError('public_network_id is not configured.') - - -####################### -# -# SERVERS -# -####################### - -def _get_server_by_name(client, name): - body = client.servers.list_servers() - for server in body['servers']: - if name == server['name']: - return server - return None - - -def _get_flavor_by_name(client, name): - body = client.flavors.list_flavors()['flavors'] - for flavor in body: - if name == flavor['name']: - return flavor - return None - - -def create_servers(servers): - if not servers: - return - LOG.info("Creating servers") - for server in servers: - client = client_for_user(server['owner']) - - if _get_server_by_name(client, server['name']): - LOG.info("Server '%s' already exists" % server['name']) - continue - - image_id = _get_image_by_name(client, server['image'])['id'] - flavor_id = _get_flavor_by_name(client, server['flavor'])['id'] - # validate neutron is enabled and ironic disabled - kwargs = dict() - if (CONF.service_available.neutron and - not CONF.baremetal.driver_enabled and server.get('networks')): - get_net_id = lambda x: (_get_resource_by_name( - client.networks, 'networks', x)['id']) - kwargs['networks'] = [{'uuid': get_net_id(network)} - for network in server['networks']] - body = client.servers.create_server( - name=server['name'], imageRef=image_id, flavorRef=flavor_id, - **kwargs)['server'] - server_id = body['id'] - client.servers.wait_for_server_status(server_id, 'ACTIVE') - # create security group(s) after server spawning - for secgroup in server['secgroups']: - client.servers.add_security_group(server_id, name=secgroup) - if CONF.validation.connect_method == 'floating': - floating_ip_pool = server.get('floating_ip_pool') - floating_ip = client.floating_ips.create_floating_ip( - pool_name=floating_ip_pool)['floating_ip'] - client.floating_ips.associate_floating_ip_to_server( - floating_ip['ip'], server_id) - - -def destroy_servers(servers): - if not servers: - return - LOG.info("Destroying servers") - for server in servers: - client = client_for_user(server['owner']) - - response = _get_server_by_name(client, server['name']) - if not response: - LOG.info("Server '%s' does not exist" % server['name']) - continue - - # TODO(EmilienM): disassociate floating IP from server and release it. - client.servers.delete_server(response['id']) - waiters.wait_for_server_termination(client.servers, response['id'], - ignore_error=True) - - -def create_secgroups(secgroups): - LOG.info("Creating security groups") - for secgroup in secgroups: - client = client_for_user(secgroup['owner']) - - # only create a security group if the name isn't here - # i.e. a security group may be used by another server - # only create a router if the name isn't here - body = client.secgroups.list_security_groups()['security_groups'] - if any(item['name'] == secgroup['name'] for item in body): - LOG.warning("Security group '%s' already exists" % - secgroup['name']) - continue - - body = client.secgroups.create_security_group( - name=secgroup['name'], - description=secgroup['description'])['security_group'] - secgroup_id = body['id'] - # for each security group, create the rules - for rule in secgroup['rules']: - ip_proto, from_port, to_port, cidr = rule.split() - client.secrules.create_security_group_rule( - parent_group_id=secgroup_id, ip_protocol=ip_proto, - from_port=from_port, to_port=to_port, cidr=cidr) - - -def destroy_secgroups(secgroups): - LOG.info("Destroying security groups") - for secgroup in secgroups: - client = client_for_user(secgroup['owner']) - sg_id = _get_resource_by_name(client.secgroups, - 'security_groups', - secgroup['name']) - # sg rules are deleted automatically - client.secgroups.delete_security_group(sg_id['id']) - - -####################### -# -# VOLUMES -# -####################### - -def _get_volume_by_name(client, name): - body = client.volumes.list_volumes()['volumes'] - for volume in body: - if name == volume['display_name']: - return volume - return None - - -def create_volumes(volumes): - if not volumes: - return - LOG.info("Creating volumes") - for volume in volumes: - client = client_for_user(volume['owner']) - - # only create a volume if the name isn't here - if _get_volume_by_name(client, volume['name']): - LOG.info("volume '%s' already exists" % volume['name']) - continue - - size = volume['gb'] - v_name = volume['name'] - body = client.volumes.create_volume(size=size, - display_name=v_name)['volume'] - waiters.wait_for_volume_status(client.volumes, body['id'], 'available') - - -def destroy_volumes(volumes): - for volume in volumes: - client = client_for_user(volume['owner']) - volume_id = _get_volume_by_name(client, volume['name'])['id'] - client.volumes.detach_volume(volume_id) - client.volumes.delete_volume(volume_id) - - -def attach_volumes(volumes): - for volume in volumes: - client = client_for_user(volume['owner']) - server_id = _get_server_by_name(client, volume['server'])['id'] - volume_id = _get_volume_by_name(client, volume['name'])['id'] - device = volume['device'] - client.volumes.attach_volume(volume_id, - instance_uuid=server_id, - mountpoint=device) - - -####################### -# -# MAIN LOGIC -# -####################### - -def create_resources(): - LOG.info("Creating Resources") - # first create keystone level resources, and we need to be admin - # for this. - create_tenants(RES['tenants']) - create_users(RES['users']) - collect_users(RES['users']) - - # next create resources in a well known order - create_objects(RES['objects']) - create_images(RES['images']) - - # validate neutron is enabled and ironic is disabled - if CONF.service_available.neutron and not CONF.baremetal.driver_enabled: - create_networks(RES['networks']) - create_subnets(RES['subnets']) - create_routers(RES['routers']) - add_router_interface(RES['routers']) - - create_secgroups(RES['secgroups']) - create_volumes(RES['volumes']) - - # Only attempt attaching the volumes if servers are defined in the - # resource file - if 'servers' in RES: - create_servers(RES['servers']) - attach_volumes(RES['volumes']) - - -def destroy_resources(): - LOG.info("Destroying Resources") - # Destroy in inverse order of create - destroy_servers(RES['servers']) - destroy_images(RES['images']) - destroy_objects(RES['objects']) - destroy_volumes(RES['volumes']) - if CONF.service_available.neutron and not CONF.baremetal.driver_enabled: - destroy_routers(RES['routers']) - destroy_subnets(RES['subnets']) - destroy_networks(RES['networks']) - destroy_secgroups(RES['secgroups']) - destroy_users(RES['users']) - destroy_tenants(RES['tenants']) - LOG.warning("Destroy mode incomplete") - - -def get_options(): - global OPTS - parser = argparse.ArgumentParser( - description='Create and validate a fixed set of OpenStack resources') - parser.add_argument('-m', '--mode', - metavar='', - required=True, - help=('One of (create, check, destroy)')) - parser.add_argument('-r', '--resources', - required=True, - metavar='resourcefile.yaml', - help='Resources definition yaml file') - - parser.add_argument( - '-d', '--devstack-base', - required=True, - metavar='/opt/stack/old', - help='Devstack base directory for retrieving artifacts') - parser.add_argument( - '-c', '--config-file', - metavar='/etc/tempest.conf', - help='path to javelin2(tempest) config file') - - # auth bits, letting us also just source the devstack openrc - parser.add_argument('--os-username', - metavar='', - default=os.environ.get('OS_USERNAME'), - help=('Defaults to env[OS_USERNAME].')) - parser.add_argument('--os-password', - metavar='', - default=os.environ.get('OS_PASSWORD'), - help=('Defaults to env[OS_PASSWORD].')) - parser.add_argument('--os-tenant-name', - metavar='', - default=os.environ.get('OS_TENANT_NAME'), - help=('Defaults to env[OS_TENANT_NAME].')) - - OPTS = parser.parse_args() - if OPTS.mode not in ('create', 'check', 'destroy'): - print("ERROR: Unknown mode -m %s\n" % OPTS.mode) - parser.print_help() - sys.exit(1) - if OPTS.config_file: - config.CONF.set_config_path(OPTS.config_file) - - -def setup_logging(): - global LOG - logging.setup(CONF, __name__) - LOG = logging.getLogger(__name__) - - -def main(): - print("Javelin is deprecated and will be removed from Tempest in the " - "future.") - global RES - get_options() - setup_logging() - RES.update(load_resources(OPTS.resources)) - - if OPTS.mode == 'create': - create_resources() - # Make sure the resources we just created actually work - checker = JavelinCheck(USERS, RES) - checker.check() - elif OPTS.mode == 'check': - collect_users(RES['users']) - checker = JavelinCheck(USERS, RES) - checker.check() - elif OPTS.mode == 'destroy': - collect_users(RES['users']) - destroy_resources() - else: - LOG.error('Unknown mode %s' % OPTS.mode) - return 1 - LOG.info('javelin2 successfully finished') - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tempest/cmd/resources.yaml b/tempest/cmd/resources.yaml deleted file mode 100644 index 5c62ee3fe3..0000000000 --- a/tempest/cmd/resources.yaml +++ /dev/null @@ -1,95 +0,0 @@ -# This is a yaml description for the most basic definitions -# of what should exist across the resource boundary. Perhaps -# one day this will grow into a Heat resource template, but as -# Heat isn't a known working element in the upgrades, we do -# this much simpler thing for now. - -tenants: - - javelin - - discuss - -users: - - name: javelin - pass: gungnir - tenant: javelin - - name: javelin2 - pass: gungnir2 - tenant: discuss - -secgroups: - - name: angon - owner: javelin - description: angon - rules: - - 'icmp -1 -1 0.0.0.0/0' - - 'tcp 22 22 0.0.0.0/0' - - name: baobab - owner: javelin - description: baobab - rules: - - 'tcp 80 80 0.0.0.0/0' - -# resources that we want to create -images: - - name: javelin_cirros - owner: javelin - imgdir: files/images/cirros-0.3.2-x86_64-uec - file: cirros-0.3.2-x86_64-blank.img - format: ami - aki: cirros-0.3.2-x86_64-vmlinuz - ari: cirros-0.3.2-x86_64-initrd -volumes: - - name: assegai - server: peltast - owner: javelin - gb: 1 - device: /dev/vdb - - name: pifpouf - server: hoplite - owner: javelin - gb: 2 - device: /dev/vdb -networks: - - name: world1 - owner: javelin - - name: world2 - owner: javelin -subnets: - - name: subnet1 - range: 10.1.0.0/24 - network: world1 - owner: javelin - - name: subnet2 - range: 192.168.1.0/24 - network: world2 - owner: javelin -routers: - - name: connector - owner: javelin - gateway: true - subnet: - - subnet1 - - subnet2 -servers: - - name: peltast - owner: javelin - flavor: m1.small - image: javelin_cirros - networks: - - world1 - secgroups: - - angon - - baobab - - name: hoplite - owner: javelin - flavor: m1.medium - image: javelin_cirros - networks: - - world2 - secgroups: - - angon -objects: - - container: jc1 - name: javelin1 - owner: javelin - file: /etc/hosts diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py deleted file mode 100644 index 5ec9720c1b..0000000000 --- a/tempest/tests/cmd/test_javelin.py +++ /dev/null @@ -1,422 +0,0 @@ -#!/usr/bin/env python -# -# 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 mock -from oslotest import mockpatch - -from tempest.cmd import javelin -from tempest.lib import exceptions as lib_exc -from tempest.tests import base - - -class JavelinUnitTest(base.TestCase): - - def setUp(self): - super(JavelinUnitTest, self).setUp() - javelin.LOG = mock.MagicMock() - self.fake_client = mock.MagicMock() - self.fake_object = mock.MagicMock() - - def test_load_resources(self): - with mock.patch('six.moves.builtins.open', mock.mock_open(), - create=True) as open_mock: - with mock.patch('yaml.load', mock.MagicMock(), - create=True) as load_mock: - javelin.load_resources(self.fake_object) - load_mock.assert_called_once_with(open_mock(self.fake_object)) - - def test_keystone_admin(self): - self.useFixture(mockpatch.PatchObject(javelin, "OSClient")) - javelin.OPTS = self.fake_object - javelin.keystone_admin() - javelin.OSClient.assert_called_once_with( - self.fake_object.os_username, - self.fake_object.os_password, - self.fake_object.os_tenant_name) - - def test_client_for_user(self): - fake_user = mock.MagicMock() - javelin.USERS = {fake_user['name']: fake_user} - self.useFixture(mockpatch.PatchObject(javelin, "OSClient")) - javelin.client_for_user(fake_user['name']) - javelin.OSClient.assert_called_once_with( - fake_user['name'], fake_user['pass'], fake_user['tenant']) - - def test_client_for_non_existing_user(self): - fake_non_existing_user = self.fake_object - fake_user = mock.MagicMock() - javelin.USERS = {fake_user['name']: fake_user} - self.useFixture(mockpatch.PatchObject(javelin, "OSClient")) - javelin.client_for_user(fake_non_existing_user['name']) - self.assertFalse(javelin.OSClient.called) - - def test_attach_volumes(self): - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - - self.useFixture(mockpatch.PatchObject( - javelin, "_get_volume_by_name", - return_value=self.fake_object.volume)) - - self.useFixture(mockpatch.PatchObject( - javelin, "_get_server_by_name", - return_value=self.fake_object.server)) - - javelin.attach_volumes([self.fake_object]) - - mocked_function = self.fake_client.volumes.attach_volume - mocked_function.assert_called_once_with( - self.fake_object.volume['id'], - instance_uuid=self.fake_object.server['id'], - mountpoint=self.fake_object['device']) - - -class TestCreateResources(JavelinUnitTest): - def test_create_tenants(self): - - self.fake_client.tenants.list_tenants.return_value = {'tenants': []} - self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin", - return_value=self.fake_client)) - - javelin.create_tenants([self.fake_object['name']]) - - mocked_function = self.fake_client.tenants.create_tenant - mocked_function.assert_called_once_with(name=self.fake_object['name']) - - def test_create_duplicate_tenant(self): - self.fake_client.tenants.list_tenants.return_value = {'tenants': [ - {'name': self.fake_object['name']}]} - self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin", - return_value=self.fake_client)) - - javelin.create_tenants([self.fake_object['name']]) - - mocked_function = self.fake_client.tenants.create_tenant - self.assertFalse(mocked_function.called) - - def test_create_users(self): - self.useFixture(mockpatch.Patch( - 'tempest.common.identity.get_tenant_by_name', - return_value=self.fake_object['tenant'])) - self.useFixture(mockpatch.Patch( - 'tempest.common.identity.get_user_by_username', - side_effect=lib_exc.NotFound("user is not found"))) - self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin", - return_value=self.fake_client)) - - javelin.create_users([self.fake_object]) - - fake_tenant_id = self.fake_object['tenant']['id'] - fake_email = "%s@%s" % (self.fake_object['user'], fake_tenant_id) - mocked_function = self.fake_client.users.create_user - mocked_function.assert_called_once_with( - name=self.fake_object['name'], - password=self.fake_object['password'], - tenantId=fake_tenant_id, - email=fake_email, - enabled=True) - - def test_create_user_missing_tenant(self): - self.useFixture(mockpatch.Patch( - 'tempest.common.identity.get_tenant_by_name', - side_effect=lib_exc.NotFound("tenant is not found"))) - self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin", - return_value=self.fake_client)) - - javelin.create_users([self.fake_object]) - - mocked_function = self.fake_client.users.create_user - self.assertFalse(mocked_function.called) - - def test_create_objects(self): - - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - self.useFixture(mockpatch.PatchObject(javelin, "_assign_swift_role")) - self.useFixture(mockpatch.PatchObject(javelin, "_file_contents", - return_value=self.fake_object.content)) - - javelin.create_objects([self.fake_object]) - - mocked_function = self.fake_client.containers.create_container - mocked_function.assert_called_once_with(self.fake_object['container']) - mocked_function = self.fake_client.objects.create_object - mocked_function.assert_called_once_with(self.fake_object['container'], - self.fake_object['name'], - self.fake_object.content) - - def test_create_images(self): - self.fake_client.images.create_image.return_value = \ - self.fake_object['body'] - - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - self.useFixture(mockpatch.PatchObject(javelin, "_get_image_by_name", - return_value=[])) - self.useFixture(mockpatch.PatchObject(javelin, "_resolve_image", - return_value=(None, None))) - - with mock.patch('six.moves.builtins.open', mock.mock_open(), - create=True) as open_mock: - javelin.create_images([self.fake_object]) - - mocked_function = self.fake_client.images.create_image - mocked_function.assert_called_once_with(self.fake_object['name'], - self.fake_object['format'], - self.fake_object['format']) - - mocked_function = self.fake_client.images.store_image_file - fake_image_id = self.fake_object['body'].get('id') - mocked_function.assert_called_once_with(fake_image_id, open_mock()) - - def test_create_networks(self): - self.fake_client.networks.list_networks.return_value = { - 'networks': []} - - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - - javelin.create_networks([self.fake_object]) - - mocked_function = self.fake_client.networks.create_network - mocked_function.assert_called_once_with(name=self.fake_object['name']) - - def test_create_subnet(self): - - fake_network = self.fake_object['network'] - - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - self.useFixture(mockpatch.PatchObject(javelin, "_get_resource_by_name", - return_value=fake_network)) - - fake_netaddr = mock.MagicMock() - self.useFixture(mockpatch.PatchObject(javelin, "netaddr", - return_value=fake_netaddr)) - fake_version = javelin.netaddr.IPNetwork().version - - javelin.create_subnets([self.fake_object]) - - mocked_function = self.fake_client.networks.create_subnet - mocked_function.assert_called_once_with(network_id=fake_network['id'], - cidr=self.fake_object['range'], - name=self.fake_object['name'], - ip_version=fake_version) - - @mock.patch("tempest.common.waiters.wait_for_volume_status") - def test_create_volumes(self, mock_wait_for_volume_status): - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - self.useFixture(mockpatch.PatchObject(javelin, "_get_volume_by_name", - return_value=None)) - self.fake_client.volumes.create_volume.return_value = \ - self.fake_object.body - - javelin.create_volumes([self.fake_object]) - - mocked_function = self.fake_client.volumes.create_volume - mocked_function.assert_called_once_with( - size=self.fake_object['gb'], - display_name=self.fake_object['name']) - mock_wait_for_volume_status.assert_called_once_with( - self.fake_client.volumes, self.fake_object.body['volume']['id'], - 'available') - - @mock.patch("tempest.common.waiters.wait_for_volume_status") - def test_create_volume_existing(self, mock_wait_for_volume_status): - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - self.useFixture(mockpatch.PatchObject(javelin, "_get_volume_by_name", - return_value=self.fake_object)) - self.fake_client.volumes.create_volume.return_value = \ - self.fake_object.body - - javelin.create_volumes([self.fake_object]) - - mocked_function = self.fake_client.volumes.create_volume - self.assertFalse(mocked_function.called) - self.assertFalse(mock_wait_for_volume_status.called) - - def test_create_router(self): - - self.fake_client.routers.list_routers.return_value = {'routers': []} - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - - javelin.create_routers([self.fake_object]) - - mocked_function = self.fake_client.networks.create_router - mocked_function.assert_called_once_with(name=self.fake_object['name']) - - def test_create_router_existing(self): - self.fake_client.routers.list_routers.return_value = { - 'routers': [self.fake_object]} - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - - javelin.create_routers([self.fake_object]) - - mocked_function = self.fake_client.networks.create_router - self.assertFalse(mocked_function.called) - - def test_create_secgroup(self): - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - self.fake_client.secgroups.list_security_groups.return_value = ( - {'security_groups': []}) - self.fake_client.secgroups.create_security_group.return_value = \ - {'security_group': {'id': self.fake_object['secgroup_id']}} - - javelin.create_secgroups([self.fake_object]) - - mocked_function = self.fake_client.secgroups.create_security_group - mocked_function.assert_called_once_with( - name=self.fake_object['name'], - description=self.fake_object['description']) - - -class TestDestroyResources(JavelinUnitTest): - - def test_destroy_tenants(self): - - fake_tenant = self.fake_object['tenant'] - fake_auth = self.fake_client - self.useFixture(mockpatch.Patch( - 'tempest.common.identity.get_tenant_by_name', - return_value=fake_tenant)) - self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin", - return_value=fake_auth)) - javelin.destroy_tenants([fake_tenant]) - - mocked_function = fake_auth.tenants.delete_tenant - mocked_function.assert_called_once_with(fake_tenant['id']) - - def test_destroy_users(self): - - fake_user = self.fake_object['user'] - fake_tenant = self.fake_object['tenant'] - - fake_auth = self.fake_client - fake_auth.tenants.list_tenants.return_value = \ - {'tenants': [fake_tenant]} - fake_auth.users.list_users.return_value = {'users': [fake_user]} - - self.useFixture(mockpatch.Patch( - 'tempest.common.identity.get_user_by_username', - return_value=fake_user)) - self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin", - return_value=fake_auth)) - - javelin.destroy_users([fake_user]) - - mocked_function = fake_auth.users.delete_user - mocked_function.assert_called_once_with(fake_user['id']) - - def test_destroy_objects(self): - - self.fake_client.objects.delete_object.return_value = \ - {'status': "200"}, "" - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - javelin.destroy_objects([self.fake_object]) - - mocked_function = self.fake_client.objects.delete_object - mocked_function.asswert_called_once(self.fake_object['container'], - self.fake_object['name']) - - def test_destroy_images(self): - - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - self.useFixture(mockpatch.PatchObject(javelin, "_get_image_by_name", - return_value=self.fake_object['image'])) - - javelin.destroy_images([self.fake_object]) - - mocked_function = self.fake_client.images.delete_image - mocked_function.assert_called_once_with( - self.fake_object['image']['id']) - - def test_destroy_networks(self): - - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - self.useFixture(mockpatch.PatchObject( - javelin, "_get_resource_by_name", - return_value=self.fake_object['resource'])) - - javelin.destroy_networks([self.fake_object]) - - mocked_function = self.fake_client.networks.delete_network - mocked_function.assert_called_once_with( - self.fake_object['resource']['id']) - - def test_destroy_volumes(self): - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - - self.useFixture(mockpatch.PatchObject( - javelin, "_get_volume_by_name", - return_value=self.fake_object.volume)) - - javelin.destroy_volumes([self.fake_object]) - - mocked_function = self.fake_client.volumes.detach_volume - mocked_function.assert_called_once_with(self.fake_object.volume['id']) - mocked_function = self.fake_client.volumes.delete_volume - mocked_function.assert_called_once_with(self.fake_object.volume['id']) - - def test_destroy_subnets(self): - - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - fake_subnet_id = self.fake_object['subnet_id'] - self.useFixture(mockpatch.PatchObject(javelin, "_get_resource_by_name", - return_value={ - 'id': fake_subnet_id})) - - javelin.destroy_subnets([self.fake_object]) - - mocked_function = self.fake_client.subnets.delete_subnet - mocked_function.assert_called_once_with(fake_subnet_id) - - def test_destroy_routers(self): - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - - # this function is used on 2 different occasions in the code - def _fake_get_resource_by_name(*args): - if args[1] == "routers": - return {"id": self.fake_object['router_id']} - elif args[1] == "subnets": - return {"id": self.fake_object['subnet_id']} - javelin._get_resource_by_name = _fake_get_resource_by_name - - javelin.destroy_routers([self.fake_object]) - - mocked_function = self.fake_client.routers.delete_router - mocked_function.assert_called_once_with( - self.fake_object['router_id']) - - def test_destroy_secgroup(self): - self.useFixture(mockpatch.PatchObject(javelin, "client_for_user", - return_value=self.fake_client)) - fake_secgroup = {'id': self.fake_object['id']} - self.useFixture(mockpatch.PatchObject(javelin, "_get_resource_by_name", - return_value=fake_secgroup)) - - javelin.destroy_secgroups([self.fake_object]) - - mocked_function = self.fake_client.secgroups.delete_security_group - mocked_function.assert_called_once_with(self.fake_object['id'])