From 4a46c6ee105522c9018e977977542e4bee50133c Mon Sep 17 00:00:00 2001 From: Guillermo Calvino Date: Thu, 23 Mar 2023 13:40:33 +0100 Subject: [PATCH] Make tcpsocket readiness and liveness configurable Change-Id: If0c466aa5a0b64fff0ed7cee037bd3cf8672ec46 Signed-off-by: Guillermo Calvino --- installers/charm/kafka-exporter/src/charm.py | 1 - installers/charm/keystone/src/charm.py | 4 +- installers/charm/lcm/src/charm.py | 1 - installers/charm/mon/src/charm.py | 1 - installers/charm/nbi/config.yaml | 28 +++++++++ installers/charm/nbi/src/charm.py | 63 ++++++++++++++++++-- installers/charm/nbi/tests/test_charm.py | 63 ++++++++++++++++++++ installers/charm/pla/src/charm.py | 1 - installers/charm/pol/src/charm.py | 1 - installers/charm/prometheus/charmcraft.yaml | 3 +- installers/charm/prometheus/src/charm.py | 1 - 11 files changed, 151 insertions(+), 16 deletions(-) diff --git a/installers/charm/kafka-exporter/src/charm.py b/installers/charm/kafka-exporter/src/charm.py index ec6eaabe..07a854fd 100755 --- a/installers/charm/kafka-exporter/src/charm.py +++ b/installers/charm/kafka-exporter/src/charm.py @@ -96,7 +96,6 @@ class KafkaEndpoint: class KafkaExporterCharm(CharmedOsmBase): - on = KafkaEvents() def __init__(self, *args) -> NoReturn: diff --git a/installers/charm/keystone/src/charm.py b/installers/charm/keystone/src/charm.py index 39a7a007..446d2e0c 100755 --- a/installers/charm/keystone/src/charm.py +++ b/installers/charm/keystone/src/charm.py @@ -248,9 +248,9 @@ class KeystoneCharm(CharmedOsmBase): ): credentials_files_builder = FilesV3Builder() fernet_files_builder = FilesV3Builder() - for (key_id, _) in enumerate(credential_keys): + for key_id, _ in enumerate(credential_keys): credentials_files_builder.add_file(str(key_id), str(key_id), secret=True) - for (key_id, _) in enumerate(fernet_keys): + for key_id, _ in enumerate(fernet_keys): fernet_files_builder.add_file(str(key_id), str(key_id), secret=True) return credentials_files_builder.build(), fernet_files_builder.build() diff --git a/installers/charm/lcm/src/charm.py b/installers/charm/lcm/src/charm.py index 7c644189..5319763f 100755 --- a/installers/charm/lcm/src/charm.py +++ b/installers/charm/lcm/src/charm.py @@ -140,7 +140,6 @@ class ConfigModel(ModelValidator): class LcmCharm(CharmedOsmBase): - on = KafkaEvents() def __init__(self, *args) -> NoReturn: diff --git a/installers/charm/mon/src/charm.py b/installers/charm/mon/src/charm.py index d04779a0..6cb77454 100755 --- a/installers/charm/mon/src/charm.py +++ b/installers/charm/mon/src/charm.py @@ -125,7 +125,6 @@ class ConfigModel(ModelValidator): class MonCharm(CharmedOsmBase): - on = KafkaEvents() def __init__(self, *args) -> NoReturn: diff --git a/installers/charm/nbi/config.yaml b/installers/charm/nbi/config.yaml index f10304fe..eabd968b 100644 --- a/installers/charm/nbi/config.yaml +++ b/installers/charm/nbi/config.yaml @@ -107,3 +107,31 @@ options: description: Enables the security context of the pods type: boolean default: false + tcpsocket_readiness_probe: + description: | + Configuration of tcpsocket readiness probe. + + Default values (when configuration is empty): + initial_delay_seconds = 5 + timeout_seconds = 5 + period_seconds = 10 + success_threshold = 1 + failure_threshold = 3 + + Example of configuration: + juju config nbi tcpsocket_readiness_probe='{"failure_threshold": 7}' + type: string + tcpsocket_liveness_probe: + description: | + Configuration of tcpsocket liveness probe. + + Default values (when configuration is empty): + initial_delay_seconds = 5 + timeout_seconds = 5 + period_seconds = 10 + success_threshold = 1 + failure_threshold = 3 + + Example of configuration: + juju config nbi tcpsocket_liveness_probe='{"initial_delay_seconds": 10}' + type: string diff --git a/installers/charm/nbi/src/charm.py b/installers/charm/nbi/src/charm.py index 4aaecb9d..e1207568 100755 --- a/installers/charm/nbi/src/charm.py +++ b/installers/charm/nbi/src/charm.py @@ -24,6 +24,7 @@ from ipaddress import ip_network +import json import logging from typing import NoReturn, Optional from urllib.parse import urlparse @@ -65,6 +66,8 @@ class ConfigModel(ModelValidator): image_pull_policy: str debug_mode: bool security_context: bool + tcpsocket_liveness_probe: Optional[str] + tcpsocket_readiness_probe: Optional[str] @validator("auth_backend") def validate_auth_backend(cls, v): @@ -116,9 +119,40 @@ class ConfigModel(ModelValidator): raise ValueError("value must be always, ifnotpresent or never") return values[v] + @staticmethod + def _validate_tcpsocket_probe(probe_str) -> dict: + valid_attributes = ( + "initial_delay_seconds", + "timeout_seconds", + "period_seconds", + "success_threshold", + "failure_threshold", + ) + if probe_str: + probe_dict = json.loads(probe_str) + if all(attribute in valid_attributes for attribute in probe_dict): + return probe_dict + raise ValueError( + "One or more attributes are not accepted by the tcpsocket probe configuration" + ) + return {} -class NbiCharm(CharmedOsmBase): + @validator("tcpsocket_readiness_probe") + def validate_tcpsocket_readiness_probe(cls, v): + try: + return ConfigModel._validate_tcpsocket_probe(v) + except Exception as e: + raise ValueError(f"tcpsocket_readiness_probe configuration error: {e}") + + @validator("tcpsocket_liveness_probe") + def validate_tcpsocket_liveness_probe(cls, v): + try: + return ConfigModel._validate_tcpsocket_probe(v) + except Exception as e: + raise ValueError(f"tcpsocket_liveness_probe configuration error: {e}") + +class NbiCharm(CharmedOsmBase): on = KafkaEvents() def __init__(self, *args) -> NoReturn: @@ -193,7 +227,6 @@ class NbiCharm(CharmedOsmBase): def build_pod_spec(self, image_info): # Validate config config = ConfigModel(**dict(self.config)) - if config.mongodb_uri and not self.mongodb_client.is_missing_data_in_unit(): raise Exception("Mongodb data cannot be provided via config and relation") @@ -242,13 +275,31 @@ class NbiCharm(CharmedOsmBase): container_builder.add_port(name=self.app.name, port=PORT) container_builder.add_tcpsocket_readiness_probe( PORT, - initial_delay_seconds=5, - timeout_seconds=5, + initial_delay_seconds=config.tcpsocket_readiness_probe.get( + "initial_delay_seconds", 5 + ), + timeout_seconds=config.tcpsocket_readiness_probe.get("timeout_seconds", 5), + period_seconds=config.tcpsocket_readiness_probe.get("period_seconds", 10), + success_threshold=config.tcpsocket_readiness_probe.get( + "success_threshold", 1 + ), + failure_threshold=config.tcpsocket_readiness_probe.get( + "failure_threshold", 3 + ), ) container_builder.add_tcpsocket_liveness_probe( PORT, - initial_delay_seconds=45, - timeout_seconds=10, + initial_delay_seconds=config.tcpsocket_liveness_probe.get( + "initial_delay_seconds", 45 + ), + timeout_seconds=config.tcpsocket_liveness_probe.get("timeout_seconds", 10), + period_seconds=config.tcpsocket_liveness_probe.get("period_seconds", 10), + success_threshold=config.tcpsocket_liveness_probe.get( + "success_threshold", 1 + ), + failure_threshold=config.tcpsocket_liveness_probe.get( + "failure_threshold", 3 + ), ) container_builder.add_envs( { diff --git a/installers/charm/nbi/tests/test_charm.py b/installers/charm/nbi/tests/test_charm.py index 92c29808..59a27fb7 100644 --- a/installers/charm/nbi/tests/test_charm.py +++ b/installers/charm/nbi/tests/test_charm.py @@ -155,6 +155,42 @@ class TestCharm(unittest.TestCase): # Verifying status self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) + def test_config_liveness_probe_with_relations( + self, + ) -> NoReturn: + "Test configuration of liveness probe with relations" + self.initialize_nbi_with_keystone() + self.config_liveness_probe() + # Verifying status + self.assertIsInstance(self.harness.charm.unit.status, ActiveStatus) + + def test_wrong_config_liveness_probe_with_relations( + self, + ) -> NoReturn: + "Test wrong configuration of liveness probe with relations" + self.initialize_nbi_with_keystone() + self.wrong_config_liveness_probe() + # Verifying status + self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) + + def test_config_readiness_probe_with_relations( + self, + ) -> NoReturn: + "Test configuration of readiness probe with relations" + self.initialize_nbi_with_keystone() + self.config_readiness_probe() + # Verifying status + self.assertIsInstance(self.harness.charm.unit.status, ActiveStatus) + + def test_wrong_config_readiness_probe_with_relations( + self, + ) -> NoReturn: + "Test wrong configuration of readiness probe with relations" + self.initialize_nbi_with_keystone() + self.wrong_config_readiness_probe() + # Verifying status + self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) + def initialize_kafka_relation(self): kafka_relation_id = self.harness.add_relation("kafka", "kafka") self.harness.add_relation_unit(kafka_relation_id, "kafka/0") @@ -165,6 +201,33 @@ class TestCharm(unittest.TestCase): def initialize_mongo_config(self): self.harness.update_config({"mongodb_uri": "mongodb://mongo:27017"}) + def initialize_nbi_with_keystone(self): + self.harness.update_config({"auth_backend": "keystone"}) + self.initialize_kafka_relation() + self.initialize_mongo_relation() + self.initialize_prometheus_relation() + self.initialize_keystone_relation() + + def config_liveness_probe(self): + self.harness.update_config( + {"tcpsocket_liveness_probe": '{"initial_delay_seconds": 10}'} + ) + + def wrong_config_liveness_probe(self): + self.harness.update_config( + {"tcpsocket_liveness_probe": "{initial_delay_seconds: 10}"} + ) + + def wrong_config_readiness_probe(self): + self.harness.update_config( + {"tcpsocket_readiness_probe": "{initial_delay_seconds: 10}"} + ) + + def config_readiness_probe(self): + self.harness.update_config( + {"tcpsocket_readiness_probe": '{"initial_delay_seconds": 10}'} + ) + def initialize_mongo_relation(self): mongodb_relation_id = self.harness.add_relation("mongodb", "mongodb") self.harness.add_relation_unit(mongodb_relation_id, "mongodb/0") diff --git a/installers/charm/pla/src/charm.py b/installers/charm/pla/src/charm.py index 36a11dcb..d907f0bc 100755 --- a/installers/charm/pla/src/charm.py +++ b/installers/charm/pla/src/charm.py @@ -76,7 +76,6 @@ class ConfigModel(ModelValidator): class PlaCharm(CharmedOsmBase): - on = KafkaEvents() def __init__(self, *args) -> NoReturn: diff --git a/installers/charm/pol/src/charm.py b/installers/charm/pol/src/charm.py index 7b92b453..94f6ecb8 100755 --- a/installers/charm/pol/src/charm.py +++ b/installers/charm/pol/src/charm.py @@ -87,7 +87,6 @@ class ConfigModel(ModelValidator): class PolCharm(CharmedOsmBase): - on = KafkaEvents() def __init__(self, *args) -> NoReturn: diff --git a/installers/charm/prometheus/charmcraft.yaml b/installers/charm/prometheus/charmcraft.yaml index 87d04635..d677a76a 100644 --- a/installers/charm/prometheus/charmcraft.yaml +++ b/installers/charm/prometheus/charmcraft.yaml @@ -34,8 +34,7 @@ bases: - arm64 parts: charm: + charm-binary-python-packages: [cryptography, bcrypt] build-packages: - - cargo - git - libffi-dev - - rustc diff --git a/installers/charm/prometheus/src/charm.py b/installers/charm/prometheus/src/charm.py index af39a13a..07793e08 100755 --- a/installers/charm/prometheus/src/charm.py +++ b/installers/charm/prometheus/src/charm.py @@ -107,7 +107,6 @@ class ConfigModel(ModelValidator): class PrometheusCharm(CharmedOsmBase): - """Prometheus Charm.""" def __init__(self, *args) -> NoReturn: -- 2.25.1