This is a temporary fix to work around a bug in nova-compute. The bug causes nova-compute to cache the placement api endpoint which causes placement api calls to fail when the endpoint switches from http to https
140 lines
5.0 KiB
Python
140 lines
5.0 KiB
Python
# Copyright 2018 Canonical Ltd.
|
|
#
|
|
# 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.
|
|
|
|
"""Run configuration phase."""
|
|
|
|
import functools
|
|
import requests
|
|
import tempfile
|
|
|
|
import zaza.charm_lifecycle.utils as lifecycle_utils
|
|
import zaza.openstack.charm_tests.vault.utils as vault_utils
|
|
import zaza.model
|
|
import zaza.openstack.utilities.cert
|
|
import zaza.openstack.utilities.openstack
|
|
|
|
|
|
def basic_setup(cacert=None, unseal_and_authorize=False):
|
|
"""Run basic setup for vault tests.
|
|
|
|
: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)
|
|
if vip_client:
|
|
unseal_client = vip_client
|
|
else:
|
|
unseal_client = clients[0]
|
|
initialized = vault_utils.is_initialized(unseal_client)
|
|
# The credentials are written to a file to allow the tests to be re-run
|
|
# this is mainly useful for manually working on the tests.
|
|
if initialized:
|
|
vault_creds = vault_utils.get_credentails()
|
|
else:
|
|
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'])
|
|
vault_utils.run_charm_authorize(vault_creds['root_token'])
|
|
|
|
|
|
def auto_initialize(cacert=None, validation_application='keystone'):
|
|
"""Auto initialize vault for testing.
|
|
|
|
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
|
|
:param validation_application: Name of application to be used as a
|
|
client for validation.
|
|
:type validation_application: 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, cacertificate) = zaza.openstack.utilities.cert.generate_cert(
|
|
'DivineAuthority',
|
|
generate_ca=True)
|
|
intermediate_cert = zaza.openstack.utilities.cert.sign_csr(
|
|
intermediate_csr,
|
|
cakey.decode(),
|
|
cacertificate.decode(),
|
|
generate_ca=True)
|
|
action = vault_utils.run_upload_signed_csr(
|
|
pem=intermediate_cert,
|
|
root_ca=cacertificate,
|
|
allowed_domains='openstack.local')
|
|
|
|
if validation_application:
|
|
validate_ca(cacertificate, application=validation_application)
|
|
# Once validation has completed restart nova-compute to work around
|
|
# bug #1826382
|
|
try:
|
|
cmd = 'systemctl restart nova-compute'
|
|
for unit in zaza.model.get_units('nova-compute'):
|
|
result = zaza.model.run_on_unit(unit.entity_id, cmd)
|
|
assert int(result['Code']) == 0, (
|
|
'Restart of nova-compute on {} failed'.format(
|
|
unit.entity_id))
|
|
except KeyError:
|
|
# Nothing todo if there are no nova-compute units
|
|
pass
|
|
|
|
|
|
auto_initialize_no_validation = functools.partial(
|
|
auto_initialize,
|
|
validation_application=None)
|
|
|
|
|
|
def validate_ca(cacertificate, application="keystone", port=5000):
|
|
"""Validate Certificate Authority against application.
|
|
|
|
: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,
|
|
zaza.openstack.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', {}))
|
|
vip = (zaza.model.get_application_config(application)
|
|
.get("vip").get("value"))
|
|
if vip:
|
|
ip = vip
|
|
else:
|
|
ip = zaza.model.get_app_ips(application)[0]
|
|
with tempfile.NamedTemporaryFile(mode='w') as fp:
|
|
fp.write(cacertificate.decode())
|
|
fp.flush()
|
|
requests.get('https://{}:{}'.format(ip, str(port)), verify=fp.name)
|