From accf1171620c343e847f61ce2dd752dbd08bcdb1 Mon Sep 17 00:00:00 2001 From: David Garcia Date: Mon, 10 May 2021 12:59:33 +0200 Subject: [PATCH] Add integration between pol and mysql charms - Added mysql_uri config in POL charm - Added mysql relation endpoint in POL charm Change-Id: I7983c1b83da6d894af864669b918215611848bf7 Signed-off-by: David Garcia --- installers/charm/bundles/osm-ha/bundle.yaml | 2 + installers/charm/bundles/osm/bundle.yaml | 2 + installers/charm/pol/config.yaml | 5 ++ installers/charm/pol/metadata.yaml | 3 ++ installers/charm/pol/src/charm.py | 22 ++++++++- installers/charm/pol/tests/test_charm.py | 52 +++++++++++++++++++++ 6 files changed, 85 insertions(+), 1 deletion(-) diff --git a/installers/charm/bundles/osm-ha/bundle.yaml b/installers/charm/bundles/osm-ha/bundle.yaml index 0843115a..b1804b85 100644 --- a/installers/charm/bundles/osm-ha/bundle.yaml +++ b/installers/charm/bundles/osm-ha/bundle.yaml @@ -216,3 +216,5 @@ relations: - nbi:nbi - - mon:keystone - keystone:keystone + - - mariadb-k8s:mysql + - pol:mysql diff --git a/installers/charm/bundles/osm/bundle.yaml b/installers/charm/bundles/osm/bundle.yaml index 824ff4c6..bc0c4006 100644 --- a/installers/charm/bundles/osm/bundle.yaml +++ b/installers/charm/bundles/osm/bundle.yaml @@ -209,3 +209,5 @@ relations: - nbi:nbi - - mon:keystone - keystone:keystone + - - mariadb-k8s:mysql + - pol:mysql diff --git a/installers/charm/pol/config.yaml b/installers/charm/pol/config.yaml index 59f695be..909235e0 100644 --- a/installers/charm/pol/config.yaml +++ b/installers/charm/pol/config.yaml @@ -27,3 +27,8 @@ options: mongodb_uri: type: string description: MongoDB URI (external database) + mysql_uri: + type: string + description: | + Mysql URI with the following format: + mysql://:@:/ diff --git a/installers/charm/pol/metadata.yaml b/installers/charm/pol/metadata.yaml index f9839b97..e01293b4 100644 --- a/installers/charm/pol/metadata.yaml +++ b/installers/charm/pol/metadata.yaml @@ -43,3 +43,6 @@ requires: interface: kafka mongodb: interface: mongodb + mysql: + interface: mysql + limit: 1 diff --git a/installers/charm/pol/src/charm.py b/installers/charm/pol/src/charm.py index b2e58836..1ad1e266 100755 --- a/installers/charm/pol/src/charm.py +++ b/installers/charm/pol/src/charm.py @@ -24,12 +24,14 @@ import logging +import re 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, @@ -40,11 +42,13 @@ from opslib.osm.validator import ModelValidator, validator logger = logging.getLogger(__name__) PORT = 9999 +DEFAULT_MYSQL_DATABASE = "pol" class ConfigModel(ModelValidator): log_level: str mongodb_uri: Optional[str] + mysql_uri: Optional[str] @validator("log_level") def validate_log_level(cls, v): @@ -58,6 +62,13 @@ class ConfigModel(ModelValidator): raise ValueError("mongodb_uri is not properly formed") return v + @validator("mysql_uri") + def validate_mysql_uri(cls, v): + pattern = re.compile("^mysql:\/\/.*:.*@.*:\d+\/.*$") # noqa: W605 + if v and not pattern.search(v): + raise ValueError("mysql_uri is not properly formed") + return v + class PolCharm(CharmedOsmBase): def __init__(self, *args) -> NoReturn: @@ -71,6 +82,10 @@ class PolCharm(CharmedOsmBase): self.framework.observe(self.on["mongodb"].relation_changed, self.configure_pod) self.framework.observe(self.on["mongodb"].relation_broken, self.configure_pod) + self.mysql_client = MysqlClient(self, "mysql") + self.framework.observe(self.on["mysql"].relation_changed, self.configure_pod) + self.framework.observe(self.on["mysql"].relation_broken, self.configure_pod) + def _check_missing_dependencies(self, config: ConfigModel): missing_relations = [] @@ -78,7 +93,8 @@ class PolCharm(CharmedOsmBase): missing_relations.append("kafka") if not config.mongodb_uri and self.mongodb_client.is_missing_data_in_unit(): missing_relations.append("mongodb") - + if not config.mysql_uri and self.mysql_client.is_missing_data_in_unit(): + missing_relations.append("mysql") if missing_relations: raise RelationsMissing(missing_relations) @@ -88,6 +104,8 @@ class PolCharm(CharmedOsmBase): 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") + if config.mysql_uri and not self.mysql_client.is_missing_data_in_unit(): + raise Exception("Mysql data cannot be provided via config and relation") # Check relations self._check_missing_dependencies(config) @@ -111,6 +129,8 @@ class PolCharm(CharmedOsmBase): "OSMPOL_DATABASE_DRIVER": "mongo", "OSMPOL_DATABASE_URI": config.mongodb_uri or self.mongodb_client.connection_string, + "OSMPOL_SQL_DATABASE_URI": config.mysql_uri + or self.mysql_client.get_root_uri(DEFAULT_MYSQL_DATABASE), } ) container = container_builder.build() diff --git a/installers/charm/pol/tests/test_charm.py b/installers/charm/pol/tests/test_charm.py index 089b6e52..330ecee6 100644 --- a/installers/charm/pol/tests/test_charm.py +++ b/installers/charm/pol/tests/test_charm.py @@ -74,6 +74,7 @@ class TestCharm(unittest.TestCase): self, ) -> NoReturn: "Test with relations and mongodb config (internal)" + self.initialize_mysql_relation() self.initialize_kafka_relation() self.initialize_mongo_config() # Verifying status @@ -85,6 +86,7 @@ class TestCharm(unittest.TestCase): "Test with relations (internal)" self.initialize_kafka_relation() self.initialize_mongo_relation() + self.initialize_mysql_relation() # Verifying status self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus) @@ -97,6 +99,35 @@ class TestCharm(unittest.TestCase): # Verifying status self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) + def test_mysql_config_success(self): + self.initialize_kafka_relation() + self.initialize_mongo_relation() + self.initialize_mysql_config() + # Verifying status + self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus) + + def test_mysql_config_wrong_value(self): + self.initialize_kafka_relation() + self.initialize_mongo_relation() + self.initialize_mysql_config(uri="wrong_uri") + # Verifying status + self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) + self.assertIn( + "mysql_uri is not properly formed", + self.harness.charm.unit.status.message, + ) + + def test_mysql_config_and_relation(self): + self.initialize_mysql_relation() + self.initialize_mysql_config() + # Verifying status + self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) + # import pdb; pdb.set_trace() + self.assertIn( + "Mysql data cannot be provided via config and relation", + self.harness.charm.unit.status.message, + ) + def initialize_kafka_relation(self): kafka_relation_id = self.harness.add_relation("kafka", "kafka") self.harness.add_relation_unit(kafka_relation_id, "kafka/0") @@ -116,6 +147,27 @@ class TestCharm(unittest.TestCase): {"connection_string": "mongodb://mongo:27017"}, ) + def initialize_mysql_config(self, uri=None): + self.harness.update_config( + {"mysql_uri": uri or "mysql://user:pass@mysql-host:3306/database"} + ) + + def initialize_mysql_relation(self): + mongodb_relation_id = self.harness.add_relation("mysql", "mysql") + self.harness.add_relation_unit(mongodb_relation_id, "mysql/0") + self.harness.update_relation_data( + mongodb_relation_id, + "mysql/0", + { + "user": "user", + "password": "pass", + "host": "host", + "port": "1234", + "database": "pol", + "root_password": "root_password", + }, + ) + if __name__ == "__main__": unittest.main() -- 2.17.1