2 # Copyright 2020 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
24 from typing
import Any
, Dict
, List
, NoReturn
26 logger
= logging
.getLogger(__name__
)
30 config_data
: Dict
[str, Any
], relation_data
: Dict
[str, Any
]
32 """Validates passed information.
35 config_data (Dict[str, Any]): configuration information.
36 relation_data (Dict[str, Any]): relation information
39 ValueError: when config and/or relation data is not valid.
42 "enable_ng_ro": lambda value
, _
: isinstance(value
, bool),
43 "database_commonkey": lambda value
, values
: (
44 isinstance(value
, str) and len(value
) > 0
46 if values
.get("enable_ng_ro", True)
48 "log_level": lambda value
, _
: (
49 isinstance(value
, str) and value
in ("INFO", "DEBUG")
51 "vim_database": lambda value
, values
: (
52 isinstance(value
, str) and len(value
) > 0
54 if not values
.get("enable_ng_ro", True)
56 "ro_database": lambda value
, values
: (isinstance(value
, str) and len(value
) > 0)
57 if not values
.get("enable_ng_ro", True)
59 "openmano_tenant": lambda value
, values
: (
60 isinstance(value
, str) and len(value
) > 0
62 if not values
.get("enable_ng_ro", True)
65 relation_validators
= {
66 "kafka_host": lambda value
, _
: (isinstance(value
, str) and len(value
) > 0)
67 if config_data
.get("enable_ng_ro", True)
69 "kafka_port": lambda value
, _
: (isinstance(value
, str) and len(value
) > 0)
70 if config_data
.get("enable_ng_ro", True)
72 "mongodb_connection_string": lambda value
, _
: (
73 isinstance(value
, str) and value
.startswith("mongodb://")
75 if config_data
.get("enable_ng_ro", True)
77 "mysql_host": lambda value
, _
: (isinstance(value
, str) and len(value
) > 0)
78 if not config_data
.get("enable_ng_ro", True)
80 "mysql_port": lambda value
, _
: (isinstance(value
, int) and value
> 0)
81 if not config_data
.get("enable_ng_ro", True)
83 "mysql_user": lambda value
, _
: (isinstance(value
, str) and len(value
) > 0)
84 if not config_data
.get("enable_ng_ro", True)
86 "mysql_password": lambda value
, _
: (isinstance(value
, str) and len(value
) > 0)
87 if not config_data
.get("enable_ng_ro", True)
89 "mysql_root_password": lambda value
, _
: (
90 isinstance(value
, str) and len(value
) > 0
92 if not config_data
.get("enable_ng_ro", True)
97 for key
, validator
in config_validators
.items():
98 valid
= validator(config_data
.get(key
), config_data
)
103 for key
, validator
in relation_validators
.items():
104 valid
= validator(relation_data
.get(key
), relation_data
)
109 if len(problems
) > 0:
110 raise ValueError("Errors found in: {}".format(", ".join(problems
)))
113 def _make_pod_ports(port
: int) -> List
[Dict
[str, Any
]]:
114 """Generate pod ports details.
117 port (int): port to expose.
120 List[Dict[str, Any]]: pod port details.
122 return [{"name": "ro", "containerPort": port
, "protocol": "TCP"}]
125 def _make_pod_envconfig(
126 config
: Dict
[str, Any
], relation_state
: Dict
[str, Any
]
128 """Generate pod environment configuration.
131 config (Dict[str, Any]): configuration information.
132 relation_state (Dict[str, Any]): relation state information.
135 Dict[str, Any]: pod environment configuration.
138 # General configuration
139 "OSMRO_LOG_LEVEL": config
["log_level"],
142 if config
.get("enable_ng_ro", True):
143 # Kafka configuration
144 envconfig
["OSMRO_MESSAGE_DRIVER"] = "kafka"
145 envconfig
["OSMRO_MESSAGE_HOST"] = relation_state
["kafka_host"]
146 envconfig
["OSMRO_MESSAGE_PORT"] = relation_state
["kafka_port"]
148 # MongoDB configuration
149 envconfig
["OSMRO_DATABASE_DRIVER"] = "mongo"
150 envconfig
["OSMRO_DATABASE_URI"] = relation_state
["mongodb_connection_string"]
151 envconfig
["OSMRO_DATABASE_COMMONKEY"] = config
["database_commonkey"]
153 envconfig
["RO_DB_HOST"] = relation_state
["mysql_host"]
154 envconfig
["RO_DB_OVIM_HOST"] = relation_state
["mysql_host"]
155 envconfig
["RO_DB_PORT"] = relation_state
["mysql_port"]
156 envconfig
["RO_DB_OVIM_PORT"] = relation_state
["mysql_port"]
157 envconfig
["RO_DB_USER"] = relation_state
["mysql_user"]
158 envconfig
["RO_DB_OVIM_USER"] = relation_state
["mysql_user"]
159 envconfig
["RO_DB_PASSWORD"] = relation_state
["mysql_password"]
160 envconfig
["RO_DB_OVIM_PASSWORD"] = relation_state
["mysql_password"]
161 envconfig
["RO_DB_ROOT_PASSWORD"] = relation_state
["mysql_root_password"]
162 envconfig
["RO_DB_OVIM_ROOT_PASSWORD"] = relation_state
["mysql_root_password"]
163 envconfig
["RO_DB_NAME"] = config
["ro_database"]
164 envconfig
["RO_DB_OVIM_NAME"] = config
["vim_database"]
165 envconfig
["OPENMANO_TENANT"] = config
["openmano_tenant"]
170 def _make_startup_probe() -> Dict
[str, Any
]:
171 """Generate startup probe.
174 Dict[str, Any]: startup probe.
177 "exec": {"command": ["/usr/bin/pgrep", "python3"]},
178 "initialDelaySeconds": 60,
183 def _make_readiness_probe(port
: int) -> Dict
[str, Any
]:
184 """Generate readiness probe.
187 port (int): service port.
190 Dict[str, Any]: readiness probe.
194 "path": "/openmano/tenants",
199 "successThreshold": 1,
200 "failureThreshold": 3,
204 def _make_liveness_probe(port
: int) -> Dict
[str, Any
]:
205 """Generate liveness probe.
208 port (int): service port.
211 Dict[str, Any]: liveness probe.
215 "path": "/openmano/tenants",
218 "initialDelaySeconds": 600,
221 "successThreshold": 1,
222 "failureThreshold": 3,
227 image_info
: Dict
[str, str],
228 config
: Dict
[str, Any
],
229 relation_state
: Dict
[str, Any
],
230 app_name
: str = "ro",
233 """Generate the pod spec information.
236 image_info (Dict[str, str]): Object provided by
237 OCIImageResource("image").fetch().
238 config (Dict[str, Any]): Configuration information.
239 relation_state (Dict[str, Any]): Relation state information.
240 app_name (str, optional): Application name. Defaults to "ro".
241 port (int, optional): Port for the container. Defaults to 9090.
244 Dict[str, Any]: Pod spec dictionary for the charm.
249 _validate_data(config
, relation_state
)
251 ports
= _make_pod_ports(port
)
252 env_config
= _make_pod_envconfig(config
, relation_state
)
253 startup_probe
= _make_startup_probe()
254 readiness_probe
= _make_readiness_probe(port
)
255 liveness_probe
= _make_liveness_probe(port
)
262 "imageDetails": image_info
,
263 "imagePullPolicy": "Always",
265 "envConfig": env_config
,
267 "startupProbe": startup_probe
,
268 "readinessProbe": readiness_probe
,
269 "livenessProbe": liveness_probe
,
273 "kubernetesResources": {
274 "ingressResources": [],