Add image_username and image_password to 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 from glob import glob
17 import logging
18 from pathlib import Path
19 from string import Template
20 import sys
21
22 from ops.charm import CharmBase
23 from ops.framework import StoredState, Object
24 from ops.main import main
25 from ops.model import (
26 ActiveStatus,
27 MaintenanceStatus,
28 WaitingStatus,
29 )
30
31
32 logger = logging.getLogger(__name__)
33
34
35 class PLACharm(CharmBase):
36 state = StoredState()
37
38 def __init__(self, framework, key):
39 super().__init__(framework, key)
40 self.state.set_default(spec=None)
41 self.state.set_default(kafka_host=None)
42 self.state.set_default(kafka_port=None)
43 self.state.set_default(mongodb_uri=None)
44
45 # Observe Charm related events
46 self.framework.observe(self.on.config_changed, self.on_config_changed)
47 self.framework.observe(self.on.start, self.on_start)
48 self.framework.observe(self.on.upgrade_charm, self.on_upgrade_charm)
49
50 # Relations
51 self.framework.observe(
52 self.on.kafka_relation_changed, self.on_kafka_relation_changed
53 )
54 self.framework.observe(
55 self.on.mongo_relation_changed, self.on_mongo_relation_changed
56 )
57
58 def _apply_spec(self):
59 # Only apply the spec if this unit is a leader.
60 unit = self.model.unit
61 if not unit.is_leader():
62 unit.status = ActiveStatus("ready")
63 return
64 if not self.state.kafka_host or not self.state.kafka_port:
65 unit.status = WaitingStatus("Waiting for Kafka")
66 return
67 if not self.state.mongodb_uri:
68 unit.status = WaitingStatus("Waiting for MongoDB")
69 return
70
71 unit.status = MaintenanceStatus("Applying new pod spec")
72
73 new_spec = self.make_pod_spec()
74 if new_spec == self.state.spec:
75 unit.status = ActiveStatus("ready")
76 return
77 self.framework.model.pod.set_spec(new_spec)
78 self.state.spec = new_spec
79 unit.status = ActiveStatus("ready")
80
81 def make_pod_spec(self):
82 config = self.framework.model.config
83
84 ports = [
85 {
86 "name": "port",
87 "containerPort": config["port"],
88 "protocol": "TCP",
89 },
90 ]
91
92 config_spec = {
93 "OSMPLA_MESSAGE_DRIVER": "kafka",
94 "OSMPLA_MESSAGE_HOST": self.state.kafka_host,
95 "OSMPLA_MESSAGE_PORT": self.state.kafka_port,
96 "OSMPLA_DATABASE_DRIVER": "mongo",
97 "OSMPLA_DATABASE_URI": self.state.mongodb_uri,
98 "OSMPLA_GLOBAL_LOG_LEVEL": config["log_level"],
99 "OSMPLA_DATABASE_COMMONKEY": config["database_common_key"],
100 }
101
102 spec = {
103 "version": 2,
104 "containers": [
105 {
106 "name": self.framework.model.app.name,
107 "imageDetails": {
108 "imagePath": config["image"],
109 "username": config["image_username"],
110 "password": config["image_password"],
111 },
112 "ports": ports,
113 "config": config_spec,
114 }
115 ],
116 }
117
118 return spec
119
120 def on_config_changed(self, event):
121 """Handle changes in configuration"""
122 self._apply_spec()
123
124 def on_start(self, event):
125 """Called when the charm is being installed"""
126 self._apply_spec()
127
128 def on_upgrade_charm(self, event):
129 """Upgrade the charm."""
130 unit = self.model.unit
131 unit.status = MaintenanceStatus("Upgrading charm")
132 self._apply_spec()
133
134 def on_kafka_relation_changed(self, event):
135 kafka_host = event.relation.data[event.unit].get("host")
136 kafka_port = event.relation.data[event.unit].get("port")
137 if kafka_host and self.state.kafka_host != kafka_host:
138 self.state.kafka_host = kafka_host
139 if kafka_port and self.state.kafka_port != kafka_port:
140 self.state.kafka_port = kafka_port
141 self._apply_spec()
142
143 def on_mongo_relation_changed(self, event):
144 mongodb_uri = event.relation.data[event.unit].get("connection_string")
145 if mongodb_uri and self.state.mongodb_uri != mongodb_uri:
146 self.state.mongodb_uri = mongodb_uri
147 self._apply_spec()
148
149
150 if __name__ == "__main__":
151 main(PLACharm)