blob: 16e7303f89b0fe1209ba4eabf8bc46d7089c665b [file] [log] [blame]
beierlma4a37f72020-06-26 12:55:01 -04001#!/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
beierlmb1a1c462020-10-23 14:54:56 -040016from glob import glob
beierlma4a37f72020-06-26 12:55:01 -040017import logging
beierlmb1a1c462020-10-23 14:54:56 -040018from pathlib import Path
19from string import Template
20import sys
beierlma4a37f72020-06-26 12:55:01 -040021
22from ops.charm import CharmBase
23from ops.framework import StoredState, Object
24from ops.main import main
25from ops.model import (
26 ActiveStatus,
27 MaintenanceStatus,
28 WaitingStatus,
29)
30
beierlmb1a1c462020-10-23 14:54:56 -040031
beierlma4a37f72020-06-26 12:55:01 -040032logger = logging.getLogger(__name__)
33
34
35class 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 = [
David Garciafa75eca2020-11-04 18:34:41 +010085 {
86 "name": "port",
87 "containerPort": config["port"],
88 "protocol": "TCP",
89 },
beierlma4a37f72020-06-26 12:55:01 -040090 ]
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,
David Garciafa75eca2020-11-04 18:34:41 +0100107 "imageDetails": {
108 "imagePath": config["image"],
109 "username": config["image_username"],
110 "password": config["image_password"],
111 },
beierlma4a37f72020-06-26 12:55:01 -0400112 "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")
David Garcia68faf8d2020-09-01 10:12:16 +0200132 self._apply_spec()
beierlma4a37f72020-06-26 12:55:01 -0400133
134 def on_kafka_relation_changed(self, event):
David Garcia68faf8d2020-09-01 10:12:16 +0200135 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
beierlma4a37f72020-06-26 12:55:01 -0400141 self._apply_spec()
142
143 def on_mongo_relation_changed(self, event):
David Garciafa75eca2020-11-04 18:34:41 +0100144 mongodb_uri = event.relation.data[event.unit].get("connection_string")
David Garcia68faf8d2020-09-01 10:12:16 +0200145 if mongodb_uri and self.state.mongodb_uri != mongodb_uri:
146 self.state.mongodb_uri = mongodb_uri
beierlma4a37f72020-06-26 12:55:01 -0400147 self._apply_spec()
148
149
150if __name__ == "__main__":
151 main(PLACharm)