2 # Copyright 2020 Canonical Ltd.
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
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,
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.
19 sys
.path
.append("lib")
21 from ops
.charm
import CharmBase
22 from ops
.framework
import StoredState
, Object
23 from ops
.main
import main
24 from ops
.model
import (
31 from pathlib
import Path
32 from string
import Template
34 logger
= logging
.getLogger(__name__
)
37 class PLACharm(CharmBase
):
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 self
.state
.set_default(mysql_host
=None)
47 self
.state
.set_default(mysql_port
=None)
49 # Observe Charm related events
50 self
.framework
.observe(self
.on
.config_changed
, self
.on_config_changed
)
51 self
.framework
.observe(self
.on
.start
, self
.on_start
)
52 self
.framework
.observe(self
.on
.upgrade_charm
, self
.on_upgrade_charm
)
55 self
.framework
.observe(
56 self
.on
.kafka_relation_changed
, self
.on_kafka_relation_changed
58 self
.framework
.observe(
59 self
.on
.mongo_relation_changed
, self
.on_mongo_relation_changed
61 self
.framework
.observe(
62 self
.on
.mysql_relation_changed
, self
.on_mysql_relation_changed
65 def _apply_spec(self
):
66 # Only apply the spec if this unit is a leader.
67 unit
= self
.model
.unit
68 if not unit
.is_leader():
69 unit
.status
= ActiveStatus("Ready")
71 if not self
.state
.kafka_host
or not self
.state
.kafka_port
:
72 unit
.status
= WaitingStatus("Waiting for Kafka")
74 if not self
.state
.mongodb_uri
:
75 unit
.status
= WaitingStatus("Waiting for MongoDB")
77 if not self
.state
.mysql_host
or not self
.state
.mysql_port
:
78 unit
.status
= WaitingStatus("Waiting for MySQL")
81 unit
.status
= MaintenanceStatus("Applying new pod spec")
83 new_spec
= self
.make_pod_spec()
84 if new_spec
== self
.state
.spec
:
85 unit
.status
= ActiveStatus("Ready")
87 self
.framework
.model
.pod
.set_spec(new_spec
)
88 self
.state
.spec
= new_spec
89 unit
.status
= ActiveStatus("Ready")
91 def make_pod_spec(self
):
92 config
= self
.framework
.model
.config
94 mysql_uri
= "mysql://root:{}@{}:{}/{}".format(
95 self
.state
.mysql_root_password
,
96 self
.state
.mysql_host
,
97 self
.state
.mysql_port
,
98 self
.state
.mysql_database
,
101 {"name": "port", "containerPort": config
["port"], "protocol": "TCP",},
105 "OSMPLA_MESSAGE_DRIVER": "kafka",
106 "OSMPLA_MESSAGE_HOST": self
.state
.kafka_host
,
107 "OSMPLA_MESSAGE_PORT": self
.state
.kafka_port
,
108 "OSMPLA_DATABASE_DRIVER": "mongo",
109 "OSMPLA_DATABASE_URI": self
.state
.mongodb_uri
,
110 "OSMPLA_GLOBAL_LOG_LEVEL": config
["log_level"],
111 "OSMPLA_SQL_DATABASE_URI": mysql_uri
,
112 "OSMPLA_DATABASE_COMMONKEY": config
["database_common_key"],
119 "name": self
.framework
.model
.app
.name
,
120 "image": config
["image"],
122 "config": config_spec
,
129 def on_config_changed(self
, event
):
130 """Handle changes in configuration"""
133 def on_start(self
, event
):
134 """Called when the charm is being installed"""
137 def on_upgrade_charm(self
, event
):
138 """Upgrade the charm."""
139 unit
= self
.model
.unit
140 unit
.status
= MaintenanceStatus("Upgrading charm")
143 def on_kafka_relation_changed(self
, event
):
144 unit
= self
.model
.unit
145 if not unit
.is_leader():
147 self
.state
.kafka_host
= event
.relation
.data
[event
.unit
].get("host")
148 self
.state
.kafka_port
= event
.relation
.data
[event
.unit
].get("port")
151 def on_mongo_relation_changed(self
, event
):
152 unit
= self
.model
.unit
153 if not unit
.is_leader():
155 self
.state
.mongodb_uri
= event
.relation
.data
[event
.unit
].get(
160 def on_mysql_relation_changed(self
, event
):
161 unit
= self
.model
.unit
162 if not unit
.is_leader():
164 unit_data
= event
.relation
.data
[event
.unit
]
165 self
.state
.mysql_host
= unit_data
.get("host")
166 self
.state
.mysql_port
= unit_data
.get("port")
167 self
.state
.mysql_root_password
= unit_data
.get("root_password")
168 self
.state
.mysql_database
= self
.model
.config
["database"]
172 if __name__
== "__main__":