diff --git a/zaza/charm_tests/keystone/__init__.py b/zaza/charm_tests/keystone/__init__.py index ee4323a..0052f6b 100644 --- a/zaza/charm_tests/keystone/__init__.py +++ b/zaza/charm_tests/keystone/__init__.py @@ -33,8 +33,6 @@ class BaseKeystoneTest(test_utils.OpenStackBaseTest): def setUpClass(cls): """Run class setup for running Keystone charm operation tests.""" super(BaseKeystoneTest, cls).setUpClass() - # Local copy of keystone's CA certificate - cls.LOCAL_KEYSTONE_CACERT = "/tmp/keystone_juju_ca_cert.crt" # Check if we are related to Vault TLS certificates cls.tls_rid = zaza.model.get_relation_id( 'keystone', 'vault', remote_interface_name='certificates') diff --git a/zaza/charm_tests/keystone/tests.py b/zaza/charm_tests/keystone/tests.py index fd2b051..3bbe6ba 100644 --- a/zaza/charm_tests/keystone/tests.py +++ b/zaza/charm_tests/keystone/tests.py @@ -236,7 +236,7 @@ class AuthenticationAuthorizationTest(BaseKeystoneTest): 'OS_DOMAIN_NAME': DEMO_DOMAIN, } if self.tls_rid: - openrc['OS_CACERT'] = self.LOCAL_KEYSTONE_CACERT + openrc['OS_CACERT'] = openstack_utils.KEYSTONE_LOCAL_CACERT openrc['OS_AUTH_URL'] = ( openrc['OS_AUTH_URL'].replace('http', 'https')) logging.info('keystone IP {}'.format(ip)) @@ -266,7 +266,7 @@ class AuthenticationAuthorizationTest(BaseKeystoneTest): """ def _validate_token_data(openrc): if self.tls_rid: - openrc['OS_CACERT'] = self.LOCAL_KEYSTONE_CACERT + openrc['OS_CACERT'] = openstack_utils.KEYSTONE_LOCAL_CACERT openrc['OS_AUTH_URL'] = ( openrc['OS_AUTH_URL'].replace('http', 'https')) keystone_session = openstack_utils.get_keystone_session( diff --git a/zaza/charm_tests/vault/setup.py b/zaza/charm_tests/vault/setup.py index 5ad32a4..5f239ee 100644 --- a/zaza/charm_tests/vault/setup.py +++ b/zaza/charm_tests/vault/setup.py @@ -21,11 +21,7 @@ import zaza.charm_lifecycle.utils as lifecycle_utils import zaza.charm_tests.vault.utils as vault_utils import zaza.model import zaza.utilities.cert - -KEYSTONE_CACERT = "keystone_juju_ca_cert.crt" -KEYSTONE_REMOTE_CACERT = ( - "/usr/local/share/ca-certificates/{}".format(KEYSTONE_CACERT)) -KEYSTONE_LOCAL_CACERT = ("/tmp/{}".format(KEYSTONE_CACERT)) +import zaza.utilities.openstack def basic_setup(cacert=None, unseal_and_authorize=False): @@ -33,6 +29,8 @@ def basic_setup(cacert=None, unseal_and_authorize=False): :param cacert: Path to CA cert used for vaults api cert. :type cacert: str + :param unseal_and_authorize: Whether to unseal and authorize vault. + :type unseal_and_authorize: bool """ clients = vault_utils.get_clients(cacert=cacert) vip_client = vault_utils.get_vip_client(cacert=cacert) @@ -49,6 +47,7 @@ def basic_setup(cacert=None, unseal_and_authorize=False): vault_creds = vault_utils.init_vault(unseal_client) vault_utils.store_credentails(vault_creds) + # For use by charms or bundles other than vault if unseal_and_authorize: vault_utils.unseal_all(clients, vault_creds['keys'][0]) vault_utils.auth_all(clients, vault_creds['root_token']) @@ -58,40 +57,51 @@ def basic_setup(cacert=None, unseal_and_authorize=False): def auto_inititialize(cacert=None): """Auto initialize vault for testing. - Generating a csr and uploading a signed certificate. - In a stack that includes and relies on certificates in vault initialize + Generate a csr and uploading a signed certificate. + In a stack that includes and relies on certificates in vault, initialize vault by unsealing and creating a certificate authority. + + :param cacert: Path to CA cert used for vault's api cert. + :type cacert: str + :returns: None + :rtype: None """ basic_setup(cacert=cacert, unseal_and_authorize=True) action = vault_utils.run_get_csr() intermediate_csr = action.data['results']['output'] - (cakey, cacert) = zaza.utilities.cert.generate_cert( + (cakey, cacertificate) = zaza.utilities.cert.generate_cert( 'DivineAuthority', generate_ca=True) intermediate_cert = zaza.utilities.cert.sign_csr( intermediate_csr, cakey.decode(), - cacert.decode(), + cacertificate.decode(), generate_ca=True) action = vault_utils.run_upload_signed_csr( pem=intermediate_cert, - root_ca=cacert, + root_ca=cacertificate, allowed_domains='openstack.local') - validate_ca(cacert) + validate_ca(cacertificate) -def validate_ca(cacert, application="keystone", port=5000): - """Validate Certificate Authority. +def validate_ca(cacertificate, application="keystone", port=5000): + """Validate Certificate Authority against application. - :param cacert: Path to CA cert used for vaults api cert. - :type cacert: str + :param cacertificate: PEM formatted CA certificate + :type cacertificate: str + :param application: Which application to validate against. + :type application: str + :param port: Port to validate against. + :type port: int + :returns: None + :rtype: None """ zaza.model.block_until_file_has_contents( application, - '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt', - cacert.decode().strip()) + zaza.utilities.openstack.KEYSTONE_REMOTE_CACERT, + cacertificate.decode().strip()) test_config = lifecycle_utils.get_charm_config() zaza.model.wait_for_application_states( states=test_config.get('target_deploy_status', {})) @@ -102,6 +112,6 @@ def validate_ca(cacert, application="keystone", port=5000): else: ip = zaza.model.get_app_ips(application)[0] with tempfile.NamedTemporaryFile(mode='w') as fp: - fp.write(cacert.decode()) + fp.write(cacertificate.decode()) fp.flush() requests.get('https://{}:{}'.format(ip, str(port)), verify=fp.name) diff --git a/zaza/charm_tests/vault/tests.py b/zaza/charm_tests/vault/tests.py index 614b0b0..fb2b208 100644 --- a/zaza/charm_tests/vault/tests.py +++ b/zaza/charm_tests/vault/tests.py @@ -27,6 +27,7 @@ import zaza.charm_lifecycle.utils as lifecycle_utils import zaza.charm_tests.test_utils as test_utils import zaza.charm_tests.vault.utils as vault_utils import zaza.utilities.cert +import zaza.utilities.openstack import zaza.model @@ -112,7 +113,7 @@ class VaultTest(BaseVaultTest): del test_config['target_deploy_status']['vault'] zaza.model.block_until_file_has_contents( 'keystone', - '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt', + zaza.utilities.openstack.KEYSTONE_REMOTE_CACERT, cacert.decode().strip()) zaza.model.wait_for_application_states( states=test_config.get('target_deploy_status', {})) diff --git a/zaza/utilities/openstack.py b/zaza/utilities/openstack.py index bb8b09b..8cadac1 100644 --- a/zaza/utilities/openstack.py +++ b/zaza/utilities/openstack.py @@ -131,6 +131,12 @@ WORKLOAD_STATUS_EXCEPTIONS = { 'postgresql': { 'workload-status-message': 'Live'}} +# For vault TLS certificates +KEYSTONE_CACERT = "keystone_juju_ca_cert.crt" +KEYSTONE_REMOTE_CACERT = ( + "/usr/local/share/ca-certificates/{}".format(KEYSTONE_CACERT)) +KEYSTONE_LOCAL_CACERT = ("/tmp/{}".format(KEYSTONE_CACERT)) + # Openstack Client helpers def get_ks_creds(cloud_creds, scope='PROJECT'): @@ -1428,16 +1434,15 @@ def get_overcloud_auth(address=None): 'API_VERSION': 3, } if tls_rid: - tmp_file = "/tmp/keystone_juju_ca_cert.crt" unit = model.get_first_unit_name('keystone') model.scp_from_unit( unit, - '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt', - tmp_file) + KEYSTONE_REMOTE_CACERT, + KEYSTONE_LOCAL_CACERT) - if os.path.exists(tmp_file): - os.chmod(tmp_file, 0o644) - auth_settings['OS_CACERT'] = tmp_file + if os.path.exists(KEYSTONE_LOCAL_CACERT): + os.chmod(KEYSTONE_LOCAL_CACERT, 0o644) + auth_settings['OS_CACERT'] = KEYSTONE_LOCAL_CACERT return auth_settings