From 5d1ec6e86da83820d316bb52d6586f9dc27106de Mon Sep 17 00:00:00 2001 From: David Garcia Date: Thu, 25 Mar 2021 15:04:52 +0100 Subject: [PATCH] Certificate addition support to mon and ro charms This commit adds the `certificates` config in both RO and MON charms. Changes: - Add `certificates` config option in mon and ro charms - Use charmed-osm/ops-lib-charmed-osm library in all charms Change-Id: I14e3cf7ad2c846c4a2af57f317d4151119ce5fbb Signed-off-by: David Garcia --- installers/charm/grafana/requirements.txt | 2 +- installers/charm/grafana/tests/__init__.py | 9 +++- installers/charm/keystone/requirements.txt | 2 +- installers/charm/keystone/tests/__init__.py | 7 +++ installers/charm/lcm/requirements.txt | 2 +- installers/charm/lcm/tests/__init__.py | 8 +++ installers/charm/mon/config.yaml | 8 +++ installers/charm/mon/requirements.txt | 2 +- installers/charm/mon/src/charm.py | 48 ++++++++++++++++- installers/charm/mon/tests/__init__.py | 8 +++ installers/charm/mon/tests/test_charm.py | 33 ++++++++++++ installers/charm/nbi/requirements.txt | 2 +- installers/charm/nbi/tests/__init__.py | 8 +++ installers/charm/ng-ui/requirements.txt | 2 +- installers/charm/ng-ui/tests/__init__.py | 7 +++ installers/charm/pla/requirements.txt | 2 +- installers/charm/pla/tests/__init__.py | 7 +++ installers/charm/pol/requirements.txt | 2 +- installers/charm/pol/tests/__init__.py | 7 +++ installers/charm/prometheus/requirements.txt | 2 +- installers/charm/prometheus/tests/__init__.py | 7 +++ installers/charm/ro/config.yaml | 8 +++ installers/charm/ro/requirements.txt | 2 +- installers/charm/ro/src/charm.py | 52 ++++++++++++++++--- installers/charm/ro/tests/__init__.py | 7 +++ installers/charm/ro/tests/test_charm.py | 35 ++++++++++++- 26 files changed, 258 insertions(+), 21 deletions(-) diff --git a/installers/charm/grafana/requirements.txt b/installers/charm/grafana/requirements.txt index f10a1997..1a8928c7 100644 --- a/installers/charm/grafana/requirements.txt +++ b/installers/charm/grafana/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/grafana/tests/__init__.py b/installers/charm/grafana/tests/__init__.py index 0967ea68..446d5cee 100644 --- a/installers/charm/grafana/tests/__init__.py +++ b/installers/charm/grafana/tests/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2021 Canonical Ltd. +# Copyright 2020 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 @@ -27,7 +27,14 @@ import sys import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/keystone/requirements.txt b/installers/charm/keystone/requirements.txt index d42bd9ed..5c18be82 100644 --- a/installers/charm/keystone/requirements.txt +++ b/installers/charm/keystone/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## cryptography -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/keystone/tests/__init__.py b/installers/charm/keystone/tests/__init__.py index ca37e3b9..446d5cee 100644 --- a/installers/charm/keystone/tests/__init__.py +++ b/installers/charm/keystone/tests/__init__.py @@ -27,7 +27,14 @@ import sys import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/lcm/requirements.txt b/installers/charm/lcm/requirements.txt index f10a1997..1a8928c7 100644 --- a/installers/charm/lcm/requirements.txt +++ b/installers/charm/lcm/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/lcm/tests/__init__.py b/installers/charm/lcm/tests/__init__.py index ee5553b0..446d5cee 100644 --- a/installers/charm/lcm/tests/__init__.py +++ b/installers/charm/lcm/tests/__init__.py @@ -24,9 +24,17 @@ import sys + import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/mon/config.yaml b/installers/charm/mon/config.yaml index 53914974..f6d1ae19 100644 --- a/installers/charm/mon/config.yaml +++ b/installers/charm/mon/config.yaml @@ -76,3 +76,11 @@ options: description: MON will use Keystone backend type: boolean default: false + certificates: + type: string + description: | + comma-separated list of : certificates. + Where: + name: name of the file for the certificate + content: base64 content of the certificate + The path for the files is /certs. diff --git a/installers/charm/mon/requirements.txt b/installers/charm/mon/requirements.txt index f10a1997..1a8928c7 100644 --- a/installers/charm/mon/requirements.txt +++ b/installers/charm/mon/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/mon/src/charm.py b/installers/charm/mon/src/charm.py index d0145d4f..ab6dd2df 100755 --- a/installers/charm/mon/src/charm.py +++ b/installers/charm/mon/src/charm.py @@ -23,8 +23,9 @@ # pylint: disable=E0213 +import base64 import logging -from typing import NoReturn +from typing import NoReturn, Optional from ops.main import main @@ -33,7 +34,7 @@ from opslib.osm.interfaces.kafka import KafkaClient from opslib.osm.interfaces.keystone import KeystoneClient from opslib.osm.interfaces.mongo import MongoClient from opslib.osm.interfaces.prometheus import PrometheusClient -from opslib.osm.pod import ContainerV3Builder, PodSpecV3Builder +from opslib.osm.pod import ContainerV3Builder, FilesV3Builder, PodSpecV3Builder from opslib.osm.validator import ModelValidator, validator @@ -42,6 +43,26 @@ logger = logging.getLogger(__name__) PORT = 8000 +def _check_certificate_data(name: str, content: str): + if not name or not content: + raise ValueError("certificate name and content must be a non-empty string") + + +def _extract_certificates(certs_config: str): + certificates = {} + if certs_config: + cert_list = certs_config.split(",") + for cert in cert_list: + name, content = cert.split(":") + _check_certificate_data(name, content) + certificates[name] = content + return certificates + + +def decode(content: str): + return base64.b64decode(content.encode("utf-8")).decode("utf-8") + + class ConfigModel(ModelValidator): keystone_enabled: bool vca_host: str @@ -57,6 +78,7 @@ class ConfigModel(ModelValidator): grafana_url: str grafana_user: str grafana_password: str + certificates: Optional[str] @validator("log_level") def validate_log_level(cls, v): @@ -64,6 +86,16 @@ class ConfigModel(ModelValidator): raise ValueError("value must be INFO or DEBUG") return v + @validator("certificates") + def validate_certificates(cls, v): + # Raises an exception if it cannot extract the certificates + _extract_certificates(v) + return v + + @property + def certificates_dict(cls): + return _extract_certificates(cls.certificates) if cls.certificates else {} + class MonCharm(CharmedOsmBase): def __init__(self, *args) -> NoReturn: @@ -105,6 +137,15 @@ class MonCharm(CharmedOsmBase): if missing_relations: raise RelationsMissing(missing_relations) + def _build_cert_files( + self, + config: ConfigModel, + ): + cert_files_builder = FilesV3Builder() + for name, content in config.certificates_dict.items(): + cert_files_builder.add_file(name, decode(content), mode=0o600) + return cert_files_builder.build() + def build_pod_spec(self, image_info): # Validate config config = ConfigModel(**dict(self.config)) @@ -114,6 +155,9 @@ class MonCharm(CharmedOsmBase): pod_spec_builder = PodSpecV3Builder() # Build Container container_builder = ContainerV3Builder(self.app.name, image_info) + certs_files = self._build_cert_files(config) + if certs_files: + container_builder.add_volume_config("certs", "/certs", certs_files) container_builder.add_port(name=self.app.name, port=PORT) container_builder.add_envs( { diff --git a/installers/charm/mon/tests/__init__.py b/installers/charm/mon/tests/__init__.py index ee5553b0..446d5cee 100644 --- a/installers/charm/mon/tests/__init__.py +++ b/installers/charm/mon/tests/__init__.py @@ -24,9 +24,17 @@ import sys + import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/mon/tests/test_charm.py b/installers/charm/mon/tests/test_charm.py index 858ff7cb..dcf74ed5 100644 --- a/installers/charm/mon/tests/test_charm.py +++ b/installers/charm/mon/tests/test_charm.py @@ -20,6 +20,7 @@ # osm-charmers@lists.launchpad.net ## +import base64 import sys from typing import NoReturn import unittest @@ -29,6 +30,37 @@ from ops.model import ActiveStatus, BlockedStatus from ops.testing import Harness +def encode(content: str): + return base64.b64encode(content.encode("ascii")).decode("utf-8") + + +certificate_pem = encode( + """ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUf1b0s3UKtrxHXH2rge7UaQyfJAMwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTAzMjIxNzEyMjdaFw0zMTAz +MjAxNzEyMjdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCgCfCBgYAN6ON0yHDXuW407rFtJVRf0u46Jrp0Dk7J +kkSZ1e7Kq14r7yFHazEBWv78oOdwBocvWrd8leLuf3bYGcHR65hRy6A/fbYm5Aje +cKpwlFwaqfR4BLelwJl79jZ2rJX738cCBVrIk1nAVdOxGrXV4MTWUaKR2c+uKKvc +OKRT+5VqCeP4N5FWeATZ/KqGu8uV9E9WhFgwIZyStemLyLaDbn5PmAQ6S9oeR5jJ +o2gEEp/lDKvsqOWs76KFumSKa9hQs5Dw2lj0mb1UoyYK1gYc4ubzVChJadv44AU8 +MYtIjlFn1X1P+RjaKZNUIAGXkoLwYn6SizF6y6LiuFS9AgMBAAGjUzBRMB0GA1Ud +DgQWBBRl+/23CB+FXczeAZRQyYcfOdy9YDAfBgNVHSMEGDAWgBRl+/23CB+FXcze +AZRQyYcfOdy9YDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAd +dkeDym6lRN8kWFtfu3IyiLF8G8sn91qNbH3Yr4TuTBhgcjYyW6PgisSbrNgA9ysE +GoaF7ohb8GeVfCsQdK23+NpAlj/+DZ3OnGcxwXj1RUAz4yr9kanV1yuEtr1q2xJI +UaECWr8HZlwGBAKNTGx2EXT2/2aFzgULpDcxzTKD+MRpKpMUrWhf9ULvVrclvHWe +POLYhobUFuBHuo6rt5Rcq16j67zCX9EVTlAE3o2OECIWByK22sXdeOidYMpTkl4q +8FrOqjNsx5d+SBPJBv/pqtBm4bA47Vx1P8tbWOQ4bXS0UmXgwpeBOU/O/ot30+KS +JnKEy+dYyvVBKg77sRHw +-----END CERTIFICATE----- +""" +) + + class TestCharm(unittest.TestCase): """Prometheus Charm unit tests.""" @@ -50,6 +82,7 @@ class TestCharm(unittest.TestCase): "collector_interval": 30, "evaluator_interval": 30, "keystone_enabled": True, + "certificates": f"cert1:{certificate_pem}", } self.harness.update_config(self.config) diff --git a/installers/charm/nbi/requirements.txt b/installers/charm/nbi/requirements.txt index f10a1997..1a8928c7 100644 --- a/installers/charm/nbi/requirements.txt +++ b/installers/charm/nbi/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/nbi/tests/__init__.py b/installers/charm/nbi/tests/__init__.py index ee5553b0..446d5cee 100644 --- a/installers/charm/nbi/tests/__init__.py +++ b/installers/charm/nbi/tests/__init__.py @@ -24,9 +24,17 @@ import sys + import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/ng-ui/requirements.txt b/installers/charm/ng-ui/requirements.txt index 2eaba28c..10ade5db 100644 --- a/installers/charm/ng-ui/requirements.txt +++ b/installers/charm/ng-ui/requirements.txt @@ -20,4 +20,4 @@ ## pydantic # TODO: remove it -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/ng-ui/tests/__init__.py b/installers/charm/ng-ui/tests/__init__.py index ca37e3b9..446d5cee 100644 --- a/installers/charm/ng-ui/tests/__init__.py +++ b/installers/charm/ng-ui/tests/__init__.py @@ -27,7 +27,14 @@ import sys import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/pla/requirements.txt b/installers/charm/pla/requirements.txt index f10a1997..1a8928c7 100644 --- a/installers/charm/pla/requirements.txt +++ b/installers/charm/pla/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/pla/tests/__init__.py b/installers/charm/pla/tests/__init__.py index ca37e3b9..446d5cee 100644 --- a/installers/charm/pla/tests/__init__.py +++ b/installers/charm/pla/tests/__init__.py @@ -27,7 +27,14 @@ import sys import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/pol/requirements.txt b/installers/charm/pol/requirements.txt index f10a1997..1a8928c7 100644 --- a/installers/charm/pol/requirements.txt +++ b/installers/charm/pol/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/pol/tests/__init__.py b/installers/charm/pol/tests/__init__.py index ca37e3b9..446d5cee 100644 --- a/installers/charm/pol/tests/__init__.py +++ b/installers/charm/pol/tests/__init__.py @@ -27,7 +27,14 @@ import sys import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/prometheus/requirements.txt b/installers/charm/prometheus/requirements.txt index f10a1997..1a8928c7 100644 --- a/installers/charm/prometheus/requirements.txt +++ b/installers/charm/prometheus/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/prometheus/tests/__init__.py b/installers/charm/prometheus/tests/__init__.py index ca37e3b9..446d5cee 100644 --- a/installers/charm/prometheus/tests/__init__.py +++ b/installers/charm/prometheus/tests/__init__.py @@ -27,7 +27,14 @@ import sys import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/ro/config.yaml b/installers/charm/ro/config.yaml index af61a101..bb667d73 100644 --- a/installers/charm/ro/config.yaml +++ b/installers/charm/ro/config.yaml @@ -44,3 +44,11 @@ options: type: string description: "Openmano Tenant" default: "osm" + certificates: + type: string + description: | + comma-separated list of : certificates. + Where: + name: name of the file for the certificate + content: base64 content of the certificate + The path for the files is /certs. diff --git a/installers/charm/ro/requirements.txt b/installers/charm/ro/requirements.txt index f10a1997..1a8928c7 100644 --- a/installers/charm/ro/requirements.txt +++ b/installers/charm/ro/requirements.txt @@ -19,4 +19,4 @@ # osm-charmers@lists.launchpad.net ## -git+https://github.com/davigar15/ops-lib-charmed-osm/@e7f26cd29b322e175a23cadbe4546b7f2bbf111c \ No newline at end of file +git+https://github.com/charmed-osm/ops-lib-charmed-osm/@master \ No newline at end of file diff --git a/installers/charm/ro/src/charm.py b/installers/charm/ro/src/charm.py index 6851600c..5b40c160 100755 --- a/installers/charm/ro/src/charm.py +++ b/installers/charm/ro/src/charm.py @@ -22,26 +22,43 @@ # pylint: disable=E0213 +import base64 import logging -from typing import NoReturn +from typing import NoReturn, Optional from ops.main import main from opslib.osm.charm import CharmedOsmBase, RelationsMissing from opslib.osm.interfaces.kafka import KafkaClient from opslib.osm.interfaces.mongo import MongoClient from opslib.osm.interfaces.mysql import MysqlClient -from opslib.osm.pod import ( - ContainerV3Builder, - PodSpecV3Builder, -) +from opslib.osm.pod import ContainerV3Builder, FilesV3Builder, PodSpecV3Builder from opslib.osm.validator import ModelValidator, validator - logger = logging.getLogger(__name__) PORT = 9090 +def _check_certificate_data(name: str, content: str): + if not name or not content: + raise ValueError("certificate name and content must be a non-empty string") + + +def _extract_certificates(certs_config: str): + certificates = {} + if certs_config: + cert_list = certs_config.split(",") + for cert in cert_list: + name, content = cert.split(":") + _check_certificate_data(name, content) + certificates[name] = content + return certificates + + +def decode(content: str): + return base64.b64decode(content.encode("utf-8")).decode("utf-8") + + class ConfigModel(ModelValidator): enable_ng_ro: bool database_commonkey: str @@ -49,6 +66,7 @@ class ConfigModel(ModelValidator): vim_database: str ro_database: str openmano_tenant: str + certificates: Optional[str] @validator("log_level") def validate_log_level(cls, v): @@ -56,6 +74,16 @@ class ConfigModel(ModelValidator): raise ValueError("value must be INFO or DEBUG") return v + @validator("certificates") + def validate_certificates(cls, v): + # Raises an exception if it cannot extract the certificates + _extract_certificates(v) + return v + + @property + def certificates_dict(cls): + return _extract_certificates(cls.certificates) if cls.certificates else {} + class RoCharm(CharmedOsmBase): """GrafanaCharm Charm.""" @@ -106,6 +134,15 @@ class RoCharm(CharmedOsmBase): if missing_relations: raise RelationsMissing(missing_relations) + def _build_cert_files( + self, + config: ConfigModel, + ): + cert_files_builder = FilesV3Builder() + for name, content in config.certificates_dict.items(): + cert_files_builder.add_file(name, decode(content), mode=0o600) + return cert_files_builder.build() + def build_pod_spec(self, image_info): # Validate config config = ConfigModel(**dict(self.config)) @@ -115,6 +152,9 @@ class RoCharm(CharmedOsmBase): pod_spec_builder = PodSpecV3Builder() # Build Container container_builder = ContainerV3Builder(self.app.name, image_info) + certs_files = self._build_cert_files(config) + if certs_files: + container_builder.add_volume_config("certs", "/certs", certs_files) container_builder.add_port(name=self.app.name, port=PORT) container_builder.add_http_readiness_probe( "/ro/" if config.enable_ng_ro else "/openmano/tenants", diff --git a/installers/charm/ro/tests/__init__.py b/installers/charm/ro/tests/__init__.py index ca37e3b9..446d5cee 100644 --- a/installers/charm/ro/tests/__init__.py +++ b/installers/charm/ro/tests/__init__.py @@ -27,7 +27,14 @@ import sys import mock + +class OCIImageResourceErrorMock(Exception): + pass + + sys.path.append("src") oci_image = mock.MagicMock() +oci_image.OCIImageResourceError = OCIImageResourceErrorMock sys.modules["oci_image"] = oci_image +sys.modules["oci_image"].OCIImageResource().fetch.return_value = {} diff --git a/installers/charm/ro/tests/test_charm.py b/installers/charm/ro/tests/test_charm.py index 4610b259..9cced455 100644 --- a/installers/charm/ro/tests/test_charm.py +++ b/installers/charm/ro/tests/test_charm.py @@ -20,7 +20,7 @@ # osm-charmers@lists.launchpad.net ## -import sys +import base64 from typing import NoReturn import unittest @@ -29,12 +29,42 @@ from ops.model import ActiveStatus, BlockedStatus from ops.testing import Harness +def encode(content: str): + return base64.b64encode(content.encode("ascii")).decode("utf-8") + + +certificate_pem = encode( + """ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUf1b0s3UKtrxHXH2rge7UaQyfJAMwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTAzMjIxNzEyMjdaFw0zMTAz +MjAxNzEyMjdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCgCfCBgYAN6ON0yHDXuW407rFtJVRf0u46Jrp0Dk7J +kkSZ1e7Kq14r7yFHazEBWv78oOdwBocvWrd8leLuf3bYGcHR65hRy6A/fbYm5Aje +cKpwlFwaqfR4BLelwJl79jZ2rJX738cCBVrIk1nAVdOxGrXV4MTWUaKR2c+uKKvc +OKRT+5VqCeP4N5FWeATZ/KqGu8uV9E9WhFgwIZyStemLyLaDbn5PmAQ6S9oeR5jJ +o2gEEp/lDKvsqOWs76KFumSKa9hQs5Dw2lj0mb1UoyYK1gYc4ubzVChJadv44AU8 +MYtIjlFn1X1P+RjaKZNUIAGXkoLwYn6SizF6y6LiuFS9AgMBAAGjUzBRMB0GA1Ud +DgQWBBRl+/23CB+FXczeAZRQyYcfOdy9YDAfBgNVHSMEGDAWgBRl+/23CB+FXcze +AZRQyYcfOdy9YDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAd +dkeDym6lRN8kWFtfu3IyiLF8G8sn91qNbH3Yr4TuTBhgcjYyW6PgisSbrNgA9ysE +GoaF7ohb8GeVfCsQdK23+NpAlj/+DZ3OnGcxwXj1RUAz4yr9kanV1yuEtr1q2xJI +UaECWr8HZlwGBAKNTGx2EXT2/2aFzgULpDcxzTKD+MRpKpMUrWhf9ULvVrclvHWe +POLYhobUFuBHuo6rt5Rcq16j67zCX9EVTlAE3o2OECIWByK22sXdeOidYMpTkl4q +8FrOqjNsx5d+SBPJBv/pqtBm4bA47Vx1P8tbWOQ4bXS0UmXgwpeBOU/O/ot30+KS +JnKEy+dYyvVBKg77sRHw +-----END CERTIFICATE----- +""" +) + + class TestCharm(unittest.TestCase): """Prometheus Charm unit tests.""" def setUp(self) -> NoReturn: """Test setup""" - self.image_info = sys.modules["oci_image"].OCIImageResource().fetch() self.harness = Harness(RoCharm) self.harness.set_leader(is_leader=True) self.harness.begin() @@ -45,6 +75,7 @@ class TestCharm(unittest.TestCase): "vim_database": "db_name", "ro_database": "ro_db_name", "openmano_tenant": "mano", + "certificates": f"cert1:{certificate_pem}", } self.harness.update_config(self.config) -- 2.17.1