From 0fe0bcc8d0e5a6d4b953a5c07d6a4abf05a4c198 Mon Sep 17 00:00:00 2001 From: Chris MacNaughton Date: Mon, 4 Jun 2018 17:31:27 +0200 Subject: [PATCH] Update tests to use Juju storage Due to changes to the ceph-osd charm, it is suggested to use Juju storage for testing. Change-Id: I329a99ea20879224f90384a8f50eecc76f5fb2ad Related-Bug: #1698154 --- .../charmhelpers/contrib/hahelpers/cluster.py | 5 ++ .../contrib/openstack/amulet/utils.py | 12 +++-- .../charmhelpers/contrib/openstack/context.py | 51 +++++++++++-------- hooks/charmhelpers/contrib/openstack/ip.py | 10 ++++ hooks/charmhelpers/core/hookenv.py | 7 +++ tests/basic_deployment.py | 14 +---- .../charmhelpers/contrib/amulet/deployment.py | 6 ++- .../contrib/openstack/amulet/utils.py | 12 +++-- tests/charmhelpers/core/hookenv.py | 7 +++ 9 files changed, 79 insertions(+), 45 deletions(-) diff --git a/hooks/charmhelpers/contrib/hahelpers/cluster.py b/hooks/charmhelpers/contrib/hahelpers/cluster.py index 47facd9..4a737e2 100644 --- a/hooks/charmhelpers/contrib/hahelpers/cluster.py +++ b/hooks/charmhelpers/contrib/hahelpers/cluster.py @@ -223,6 +223,11 @@ def https(): return True if config_get('ssl_cert') and config_get('ssl_key'): return True + for r_id in relation_ids('certificates'): + for unit in relation_list(r_id): + ca = relation_get('ca', rid=r_id, unit=unit) + if ca: + return True for r_id in relation_ids('identity-service'): for unit in relation_list(r_id): # TODO - needs fixing for new helper as ssl_cert/key suffixes with CN diff --git a/hooks/charmhelpers/contrib/openstack/amulet/utils.py b/hooks/charmhelpers/contrib/openstack/amulet/utils.py index 84e87f5..d43038b 100644 --- a/hooks/charmhelpers/contrib/openstack/amulet/utils.py +++ b/hooks/charmhelpers/contrib/openstack/amulet/utils.py @@ -40,6 +40,7 @@ import novaclient import pika import swiftclient +from charmhelpers.core.decorators import retry_on_exception from charmhelpers.contrib.amulet.utils import ( AmuletUtils ) @@ -423,6 +424,7 @@ class OpenStackAmuletUtils(AmuletUtils): self.log.debug('Checking if tenant exists ({})...'.format(tenant)) return tenant in [t.name for t in keystone.tenants.list()] + @retry_on_exception(num_retries=5, base_delay=1) def keystone_wait_for_propagation(self, sentry_relation_pairs, api_version): """Iterate over list of sentry and relation tuples and verify that @@ -542,7 +544,7 @@ class OpenStackAmuletUtils(AmuletUtils): return ep def get_default_keystone_session(self, keystone_sentry, - openstack_release=None): + openstack_release=None, api_version=2): """Return a keystone session object and client object assuming standard default settings @@ -557,12 +559,12 @@ class OpenStackAmuletUtils(AmuletUtils): eyc """ self.log.debug('Authenticating keystone admin...') - api_version = 2 - client_class = keystone_client.Client # 11 => xenial_queens - if openstack_release and openstack_release >= 11: - api_version = 3 + if api_version == 3 or (openstack_release and openstack_release >= 11): client_class = keystone_client_v3.Client + api_version = 3 + else: + client_class = keystone_client.Client keystone_ip = keystone_sentry.info['public-address'] session, auth = self.get_keystone_session( keystone_ip, diff --git a/hooks/charmhelpers/contrib/openstack/context.py b/hooks/charmhelpers/contrib/openstack/context.py index 2d91f0a..b196d63 100644 --- a/hooks/charmhelpers/contrib/openstack/context.py +++ b/hooks/charmhelpers/contrib/openstack/context.py @@ -789,17 +789,18 @@ class ApacheSSLContext(OSContextGenerator): ssl_dir = os.path.join('/etc/apache2/ssl/', self.service_namespace) mkdir(path=ssl_dir) cert, key = get_cert(cn) - if cn: - cert_filename = 'cert_{}'.format(cn) - key_filename = 'key_{}'.format(cn) - else: - cert_filename = 'cert' - key_filename = 'key' + if cert and key: + if cn: + cert_filename = 'cert_{}'.format(cn) + key_filename = 'key_{}'.format(cn) + else: + cert_filename = 'cert' + key_filename = 'key' - write_file(path=os.path.join(ssl_dir, cert_filename), - content=b64decode(cert), perms=0o640) - write_file(path=os.path.join(ssl_dir, key_filename), - content=b64decode(key), perms=0o640) + write_file(path=os.path.join(ssl_dir, cert_filename), + content=b64decode(cert), perms=0o640) + write_file(path=os.path.join(ssl_dir, key_filename), + content=b64decode(key), perms=0o640) def configure_ca(self): ca_cert = get_ca_cert() @@ -871,23 +872,31 @@ class ApacheSSLContext(OSContextGenerator): if not self.external_ports or not https(): return {} - self.configure_ca() + use_keystone_ca = True + for rid in relation_ids('certificates'): + if related_units(rid): + use_keystone_ca = False + + if use_keystone_ca: + self.configure_ca() + self.enable_modules() ctxt = {'namespace': self.service_namespace, 'endpoints': [], 'ext_ports': []} - cns = self.canonical_names() - if cns: - for cn in cns: - self.configure_cert(cn) - else: - # Expect cert/key provided in config (currently assumed that ca - # uses ip for cn) - for net_type in (INTERNAL, ADMIN, PUBLIC): - cn = resolve_address(endpoint_type=net_type) - self.configure_cert(cn) + if use_keystone_ca: + cns = self.canonical_names() + if cns: + for cn in cns: + self.configure_cert(cn) + else: + # Expect cert/key provided in config (currently assumed that ca + # uses ip for cn) + for net_type in (INTERNAL, ADMIN, PUBLIC): + cn = resolve_address(endpoint_type=net_type) + self.configure_cert(cn) addresses = self.get_network_addresses() for address, endpoint in addresses: diff --git a/hooks/charmhelpers/contrib/openstack/ip.py b/hooks/charmhelpers/contrib/openstack/ip.py index d1476b1..73102af 100644 --- a/hooks/charmhelpers/contrib/openstack/ip.py +++ b/hooks/charmhelpers/contrib/openstack/ip.py @@ -184,3 +184,13 @@ def resolve_address(endpoint_type=PUBLIC, override=True): "clustered=%s)" % (net_type, clustered)) return resolved_address + + +def get_vip_in_network(network): + matching_vip = None + vips = config('vip') + if vips: + for vip in vips.split(): + if is_address_in_network(network, vip): + matching_vip = vip + return matching_vip diff --git a/hooks/charmhelpers/core/hookenv.py b/hooks/charmhelpers/core/hookenv.py index 627d8f7..ed7af39 100644 --- a/hooks/charmhelpers/core/hookenv.py +++ b/hooks/charmhelpers/core/hookenv.py @@ -972,6 +972,13 @@ def application_version_set(version): log("Application Version: {}".format(version)) +@translate_exc(from_exc=OSError, to_exc=NotImplementedError) +def goal_state(): + """Juju goal state values""" + cmd = ['goal-state', '--format=json'] + return json.loads(subprocess.check_output(cmd).decode('UTF-8')) + + @translate_exc(from_exc=OSError, to_exc=NotImplementedError) def is_leader(): """Does the current unit hold the juju leadership diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index 88504bc..29ce31b 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -68,7 +68,8 @@ class CinderBackupBasicDeployment(OpenStackAmuletDeployment): {'name': 'keystone'}, {'name': 'rabbitmq-server'}, {'name': 'ceph-mon', 'units': 3}, - {'name': 'ceph-osd', 'units': 3}, + {'name': 'ceph-osd', 'units': 3, + 'storage': {'osd-devices': 'cinder,10G'}}, {'name': 'cinder'}, {'name': 'cinder-ceph'}, ] @@ -108,16 +109,6 @@ class CinderBackupBasicDeployment(OpenStackAmuletDeployment): ceph_config = { 'monitor-count': '3', 'auth-supported': 'none', - 'fsid': '6547bd3e-1397-11e2-82e5-53567c8d32dc', - 'monitor-secret': 'AQCXrnZQwI7KGBAAiPofmKEXKxu5bUzoYLVkbQ==', - } - - # Include a non-existent device as osd-devices is a whitelist, - # and this will catch cases where proposals attempt to change that. - ceph_osd_config = { - 'osd-reformat': True, - 'ephemeral-unmount': '/mnt', - 'osd-devices': '/dev/vdb /srv/ceph /dev/test-non-existent' } cinder_ceph_config = { @@ -128,7 +119,6 @@ class CinderBackupBasicDeployment(OpenStackAmuletDeployment): 'percona-cluster': pxc_config, 'cinder': cinder_config, 'ceph-mon': ceph_config, - 'ceph-osd': ceph_osd_config, 'cinder-ceph': cinder_ceph_config, 'cinder-backup': cinder_ceph_config, } diff --git a/tests/charmhelpers/contrib/amulet/deployment.py b/tests/charmhelpers/contrib/amulet/deployment.py index 9c65518..d21d01d 100644 --- a/tests/charmhelpers/contrib/amulet/deployment.py +++ b/tests/charmhelpers/contrib/amulet/deployment.py @@ -50,7 +50,8 @@ class AmuletDeployment(object): this_service['units'] = 1 self.d.add(this_service['name'], units=this_service['units'], - constraints=this_service.get('constraints')) + constraints=this_service.get('constraints'), + storage=this_service.get('storage')) for svc in other_services: if 'location' in svc: @@ -64,7 +65,8 @@ class AmuletDeployment(object): svc['units'] = 1 self.d.add(svc['name'], charm=branch_location, units=svc['units'], - constraints=svc.get('constraints')) + constraints=svc.get('constraints'), + storage=svc.get('storage')) def _add_relations(self, relations): """Add all of the relations for the services.""" diff --git a/tests/charmhelpers/contrib/openstack/amulet/utils.py b/tests/charmhelpers/contrib/openstack/amulet/utils.py index 84e87f5..d43038b 100644 --- a/tests/charmhelpers/contrib/openstack/amulet/utils.py +++ b/tests/charmhelpers/contrib/openstack/amulet/utils.py @@ -40,6 +40,7 @@ import novaclient import pika import swiftclient +from charmhelpers.core.decorators import retry_on_exception from charmhelpers.contrib.amulet.utils import ( AmuletUtils ) @@ -423,6 +424,7 @@ class OpenStackAmuletUtils(AmuletUtils): self.log.debug('Checking if tenant exists ({})...'.format(tenant)) return tenant in [t.name for t in keystone.tenants.list()] + @retry_on_exception(num_retries=5, base_delay=1) def keystone_wait_for_propagation(self, sentry_relation_pairs, api_version): """Iterate over list of sentry and relation tuples and verify that @@ -542,7 +544,7 @@ class OpenStackAmuletUtils(AmuletUtils): return ep def get_default_keystone_session(self, keystone_sentry, - openstack_release=None): + openstack_release=None, api_version=2): """Return a keystone session object and client object assuming standard default settings @@ -557,12 +559,12 @@ class OpenStackAmuletUtils(AmuletUtils): eyc """ self.log.debug('Authenticating keystone admin...') - api_version = 2 - client_class = keystone_client.Client # 11 => xenial_queens - if openstack_release and openstack_release >= 11: - api_version = 3 + if api_version == 3 or (openstack_release and openstack_release >= 11): client_class = keystone_client_v3.Client + api_version = 3 + else: + client_class = keystone_client.Client keystone_ip = keystone_sentry.info['public-address'] session, auth = self.get_keystone_session( keystone_ip, diff --git a/tests/charmhelpers/core/hookenv.py b/tests/charmhelpers/core/hookenv.py index 627d8f7..ed7af39 100644 --- a/tests/charmhelpers/core/hookenv.py +++ b/tests/charmhelpers/core/hookenv.py @@ -972,6 +972,13 @@ def application_version_set(version): log("Application Version: {}".format(version)) +@translate_exc(from_exc=OSError, to_exc=NotImplementedError) +def goal_state(): + """Juju goal state values""" + cmd = ['goal-state', '--format=json'] + return json.loads(subprocess.check_output(cmd).decode('UTF-8')) + + @translate_exc(from_exc=OSError, to_exc=NotImplementedError) def is_leader(): """Does the current unit hold the juju leadership