Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python3 

2# Copyright 2021 Canonical Ltd. 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); you may 

5# not use this file except in compliance with the License. You may obtain 

6# 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, WITHOUT 

12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

13# License for the specific language governing permissions and limitations 

14# under the License. 

15# 

16# For those usages not covered by the Apache License, Version 2.0 please 

17# contact: legal@canonical.com 

18# 

19# To get in touch with the maintainers, please contact: 

20# osm-charmers@lists.launchpad.net 

21## 

22 

23# pylint: disable=E0213 

24 

25 

26import logging 

27from typing import NoReturn 

28 

29from ops.main import main 

30from opslib.osm.charm import CharmedOsmBase, RelationsMissing 

31from opslib.osm.interfaces.kafka import KafkaClient 

32from opslib.osm.interfaces.mongo import MongoClient 

33from opslib.osm.pod import ( 

34 ContainerV3Builder, 

35 PodSpecV3Builder, 

36) 

37from opslib.osm.validator import ModelValidator, validator 

38 

39 

40logger = logging.getLogger(__name__) 

41 

42PORT = 9999 

43 

44 

45class ConfigModel(ModelValidator): 

46 database_commonkey: str 

47 log_level: str 

48 

49 @validator("log_level") 

50 def validate_log_level(cls, v): 

51 if v not in {"INFO", "DEBUG"}: 

52 raise ValueError("value must be INFO or DEBUG") 

53 return v 

54 

55 

56class PlaCharm(CharmedOsmBase): 

57 def __init__(self, *args) -> NoReturn: 

58 super().__init__(*args, oci_image="image") 

59 

60 self.kafka_client = KafkaClient(self, "kafka") 

61 self.framework.observe(self.on["kafka"].relation_changed, self.configure_pod) 

62 self.framework.observe(self.on["kafka"].relation_broken, self.configure_pod) 

63 

64 self.mongodb_client = MongoClient(self, "mongodb") 

65 self.framework.observe(self.on["mongodb"].relation_changed, self.configure_pod) 

66 self.framework.observe(self.on["mongodb"].relation_broken, self.configure_pod) 

67 

68 def _check_missing_dependencies(self, config: ConfigModel): 

69 missing_relations = [] 

70 

71 if self.kafka_client.is_missing_data_in_unit(): 

72 missing_relations.append("kafka") 

73 if self.mongodb_client.is_missing_data_in_unit(): 

74 missing_relations.append("mongodb") 

75 

76 if missing_relations: 

77 raise RelationsMissing(missing_relations) 

78 

79 def build_pod_spec(self, image_info): 

80 # Validate config 

81 config = ConfigModel(**dict(self.config)) 

82 # Check relations 

83 self._check_missing_dependencies(config) 

84 # Create Builder for the PodSpec 

85 pod_spec_builder = PodSpecV3Builder() 

86 # Build Container 

87 container_builder = ContainerV3Builder(self.app.name, image_info) 

88 container_builder.add_port(name=self.app.name, port=PORT) 

89 container_builder.add_envs( 

90 { 

91 # General configuration 

92 "ALLOW_ANONYMOUS_LOGIN": "yes", 

93 "OSMPLA_GLOBAL_LOG_LEVEL": config.log_level, 

94 # Kafka configuration 

95 "OSMPLA_MESSAGE_DRIVER": "kafka", 

96 "OSMPLA_MESSAGE_HOST": self.kafka_client.host, 

97 "OSMPLA_MESSAGE_PORT": self.kafka_client.port, 

98 # Database configuration 

99 "OSMPLA_DATABASE_DRIVER": "mongo", 

100 "OSMPLA_DATABASE_URI": self.mongodb_client.connection_string, 

101 "OSMPLA_DATABASE_COMMONKEY": config.database_commonkey, 

102 } 

103 ) 

104 

105 container = container_builder.build() 

106 # Add container to pod spec 

107 pod_spec_builder.add_container(container) 

108 return pod_spec_builder.build() 

109 

110 

111if __name__ == "__main__": 

112 main(PlaCharm)