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 log_level: str 

47 

48 @validator("log_level") 

49 def validate_log_level(cls, v): 

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

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

52 return v 

53 

54 

55class PolCharm(CharmedOsmBase): 

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

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

58 

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

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

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

62 

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

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

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

66 

67 def _check_missing_dependencies(self, config: ConfigModel): 

68 missing_relations = [] 

69 

70 if self.kafka_client.is_missing_data_in_unit(): 

71 missing_relations.append("kafka") 

72 if self.mongodb_client.is_missing_data_in_unit(): 

73 missing_relations.append("mongodb") 

74 

75 if missing_relations: 

76 raise RelationsMissing(missing_relations) 

77 

78 def build_pod_spec(self, image_info): 

79 # Validate config 

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

81 # Check relations 

82 self._check_missing_dependencies(config) 

83 # Create Builder for the PodSpec 

84 pod_spec_builder = PodSpecV3Builder() 

85 # Build Container 

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

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

88 container_builder.add_envs( 

89 { 

90 # General configuration 

91 "ALLOW_ANONYMOUS_LOGIN": "yes", 

92 "OSMPOL_GLOBAL_LOGLEVEL": config.log_level, 

93 # Kafka configuration 

94 "OSMPOL_MESSAGE_DRIVER": "kafka", 

95 "OSMPOL_MESSAGE_HOST": self.kafka_client.host, 

96 "OSMPOL_MESSAGE_PORT": self.kafka_client.port, 

97 # Database configuration 

98 "OSMPOL_DATABASE_DRIVER": "mongo", 

99 "OSMPOL_DATABASE_URI": self.mongodb_client.connection_string, 

100 } 

101 ) 

102 

103 container = container_builder.build() 

104 # Add container to pod spec 

105 pod_spec_builder.add_container(container) 

106 return pod_spec_builder.build() 

107 

108 

109if __name__ == "__main__": 

110 main(PolCharm)