Fix juju status in OSM Charms
[osm/devops.git] / installers / charm / pla / src / charm.py
1 #!/usr/bin/env python3
2 # Copyright 2020 Canonical Ltd.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 import sys
17 import logging
18
19 sys.path.append("lib")
20
21 from ops.charm import CharmBase
22 from ops.framework import StoredState, Object
23 from ops.main import main
24 from ops.model import (
25 ActiveStatus,
26 MaintenanceStatus,
27 WaitingStatus,
28 )
29
30 from glob import glob
31 from pathlib import Path
32 from string import Template
33
34 logger = logging.getLogger(__name__)
35
36
37 class PLACharm(CharmBase):
38 state = StoredState()
39
40 def __init__(self, framework, key):
41 super().__init__(framework, key)
42 self.state.set_default(spec=None)
43 self.state.set_default(kafka_host=None)
44 self.state.set_default(kafka_port=None)
45 self.state.set_default(mongodb_uri=None)
46
47 # Observe Charm related events
48 self.framework.observe(self.on.config_changed, self.on_config_changed)
49 self.framework.observe(self.on.start, self.on_start)
50 self.framework.observe(self.on.upgrade_charm, self.on_upgrade_charm)
51
52 # Relations
53 self.framework.observe(
54 self.on.kafka_relation_changed, self.on_kafka_relation_changed
55 )
56 self.framework.observe(
57 self.on.mongo_relation_changed, self.on_mongo_relation_changed
58 )
59
60 def _apply_spec(self):
61 # Only apply the spec if this unit is a leader.
62 unit = self.model.unit
63 if not unit.is_leader():
64 unit.status = ActiveStatus("ready")
65 return
66 if not self.state.kafka_host or not self.state.kafka_port:
67 unit.status = WaitingStatus("Waiting for Kafka")
68 return
69 if not self.state.mongodb_uri:
70 unit.status = WaitingStatus("Waiting for MongoDB")
71 return
72
73 unit.status = MaintenanceStatus("Applying new pod spec")
74
75 new_spec = self.make_pod_spec()
76 if new_spec == self.state.spec:
77 unit.status = ActiveStatus("ready")
78 return
79 self.framework.model.pod.set_spec(new_spec)
80 self.state.spec = new_spec
81 unit.status = ActiveStatus("ready")
82
83 def make_pod_spec(self):
84 config = self.framework.model.config
85
86 ports = [
87 {"name": "port", "containerPort": config["port"], "protocol": "TCP",},
88 ]
89
90 config_spec = {
91 "OSMPLA_MESSAGE_DRIVER": "kafka",
92 "OSMPLA_MESSAGE_HOST": self.state.kafka_host,
93 "OSMPLA_MESSAGE_PORT": self.state.kafka_port,
94 "OSMPLA_DATABASE_DRIVER": "mongo",
95 "OSMPLA_DATABASE_URI": self.state.mongodb_uri,
96 "OSMPLA_GLOBAL_LOG_LEVEL": config["log_level"],
97 "OSMPLA_DATABASE_COMMONKEY": config["database_common_key"],
98 }
99
100 spec = {
101 "version": 2,
102 "containers": [
103 {
104 "name": self.framework.model.app.name,
105 "image": config["image"],
106 "ports": ports,
107 "config": config_spec,
108 }
109 ],
110 }
111
112 return spec
113
114 def on_config_changed(self, event):
115 """Handle changes in configuration"""
116 self._apply_spec()
117
118 def on_start(self, event):
119 """Called when the charm is being installed"""
120 self._apply_spec()
121
122 def on_upgrade_charm(self, event):
123 """Upgrade the charm."""
124 unit = self.model.unit
125 unit.status = MaintenanceStatus("Upgrading charm")
126 self._apply_spec()
127
128 def on_kafka_relation_changed(self, event):
129 kafka_host = event.relation.data[event.unit].get("host")
130 kafka_port = event.relation.data[event.unit].get("port")
131 if kafka_host and self.state.kafka_host != kafka_host:
132 self.state.kafka_host = kafka_host
133 if kafka_port and self.state.kafka_port != kafka_port:
134 self.state.kafka_port = kafka_port
135 self._apply_spec()
136
137 def on_mongo_relation_changed(self, event):
138 mongodb_uri = event.relation.data[event.unit].get(
139 "connection_string"
140 )
141 if mongodb_uri and self.state.mongodb_uri != mongodb_uri:
142 self.state.mongodb_uri = mongodb_uri
143 self._apply_spec()
144
145
146 if __name__ == "__main__":
147 main(PLACharm)