Skip to content
Snippets Groups Projects
Commit accf1171 authored by garciadav's avatar garciadav Committed by Mark Beierl
Browse files

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: default avatarDavid Garcia <david.garcia@canonical.com>
parent 76a02050
No related branches found
No related tags found
No related merge requests found
......@@ -216,3 +216,5 @@ relations:
- nbi:nbi
- - mon:keystone
- keystone:keystone
- - mariadb-k8s:mysql
- pol:mysql
......@@ -209,3 +209,5 @@ relations:
- nbi:nbi
- - mon:keystone
- keystone:keystone
- - mariadb-k8s:mysql
- pol:mysql
......@@ -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://<user>:<password>@<mysql_host>:<mysql_port>/<database>
......@@ -43,3 +43,6 @@ requires:
interface: kafka
mongodb:
interface: mongodb
mysql:
interface: mysql
limit: 1
......@@ -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()
......
......@@ -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()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment