Remove unneeded mysql interface in PLA, fix osm-ha bundle, and add README.md to bundles
[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.on_start(event)
127
128 def on_kafka_relation_changed(self, event):
129 unit = self.model.unit
130 if not unit.is_leader():
131 return
132 self.state.kafka_host = event.relation.data[event.unit].get("host")
133 self.state.kafka_port = event.relation.data[event.unit].get("port")
134 self._apply_spec()
135
136 def on_mongo_relation_changed(self, event):
137 unit = self.model.unit
138 if not unit.is_leader():
139 return
140 self.state.mongodb_uri = event.relation.data[event.unit].get(
141 "connection_string"
142 )
143 self._apply_spec()
144
145
146 if __name__ == "__main__":
147 main(PLACharm)