Merge branch 'master' into gustavosr98_master

Change-Id: Ifaf449c6cffc900d3c5e240f467a4408ea6a195d
This commit is contained in:
Aurelien Lourot
2021-09-08 11:39:09 +02:00
7 changed files with 118 additions and 63 deletions
@@ -0,0 +1,34 @@
# Copyright 2021 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.
"""Code for setting up Ceph Dashboard."""
import logging
import zaza.model
import zaza.openstack.utilities.openstack
def check_dashboard_cert(model_name=None):
"""Wait for Dashboard to be ready.
:param model_name: Name of model to query.
:type model_name: str
"""
logging.info("Check dashbaord Waiting for cacert")
zaza.openstack.utilities.openstack.block_until_ca_exists(
'ceph-dashboard',
'CERTIFICATE',
model_name=model_name)
zaza.model.block_until_all_units_idle(model_name=model_name)
@@ -15,12 +15,11 @@
"""Encapsulating `ceph-dashboard` testing."""
import collections
import os
import requests
import zaza
import zaza.openstack.charm_tests.test_utils as test_utils
import zaza.utilities.deployment_env as deployment_env
import zaza.openstack.utilities.openstack as openstack_utils
class CephDashboardTest(test_utils.BaseCharmTest):
@@ -34,21 +33,8 @@ class CephDashboardTest(test_utils.BaseCharmTest):
"""Run class setup for running ceph dashboard tests."""
super().setUpClass()
cls.application_name = 'ceph-dashboard'
cls.local_ca_cert = cls.collect_ca()
@classmethod
def collect_ca(cls):
"""Collect CA from ceph-dashboard unit."""
local_ca_cert = os.path.join(
deployment_env.get_tmpdir(),
os.path.basename(cls.REMOTE_CERT_FILE))
if not os.path.isfile(local_ca_cert):
units = zaza.model.get_units(cls.application_name)
zaza.model.scp_from_unit(
units[0].entity_id,
cls.REMOTE_CERT_FILE,
local_ca_cert)
return local_ca_cert
cls.local_ca_cert = openstack_utils.get_remote_ca_cert_file(
cls.application_name)
def test_dashboard_units(self):
"""Check dashboard units are configured correctly."""
+29 -1
View File
@@ -25,6 +25,7 @@ import designateclient.v1.servers as servers
import zaza.model
import zaza.utilities.juju as juju_utils
import zaza.openstack.charm_tests.test_utils as test_utils
import zaza.openstack.utilities.generic as generic_utils
import zaza.openstack.utilities.openstack as openstack_utils
import zaza.openstack.charm_tests.designate.utils as designate_utils
import zaza.charm_lifecycle.utils as lifecycle_utils
@@ -90,6 +91,14 @@ class BaseDesignateTest(test_utils.OpenStackBaseTest):
cls.server_create = cls.designate.servers.create
cls.server_delete = cls.designate.servers.delete
@tenacity.retry(
retry=tenacity.retry_if_result(lambda ret: ret is not None),
# sleep for 2mins to allow 1min cron job to run...
wait=tenacity.wait_fixed(120),
stop=tenacity.stop_after_attempt(2))
def _retry_check_commands_on_units(self, cmds, units):
return generic_utils.check_commands_on_units(cmds, units)
class DesignateAPITests(BaseDesignateTest):
"""Tests interact with designate api."""
@@ -294,7 +303,26 @@ class DesignateCharmTests(BaseDesignateTest):
logging.info("Testing pause resume")
class DesignateTests(DesignateAPITests, DesignateCharmTests):
class DesignateMonitoringTests(BaseDesignateTest):
"""Designate charm monitoring tests."""
def test_nrpe_configured(self):
"""Confirm that the NRPE service check files are created."""
units = zaza.model.get_units(self.application_name)
cmds = []
for check_name in self.designate_svcs:
cmds.append(
'egrep -oh /usr/local.* /etc/nagios/nrpe.d/'
'check_{}.cfg'.format(check_name)
)
ret = self._retry_check_commands_on_units(cmds, units)
if ret:
logging.info(ret)
self.assertIsNone(ret, msg=ret)
class DesignateTests(DesignateAPITests, DesignateCharmTests,
DesignateMonitoringTests):
"""Collection of all Designate test classes."""
pass
+3 -17
View File
@@ -17,14 +17,12 @@
import base64
import functools
import logging
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
import zaza.openstack.utilities.generic
import zaza.openstack.utilities.exceptions as zaza_exceptions
import zaza.utilities.juju as juju_utils
@@ -95,7 +93,7 @@ def mojo_unseal_by_unit():
def unseal_by_unit(cacert=None):
"""Unseal any units reported as sealed using mojo cacert."""
cacert = cacert or get_cacert_file()
vault_creds = vault_utils.get_credentails()
vault_creds = vault_utils.get_credentials()
for client in vault_utils.get_clients(cacert=cacert):
if client.hvac_client.is_sealed():
client.hvac_client.unseal(vault_creds['keys'][0])
@@ -126,7 +124,7 @@ async def async_mojo_unseal_by_unit():
async def async_unseal_by_unit(cacert=None):
"""Unseal any units reported as sealed using vault cacert."""
cacert = cacert or get_cacert_file()
vault_creds = vault_utils.get_credentails()
vault_creds = vault_utils.get_credentials()
for client in vault_utils.get_clients(cacert=cacert):
if client.hvac_client.is_sealed():
client.hvac_client.unseal(vault_creds['keys'][0])
@@ -222,16 +220,4 @@ def validate_ca(cacertificate, application="keystone", port=5000):
:returns: None
:rtype: None
"""
zaza.openstack.utilities.openstack.block_until_ca_exists(
application,
cacertificate.decode().strip())
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)
vault_utils.validate_ca(cacertificate, application, port)
+2 -20
View File
@@ -21,9 +21,7 @@ import json
import logging
import unittest
import uuid
import tempfile
import requests
import tenacity
from hvac.exceptions import InternalServerError
@@ -64,7 +62,7 @@ class BaseVaultTest(test_utils.OpenStackBaseTest):
cls.vip_client = vault_utils.get_vip_client()
if cls.vip_client:
cls.clients.append(cls.vip_client)
cls.vault_creds = vault_utils.get_credentails()
cls.vault_creds = vault_utils.get_credentials()
vault_utils.unseal_all(cls.clients, cls.vault_creds['keys'][0])
vault_utils.auth_all(cls.clients, cls.vault_creds['root_token'])
vault_utils.ensure_secret_backend(cls.clients[0])
@@ -180,26 +178,10 @@ class VaultTest(BaseVaultTest):
except KeyError:
# Already removed
pass
zaza.openstack.utilities.openstack.block_until_ca_exists(
'keystone',
cacert.decode().strip())
zaza.model.wait_for_application_states(
states=test_config.get('target_deploy_status', {}))
ip = zaza.model.get_app_ips(
'keystone')[0]
with tempfile.NamedTemporaryFile(mode='w') as fp:
fp.write(cacert.decode())
fp.flush()
# Avoid race condition and retry
for attempt in tenacity.Retrying(
stop=tenacity.stop_after_attempt(3),
wait=tenacity.wait_exponential(
multiplier=2, min=2, max=10)):
with attempt:
logging.info(
"Attempting to connect to https://{}:5000".format(ip))
requests.get('https://{}:5000'.format(ip), verify=fp.name)
vault_utils.validate_ca(cacert)
def test_all_clients_authenticated(self):
"""Check all vault clients are authenticated."""
+42 -6
View File
@@ -18,6 +18,7 @@
import base64
import hvac
import logging
import requests
import tempfile
import urllib3
@@ -27,6 +28,7 @@ import tenacity
import collections
import zaza.model
import zaza.openstack.utilities.openstack
import zaza.utilities.networking as network_utils
AUTH_FILE = "vault_tests.yaml"
@@ -70,10 +72,10 @@ class VaultFacade:
def initialize(self):
"""Initialise vault and store resulting credentials."""
if self.is_initialized:
self.vault_creds = get_credentails()
self.vault_creds = get_credentials()
else:
self.vault_creds = init_vault(self.unseal_client)
store_credentails(self.vault_creds)
store_credentials(self.vault_creds)
self.initialized = is_initialized(self.unseal_client)
def unseal(self):
@@ -294,7 +296,7 @@ def find_unit_with_creds():
return unit
def get_credentails():
def get_credentials():
"""Retrieve vault token and keys from unit.
Retrieve vault token and keys from unit. These are stored on a unit
@@ -315,7 +317,7 @@ def get_credentails():
return creds
def store_credentails(creds):
def store_credentials(creds):
"""Store the supplied credentials.
Store the supplied credentials on a vault unit. ONLY USE FOR FUNCTIONAL
@@ -334,7 +336,7 @@ def store_credentails(creds):
'~/{}'.format(AUTH_FILE))
def get_credentails_from_file(auth_file):
def get_credentials_from_file(auth_file):
"""Read the vault credentials from the auth_file.
:param auth_file: Path to file with credentials
@@ -347,7 +349,7 @@ def get_credentails_from_file(auth_file):
return vault_creds
def write_credentails(auth_file, vault_creds):
def write_credentials(auth_file, vault_creds):
"""Write the vault credentials to the auth_file.
:param auth_file: Path to file to write credentials
@@ -434,3 +436,37 @@ def run_upload_signed_csr(pem, root_ca, allowed_domains):
'root-ca': base64.b64encode(root_ca).decode(),
'allowed-domains=': allowed_domains,
'ttl': '24h'})
@tenacity.retry(
reraise=True,
wait=tenacity.wait_exponential(multiplier=2, min=2, max=10),
stop=tenacity.stop_after_attempt(3))
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.openstack.utilities.openstack.block_until_ca_exists(
application,
cacertificate.decode().strip())
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()
keystone_url = 'https://{}:{}'.format(ip, str(port))
logging.info(
'Attempting to connect to {}'.format(keystone_url))
requests.get(keystone_url, verify=fp.name)
+5 -2
View File
@@ -986,8 +986,11 @@ def configure_networking_charms(networking_data, macs, use_juju_wait=True):
current_data_port = get_application_config_option(
application_name,
networking_data.port_config_key)
if current_data_port == config[networking_data.port_config_key]:
logging.info('Config already set to value')
if current_data_port:
logging.info("Skip update of external network data port config."
"Config '{}' already set to value: {}".format(
networking_data.port_config_key,
current_data_port))
return
model.set_application_config(