b2e588368362556fe1978280d7167d1abf7666c3
2 # Copyright 2021 Canonical Ltd.
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
16 # For those usages not covered by the Apache License, Version 2.0 please
17 # contact: legal@canonical.com
19 # To get in touch with the maintainers, please contact:
20 # osm-charmers@lists.launchpad.net
23 # pylint: disable=E0213
27 from typing
import NoReturn
, Optional
29 from ops
.main
import main
30 from opslib
.osm
.charm
import CharmedOsmBase
, RelationsMissing
31 from opslib
.osm
.interfaces
.kafka
import KafkaClient
32 from opslib
.osm
.interfaces
.mongo
import MongoClient
33 from opslib
.osm
.pod
import (
37 from opslib
.osm
.validator
import ModelValidator
, validator
40 logger
= logging
.getLogger(__name__
)
45 class ConfigModel(ModelValidator
):
47 mongodb_uri
: Optional
[str]
49 @validator("log_level")
50 def validate_log_level(cls
, v
):
51 if v
not in {"INFO", "DEBUG"}:
52 raise ValueError("value must be INFO or DEBUG")
55 @validator("mongoddb_uri")
56 def validate_mongodb_uri(cls
, v
):
57 if v
and not v
.startswith("mongodb://"):
58 raise ValueError("mongodb_uri is not properly formed")
62 class PolCharm(CharmedOsmBase
):
63 def __init__(self
, *args
) -> NoReturn
:
64 super().__init
__(*args
, oci_image
="image")
66 self
.kafka_client
= KafkaClient(self
, "kafka")
67 self
.framework
.observe(self
.on
["kafka"].relation_changed
, self
.configure_pod
)
68 self
.framework
.observe(self
.on
["kafka"].relation_broken
, self
.configure_pod
)
70 self
.mongodb_client
= MongoClient(self
, "mongodb")
71 self
.framework
.observe(self
.on
["mongodb"].relation_changed
, self
.configure_pod
)
72 self
.framework
.observe(self
.on
["mongodb"].relation_broken
, self
.configure_pod
)
74 def _check_missing_dependencies(self
, config
: ConfigModel
):
75 missing_relations
= []
77 if self
.kafka_client
.is_missing_data_in_unit():
78 missing_relations
.append("kafka")
79 if not config
.mongodb_uri
and self
.mongodb_client
.is_missing_data_in_unit():
80 missing_relations
.append("mongodb")
83 raise RelationsMissing(missing_relations
)
85 def build_pod_spec(self
, image_info
):
87 config
= ConfigModel(**dict(self
.config
))
89 if config
.mongodb_uri
and not self
.mongodb_client
.is_missing_data_in_unit():
90 raise Exception("Mongodb data cannot be provided via config and relation")
93 self
._check
_missing
_dependencies
(config
)
95 # Create Builder for the PodSpec
96 pod_spec_builder
= PodSpecV3Builder()
99 container_builder
= ContainerV3Builder(self
.app
.name
, image_info
)
100 container_builder
.add_port(name
=self
.app
.name
, port
=PORT
)
101 container_builder
.add_envs(
103 # General configuration
104 "ALLOW_ANONYMOUS_LOGIN": "yes",
105 "OSMPOL_GLOBAL_LOGLEVEL": config
.log_level
,
106 # Kafka configuration
107 "OSMPOL_MESSAGE_DRIVER": "kafka",
108 "OSMPOL_MESSAGE_HOST": self
.kafka_client
.host
,
109 "OSMPOL_MESSAGE_PORT": self
.kafka_client
.port
,
110 # Database configuration
111 "OSMPOL_DATABASE_DRIVER": "mongo",
112 "OSMPOL_DATABASE_URI": config
.mongodb_uri
113 or self
.mongodb_client
.connection_string
,
116 container
= container_builder
.build()
118 # Add container to pod spec
119 pod_spec_builder
.add_container(container
)
121 return pod_spec_builder
.build()
124 if __name__
== "__main__":