From 13722ca955cf2dfc9fd7b11a4c11ea5dc63f1e46 Mon Sep 17 00:00:00 2001 From: sousaedu Date: Tue, 5 Jan 2021 14:25:19 +0000 Subject: [PATCH] Removing pydantic from LCM charm Change-Id: I08e4acff8b84f4f9a36846cc0f7973d06c4abc1c Signed-off-by: sousaedu --- installers/charm/lcm/requirements.txt | 1 - installers/charm/lcm/src/charm.py | 19 ++--- installers/charm/lcm/src/pod_spec.py | 74 +++++++++++------- installers/charm/lcm/tests/test_charm.py | 87 +-------------------- installers/charm/lcm/tests/test_pod_spec.py | 5 +- installers/charm/lcm/tox.ini | 1 - 6 files changed, 54 insertions(+), 133 deletions(-) diff --git a/installers/charm/lcm/requirements.txt b/installers/charm/lcm/requirements.txt index 24f1672c..a26601fe 100644 --- a/installers/charm/lcm/requirements.txt +++ b/installers/charm/lcm/requirements.txt @@ -20,5 +20,4 @@ ## ops -pydantic git+https://github.com/juju-solutions/resource-oci-image/@c5778285d332edf3d9a538f9d0c06154b7ec1b0b#egg=oci-image diff --git a/installers/charm/lcm/src/charm.py b/installers/charm/lcm/src/charm.py index d65bdcfa..52b6964a 100755 --- a/installers/charm/lcm/src/charm.py +++ b/installers/charm/lcm/src/charm.py @@ -21,7 +21,6 @@ ## import logging -from pydantic import ValidationError from typing import Any, Dict, NoReturn from ops.charm import CharmBase, CharmEvents @@ -112,10 +111,8 @@ class LcmCharm(CharmBase): Args: event (EventBase): Kafka relation event. """ - data_loc = event.unit if event.unit else event.app - - message_host = event.relation.data[data_loc].get("host") - message_port = event.relation.data[data_loc].get("port") + message_host = event.relation.data[event.unit].get("host") + message_port = event.relation.data[event.unit].get("port") if ( message_host @@ -145,9 +142,7 @@ class LcmCharm(CharmBase): Args: event (EventBase): DB relation event. """ - data_loc = event.unit if event.unit else event.app - - database_uri = event.relation.data[data_loc].get("connection_string") + database_uri = event.relation.data[event.unit].get("connection_string") if database_uri and self.state.database_uri != database_uri: self.state.database_uri = database_uri @@ -168,10 +163,8 @@ class LcmCharm(CharmBase): Args: event (EventBase): Keystone relation event. """ - data_loc = event.unit if event.unit else event.app - - ro_host = event.relation.data[data_loc].get("host") - ro_port = event.relation.data[data_loc].get("port") + ro_host = event.relation.data[event.unit].get("host") + ro_port = event.relation.data[event.unit].get("port") if ( ro_host @@ -262,7 +255,7 @@ class LcmCharm(CharmBase): self.model.app.name, self.port, ) - except ValidationError as exc: + except ValueError as exc: logger.exception("Config/Relation data validation error") self.unit.status = BlockedStatus(str(exc)) return diff --git a/installers/charm/lcm/src/pod_spec.py b/installers/charm/lcm/src/pod_spec.py index c0e9624c..dc214537 100644 --- a/installers/charm/lcm/src/pod_spec.py +++ b/installers/charm/lcm/src/pod_spec.py @@ -21,43 +21,60 @@ ## import logging -from pydantic import BaseModel, constr, PositiveInt, validator -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, NoReturn logger = logging.getLogger(__name__) -class ConfigData(BaseModel): - """Configuration data model.""" +def _validate_data( + config_data: Dict[str, Any], relation_data: Dict[str, Any] +) -> NoReturn: + """Validate input data. - database_commonkey: constr(min_length=1) - log_level: constr(regex=r"^(INFO|DEBUG)$") - vca_host: constr(min_length=1) - vca_port: PositiveInt - vca_user: constr(min_length=1) - vca_pubkey: constr(min_length=1) - vca_password: constr(min_length=1) - vca_cacert: str - vca_cloud: constr(min_length=1) - vca_k8s_cloud: constr(min_length=1) - vca_apiproxy: Optional[constr(min_length=1)] + Args: + config_data (Dict[str, Any]): configuration data. + relation_data (Dict[str, Any]): relation data. + """ + config_validators = { + "database_commonkey": lambda value, _: isinstance(value, str) + and len(value) > 1, + "log_level": lambda value, _: isinstance(value, str) + and value in ("INFO", "DEBUG"), + "vca_host": lambda value, _: isinstance(value, str) and len(value) > 1, + "vca_port": lambda value, _: isinstance(value, int) and value > 0, + "vca_user": lambda value, _: isinstance(value, str) and len(value) > 1, + "vca_pubkey": lambda value, _: isinstance(value, str) and len(value) > 1, + "vca_password": lambda value, _: isinstance(value, str) and len(value) > 1, + "vca_cacert": lambda value, _: isinstance(value, str), + "vca_cloud": lambda value, _: isinstance(value, str) and len(value) > 1, + "vca_k8s_cloud": lambda value, _: isinstance(value, str) and len(value) > 1, + "vca_apiproxy": lambda value, _: (isinstance(value, str) and len(value) > 1) + if value + else True, + } + relation_validators = { + "ro_host": lambda value, _: isinstance(value, str) and len(value) > 1, + "ro_port": lambda value, _: isinstance(value, int) and value > 0, + "message_host": lambda value, _: isinstance(value, str) and len(value) > 1, + "message_port": lambda value, _: isinstance(value, int) and value > 0, + "database_uri": lambda value, _: isinstance(value, str) and len(value) > 1, + } + problems = [] - @validator("vca_apiproxy", pre=True, always=True) - def validate_vca_apiproxy(cls, value, values, **kwargs): - if not value: - return None + for key, validator in config_validators.items(): + valid = validator(config_data.get(key), config_data) - return value + if not valid: + problems.append(key) + for key, validator in relation_validators.items(): + valid = validator(relation_data.get(key), relation_data) -class RelationData(BaseModel): - """Relation data model.""" + if not valid: + problems.append(key) - ro_host: constr(min_length=1) - ro_port: PositiveInt - message_host: constr(min_length=1) - message_port: PositiveInt - database_uri: constr(regex=r"^(mongodb://)") + if len(problems) > 0: + raise ValueError("Errors found in: {}".format(", ".join(problems))) def _make_pod_ports(port: int) -> List[Dict[str, Any]]: @@ -196,8 +213,7 @@ def make_pod_spec( if not image_info: return None - ConfigData(**(config)) - RelationData(**(relation_state)) + _validate_data(config, relation_state) ports = _make_pod_ports(port) env_config = _make_pod_envconfig(config, relation_state) diff --git a/installers/charm/lcm/tests/test_charm.py b/installers/charm/lcm/tests/test_charm.py index a7133e3d..25e2cd64 100644 --- a/installers/charm/lcm/tests/test_charm.py +++ b/installers/charm/lcm/tests/test_charm.py @@ -134,7 +134,7 @@ class TestCharm(unittest.TestCase): ro_relation_id = self.harness.add_relation("ro", "ro") self.harness.add_relation_unit(ro_relation_id, "ro/0") self.harness.update_relation_data( - ro_relation_id, "ro", {"host": "ro", "port": 9090} + ro_relation_id, "ro/0", {"host": "ro", "port": 9090} ) # Checking if kafka data is stored @@ -155,35 +155,6 @@ class TestCharm(unittest.TestCase): self.assertDictEqual(expected_result, pod_spec) - def test_on_kafka_relation_app_changed(self) -> NoReturn: - """Test to see if kafka relation is updated.""" - self.harness.charm.on.start.emit() - - self.assertIsNone(self.harness.charm.state.message_host) - self.assertIsNone(self.harness.charm.state.message_port) - - relation_id = self.harness.add_relation("kafka", "kafka") - self.harness.add_relation_unit(relation_id, "kafka/0") - self.harness.update_relation_data( - relation_id, "kafka", {"host": "kafka", "port": 9092} - ) - - self.assertEqual(self.harness.charm.state.message_host, "kafka") - self.assertEqual(self.harness.charm.state.message_port, 9092) - - # Verifying status - self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) - - # Verifying status message - self.assertGreater(len(self.harness.charm.unit.status.message), 0) - self.assertTrue( - self.harness.charm.unit.status.message.startswith("Waiting for ") - ) - self.assertNotIn("kafka", self.harness.charm.unit.status.message) - self.assertIn("mongodb", self.harness.charm.unit.status.message) - self.assertIn("ro", self.harness.charm.unit.status.message) - self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations")) - def test_on_kafka_relation_unit_changed(self) -> NoReturn: """Test to see if kafka relation is updated.""" self.harness.charm.on.start.emit() @@ -213,33 +184,6 @@ class TestCharm(unittest.TestCase): self.assertIn("ro", self.harness.charm.unit.status.message) self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations")) - def test_on_mongodb_app_relation_changed(self) -> NoReturn: - """Test to see if mongodb relation is updated.""" - self.harness.charm.on.start.emit() - - self.assertIsNone(self.harness.charm.state.database_uri) - - relation_id = self.harness.add_relation("mongodb", "mongodb") - self.harness.add_relation_unit(relation_id, "mongodb/0") - self.harness.update_relation_data( - relation_id, "mongodb", {"connection_string": "mongodb://mongo:27017"} - ) - - self.assertEqual(self.harness.charm.state.database_uri, "mongodb://mongo:27017") - - # Verifying status - self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) - - # Verifying status message - self.assertGreater(len(self.harness.charm.unit.status.message), 0) - self.assertTrue( - self.harness.charm.unit.status.message.startswith("Waiting for ") - ) - self.assertIn("kafka", self.harness.charm.unit.status.message) - self.assertNotIn("mongodb", self.harness.charm.unit.status.message) - self.assertIn("ro", self.harness.charm.unit.status.message) - self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations")) - def test_on_mongodb_unit_relation_changed(self) -> NoReturn: """Test to see if mongodb relation is updated.""" self.harness.charm.on.start.emit() @@ -267,35 +211,6 @@ class TestCharm(unittest.TestCase): self.assertIn("ro", self.harness.charm.unit.status.message) self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations")) - def test_on_ro_app_relation_changed(self) -> NoReturn: - """Test to see if RO relation is updated.""" - self.harness.charm.on.start.emit() - - self.assertIsNone(self.harness.charm.state.ro_host) - self.assertIsNone(self.harness.charm.state.ro_port) - - relation_id = self.harness.add_relation("ro", "ro") - self.harness.add_relation_unit(relation_id, "ro/0") - self.harness.update_relation_data( - relation_id, "ro", {"host": "ro", "port": 9090} - ) - - self.assertEqual(self.harness.charm.state.ro_host, "ro") - self.assertEqual(self.harness.charm.state.ro_port, 9090) - - # Verifying status - self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) - - # Verifying status message - self.assertGreater(len(self.harness.charm.unit.status.message), 0) - self.assertTrue( - self.harness.charm.unit.status.message.startswith("Waiting for ") - ) - self.assertIn("kafka", self.harness.charm.unit.status.message) - self.assertIn("mongodb", self.harness.charm.unit.status.message) - self.assertNotIn("ro", self.harness.charm.unit.status.message) - self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations")) - def test_on_ro_unit_relation_changed(self) -> NoReturn: """Test to see if RO relation is updated.""" self.harness.charm.on.start.emit() diff --git a/installers/charm/lcm/tests/test_pod_spec.py b/installers/charm/lcm/tests/test_pod_spec.py index 4c6b0cba..c74fb102 100644 --- a/installers/charm/lcm/tests/test_pod_spec.py +++ b/installers/charm/lcm/tests/test_pod_spec.py @@ -20,7 +20,6 @@ # osm-charmers@lists.launchpad.net ## -from pydantic import ValidationError from typing import NoReturn import unittest @@ -396,7 +395,7 @@ class TestPodSpec(unittest.TestCase): app_name = "lcm" port = 9999 - with self.assertRaises(ValidationError): + with self.assertRaises(ValueError): pod_spec.make_pod_spec(image_info, config, relation_state, app_name, port) def test_make_pod_spec_without_relation_state(self) -> NoReturn: @@ -419,7 +418,7 @@ class TestPodSpec(unittest.TestCase): app_name = "lcm" port = 9999 - with self.assertRaises(ValidationError): + with self.assertRaises(ValueError): pod_spec.make_pod_spec(image_info, config, relation_state, app_name, port) diff --git a/installers/charm/lcm/tox.ini b/installers/charm/lcm/tox.ini index 60ac1dec..bc7ee37a 100644 --- a/installers/charm/lcm/tox.ini +++ b/installers/charm/lcm/tox.ini @@ -56,7 +56,6 @@ deps = stestr mock ops - pydantic setenv = {[testenv]setenv} PYTHON=coverage run -- 2.25.1