diff --git a/src/charm.py b/src/charm.py index c396b8e..776b9dc 100755 --- a/src/charm.py +++ b/src/charm.py @@ -10,6 +10,7 @@ import logging import os +from pathlib import Path from typing import Any, Optional import ops @@ -34,7 +35,8 @@ # store the clouds.yaml where it's easily accessible by the openstack-exporter snap # This is the SNAP_COMMON directory for the exporter snap, which is accessible, # unversioned, and retained across updates of the snap. -OS_CLIENT_CONFIG = f"/var/snap/{SNAP_NAME}/common/clouds.yaml" +OS_CLIENT_CONFIG = Path(f"/var/snap/{SNAP_NAME}/common/clouds.yaml") +OS_CLIENT_CONFIG_CACERT = Path(f"/var/snap/{SNAP_NAME}/common/cacert.pem") class OpenstackExporterOperatorCharm(ops.CharmBase): @@ -90,6 +92,9 @@ def _write_cloud_config(self, data: dict[str, str]) -> None: since v2 was removed a long time ago (Queens release) https://docs.openstack.org/keystone/latest/contributor/http-api.html """ + OS_CLIENT_CONFIG.parent.mkdir(parents=True, exist_ok=True) + OS_CLIENT_CONFIG_CACERT.write_text(self.config["ssl_ca"]) + auth_url = "{protocol}://{hostname}:{port}/v3".format( protocol=data["service_protocol"], hostname=data["service_hostname"], @@ -110,14 +115,12 @@ def _write_cloud_config(self, data: dict[str, str]) -> None: "auth_url": auth_url, }, "verify": data["service_protocol"] == "https", - "cacert": self.config["ssl_ca"], + "cacert": str(OS_CLIENT_CONFIG_CACERT), } } } - os.makedirs(os.path.dirname(OS_CLIENT_CONFIG), exist_ok=True) - with open(OS_CLIENT_CONFIG, "w") as f: - yaml.dump(contents, f) + OS_CLIENT_CONFIG.write_text(yaml.dump(contents)) def _get_keystone_data(self) -> dict[str, str]: """Get keystone data if ready, otherwise empty dict.""" diff --git a/tests/integration/tests/charm_tests/openstack_exporter.py b/tests/integration/tests/charm_tests/openstack_exporter.py index a0020eb..54b3578 100644 --- a/tests/integration/tests/charm_tests/openstack_exporter.py +++ b/tests/integration/tests/charm_tests/openstack_exporter.py @@ -45,7 +45,7 @@ def test_clouds_yaml(self): results = model.run_on_leader(APP_NAME, command) clouds_yaml_path = results.get("Stdout", "").strip() self.assertEqual(int(results.get("Code", "-1")), 0) - self.assertEqual(clouds_yaml_path, OS_CLIENT_CONFIG) + self.assertEqual(clouds_yaml_path, str(OS_CLIENT_CONFIG)) # Make sure the clouds yaml is not empty and it's a valid yaml command = f"cat $(sudo snap get {SNAP_NAME} os-client-config)" @@ -161,8 +161,10 @@ def test_configure_ssl_ca(self): results = model.run_on_leader(APP_NAME, command) clouds_yaml = results.get("Stdout", "").strip() data = yaml.safe_load(clouds_yaml) - cacert = data["clouds"][CLOUD_NAME]["cacert"] - self.assertEqual(cacert, f"{new_value}") + cacert_path = data["clouds"][CLOUD_NAME]["cacert"] + + # Verify ssl_ca was written to the file + model.block_until_file_has_contents(APP_NAME, cacert_path, new_value) # Verify the exporter crashes because of wrong ssl_ca command = "curl -q localhost:9180/metrics" diff --git a/tests/integration/tests/charm_tests/setup.py b/tests/integration/tests/charm_tests/setup.py index 107ec80..fc0f176 100644 --- a/tests/integration/tests/charm_tests/setup.py +++ b/tests/integration/tests/charm_tests/setup.py @@ -12,6 +12,6 @@ def setup_export_ssl_ca_config(): model.set_application_config("openstack-exporter", {"ssl_ca": cacert}) model.block_until_file_has_contents( "openstack-exporter", - f"/var/snap/{SNAP_NAME}/common/clouds.yaml", + f"/var/snap/{SNAP_NAME}/common/cacert.pem", "-----BEGIN CERTIFICATE-----", )