Merge ~ballot/charm-k8s-mm-pd-bot/+git/charm-k8s-mm-pd-bot:quotes into charm-k8s-mm-pd-bot:master
- Git
- lp:~ballot/charm-k8s-mm-pd-bot/+git/charm-k8s-mm-pd-bot
- quotes
- Merge into master
Proposed by
Benjamin Allot
Status: | Merged |
---|---|
Approved by: | Benjamin Allot |
Approved revision: | 8d9e09b73c39cb2d02f2975762942c830e966e9f |
Merged at revision: | 8671d0b6c001cc0e0ae09865386645511af1c755 |
Proposed branch: | ~ballot/charm-k8s-mm-pd-bot/+git/charm-k8s-mm-pd-bot:quotes |
Merge into: | charm-k8s-mm-pd-bot:master |
Diff against target: |
727 lines (+210/-211) 4 files modified
pyproject.toml (+0/-1) src/charm.py (+41/-41) tests/unit/scenario.py (+143/-143) tests/unit/test_charm.py (+26/-26) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurent Sesquès | Approve | ||
Canonical IS Reviewers | Pending | ||
Review via email:
|
Commit message
Normalize quotes with black
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Change successfully merged at revision 8671d0b6c001cc0
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/pyproject.toml b/pyproject.toml |
2 | index d2f23b9..55ec8d7 100644 |
3 | --- a/pyproject.toml |
4 | +++ b/pyproject.toml |
5 | @@ -1,3 +1,2 @@ |
6 | [tool.black] |
7 | -skip-string-normalization = true |
8 | line-length = 120 |
9 | diff --git a/src/charm.py b/src/charm.py |
10 | index b17ced0..7b2807f 100755 |
11 | --- a/src/charm.py |
12 | +++ b/src/charm.py |
13 | @@ -18,18 +18,18 @@ from ops.model import ( |
14 | |
15 | logger = logging.getLogger() |
16 | |
17 | -REQUIRED_JUJU_SETTINGS = ['image_path', 'mm_pd_bot_cfg'] |
18 | +REQUIRED_JUJU_SETTINGS = ["image_path", "mm_pd_bot_cfg"] |
19 | REQUIRED_CFG_SETTINGS = { |
20 | - 'PagerDuty': ['account', 'api-token', 'private-channel', 'public-channel'], |
21 | - 'Prometheus': ['max_cache_size'], |
22 | - 'httpd': ['hostname', 'listen-ip', 'listen-port', 'magic-uuid'], |
23 | - 'MattermostBot': ['bot_url', 'bot_team'], |
24 | + "PagerDuty": ["account", "api-token", "private-channel", "public-channel"], |
25 | + "Prometheus": ["max_cache_size"], |
26 | + "httpd": ["hostname", "listen-ip", "listen-port", "magic-uuid"], |
27 | + "MattermostBot": ["bot_url", "bot_team"], |
28 | # Those sections can be empty |
29 | - 'nickname to email': [], |
30 | - 'Mattermost Aliases': [], |
31 | - 'PagerDuty service to Mattermost Channel': [], |
32 | + "nickname to email": [], |
33 | + "Mattermost Aliases": [], |
34 | + "PagerDuty service to Mattermost Channel": [], |
35 | } |
36 | -BOT_CFG_SECTION = 'MattermostBot' |
37 | +BOT_CFG_SECTION = "MattermostBot" |
38 | |
39 | |
40 | class MmPdBotK8sCharmConfigError(Exception): |
41 | @@ -51,9 +51,9 @@ class MmPdBotK8sCharm(CharmBase): |
42 | :raises MmPdBotK8sCharmConfigError: Raise if you don't have a bot_token or the combination of bot_login and |
43 | bot_password. |
44 | """ |
45 | - bot_token = self.bot_config.get(BOT_CFG_SECTION, 'bot_token', fallback=None) |
46 | - bot_login = self.bot_config.get(BOT_CFG_SECTION, 'bot_login', fallback=None) |
47 | - bot_password = self.bot_config.get(BOT_CFG_SECTION, 'bot_password', fallback=None) |
48 | + bot_token = self.bot_config.get(BOT_CFG_SECTION, "bot_token", fallback=None) |
49 | + bot_login = self.bot_config.get(BOT_CFG_SECTION, "bot_login", fallback=None) |
50 | + bot_password = self.bot_config.get(BOT_CFG_SECTION, "bot_password", fallback=None) |
51 | |
52 | if not bot_token and (not bot_login or not bot_password): |
53 | err_msg = "bot_token or bot_login/bot_password in {0} section required".format(BOT_CFG_SECTION) |
54 | @@ -129,7 +129,7 @@ class MmPdBotK8sCharm(CharmBase): |
55 | |
56 | def _validate_mm_pd_bot_configuration(self) -> None: |
57 | """Check the configuration part related to mm_pd_bot configuration.""" |
58 | - self.bot_config = self._load_mm_pd_bot_configuration(self.model.config['mm_pd_bot_cfg']) |
59 | + self.bot_config = self._load_mm_pd_bot_configuration(self.model.config["mm_pd_bot_cfg"]) |
60 | self._validate_mm_pd_bot_configuration_content() |
61 | self._validate_bot_creds() |
62 | |
63 | @@ -148,7 +148,7 @@ class MmPdBotK8sCharm(CharmBase): |
64 | """ |
65 | config = self.model.config |
66 | pod_config = { |
67 | - 'MM_PD_BOT_CFG': config['mm_pd_bot_cfg'], |
68 | + "MM_PD_BOT_CFG": config["mm_pd_bot_cfg"], |
69 | } |
70 | |
71 | return pod_config |
72 | @@ -159,10 +159,10 @@ class MmPdBotK8sCharm(CharmBase): |
73 | :param pod_spec: pod spec v3 as defined by juju. |
74 | """ |
75 | |
76 | - hostname = self.bot_config.get('httpd', 'hostname') |
77 | - container_port = self.bot_config.getint('httpd', 'listen-port') |
78 | - magic_uuid = self.bot_config.get('httpd', 'magic-uuid') |
79 | - tls_secret_name = self.model.config.get('tls_secret_name', None) |
80 | + hostname = self.bot_config.get("httpd", "hostname") |
81 | + container_port = self.bot_config.getint("httpd", "listen-port") |
82 | + magic_uuid = self.bot_config.get("httpd", "magic-uuid") |
83 | + tls_secret_name = self.model.config.get("tls_secret_name", None) |
84 | |
85 | if tls_secret_name: |
86 | scheme = "https" |
87 | @@ -192,52 +192,52 @@ class MmPdBotK8sCharm(CharmBase): |
88 | }, |
89 | } |
90 | if tls_secret_name: |
91 | - ingress['spec']['tls'] = [ |
92 | - {'hosts': [bot_listening_url_parsed.hostname], 'secretName': tls_secret_name}, |
93 | + ingress["spec"]["tls"] = [ |
94 | + {"hosts": [bot_listening_url_parsed.hostname], "secretName": tls_secret_name}, |
95 | ] |
96 | else: |
97 | - annotations['nginx.ingress.kubernetes.io/ssl-redirect'] = 'false' |
98 | + annotations["nginx.ingress.kubernetes.io/ssl-redirect"] = "false" |
99 | |
100 | - ingress_whitelist_source_range = self.model.config.get('ingress_whitelist_source_range', None) |
101 | + ingress_whitelist_source_range = self.model.config.get("ingress_whitelist_source_range", None) |
102 | if ingress_whitelist_source_range: |
103 | - annotations['nginx.ingress.kubernetes.io/whitelist-source-range'] = ingress_whitelist_source_range |
104 | + annotations["nginx.ingress.kubernetes.io/whitelist-source-range"] = ingress_whitelist_source_range |
105 | |
106 | if annotations: |
107 | - ingress['annotations'] = annotations |
108 | + ingress["annotations"] = annotations |
109 | |
110 | # Due to https://github.com/canonical/operator/issues/293 we |
111 | # can't use pod.set_spec's k8s_resources argument. |
112 | - resources = pod_spec.get('kubernetesResources', {}) |
113 | - resources['ingressResources'] = [ingress] |
114 | - pod_spec['kubernetesResources'] = resources |
115 | + resources = pod_spec.get("kubernetesResources", {}) |
116 | + resources["ingressResources"] = [ingress] |
117 | + pod_spec["kubernetesResources"] = resources |
118 | |
119 | def _make_pod_spec(self) -> None: |
120 | """Create a pod spec with some core configuration.""" |
121 | |
122 | config = self.model.config |
123 | - container_port = self.bot_config.getint('httpd', 'listen-port') |
124 | + container_port = self.bot_config.getint("httpd", "listen-port") |
125 | # TODO: The bot replies 501 on HTTP GET so until we have something to probe readiness, magic-uuid is not needed |
126 | # here |
127 | # magic_uuid = self.bot_config.get('httpd', 'magic-uuid') |
128 | image_details = { |
129 | - 'imagePath': config['image_path'], |
130 | + "imagePath": config["image_path"], |
131 | } |
132 | - if config.get('image_username', None): |
133 | - image_details.update({'username': config['image_username'], 'password': config['image_password']}) |
134 | + if config.get("image_username", None): |
135 | + image_details.update({"username": config["image_username"], "password": config["image_password"]}) |
136 | pod_config = self._make_pod_config() |
137 | |
138 | return { |
139 | - 'version': 3, # otherwise resources are ignored |
140 | - 'containers': [ |
141 | + "version": 3, # otherwise resources are ignored |
142 | + "containers": [ |
143 | { |
144 | - 'name': self.app.name, |
145 | - 'imageDetails': image_details, |
146 | + "name": self.app.name, |
147 | + "imageDetails": image_details, |
148 | # TODO: debatable. The idea is that if you want to force an update with the same image name, you |
149 | # don't need to empty kubelet cache on each node to have the right version. |
150 | # This implies a performance drop upon start. |
151 | - 'imagePullPolicy': 'Always', |
152 | - 'ports': [{'containerPort': container_port, 'protocol': 'TCP'}], |
153 | - 'envConfig': pod_config, |
154 | + "imagePullPolicy": "Always", |
155 | + "ports": [{"containerPort": container_port, "protocol": "TCP"}], |
156 | + "envConfig": pod_config, |
157 | # TODO: Add readiness probe in the bot. |
158 | # 'kubernetes': { |
159 | # 'readinessProbe': {'httpGet': {'path': '/{0}/'.format(magic_uuid), 'port': container_port}}, |
160 | @@ -261,13 +261,13 @@ class MmPdBotK8sCharm(CharmBase): |
161 | self.unit.status = BlockedStatus(str(exc)) |
162 | return |
163 | |
164 | - logger.info('Assembling pod spec') |
165 | + logger.info("Assembling pod spec") |
166 | pod_spec = self._make_pod_spec() |
167 | self._update_pod_spec_for_k8s_ingress(pod_spec) |
168 | - logger.info('Setting pod spec') |
169 | + logger.info("Setting pod spec") |
170 | self.model.pod.set_spec(pod_spec) |
171 | self.unit.status = ActiveStatus() |
172 | |
173 | |
174 | -if __name__ == '__main__': # pragma: no cover |
175 | +if __name__ == "__main__": # pragma: no cover |
176 | main(MmPdBotK8sCharm, use_juju_for_storage=True) |
177 | diff --git a/tests/unit/scenario.py b/tests/unit/scenario.py |
178 | index 9c62641..4aa55b5 100644 |
179 | --- a/tests/unit/scenario.py |
180 | +++ b/tests/unit/scenario.py |
181 | @@ -12,16 +12,16 @@ import yaml |
182 | logger = logging.getLogger(__name__) |
183 | |
184 | BOT_CFG_FILES = { |
185 | - 'both_authentication_method': 'both_authentication_method.cfg', |
186 | - 'good_configuration': 'good_bot.cfg', |
187 | - 'missing_options': 'missing_options.cfg', |
188 | - 'missing_sections': 'missing_sections.cfg', |
189 | - 'no_valid_authentication': 'no_valid_authentication.cfg', |
190 | - 'ssl_configuration': 'ssl_bot.cfg', |
191 | + "both_authentication_method": "both_authentication_method.cfg", |
192 | + "good_configuration": "good_bot.cfg", |
193 | + "missing_options": "missing_options.cfg", |
194 | + "missing_sections": "missing_sections.cfg", |
195 | + "no_valid_authentication": "no_valid_authentication.cfg", |
196 | + "ssl_configuration": "ssl_bot.cfg", |
197 | } |
198 | |
199 | |
200 | -def get_cfg_content(configuration='good_configuration') -> str: |
201 | +def get_cfg_content(configuration="good_configuration") -> str: |
202 | """Get the content of the file associated with configuration. |
203 | |
204 | :param str configuration: Key of the BOT_CFG_FILES dictionary to get the content of the associated configuration |
205 | @@ -32,7 +32,7 @@ def get_cfg_content(configuration='good_configuration') -> str: |
206 | files_dir = "files" |
207 | try: |
208 | path = Path(dir_path, files_dir, BOT_CFG_FILES[configuration]) |
209 | - with open(path, 'r') as cfg: |
210 | + with open(path, "r") as cfg: |
211 | return cfg.read() |
212 | except KeyError: |
213 | logger.error("No configuration files associated with '%s'", configuration) |
214 | @@ -43,12 +43,12 @@ def get_juju_settings_default_value() -> list: |
215 | """Return the list of juju settings as defined in config.yaml.""" |
216 | |
217 | dir_path = os.path.dirname(os.path.realpath(__file__)) |
218 | - config_yaml = Path(dir_path, '..', '..', 'config.yaml') |
219 | - with open(config_yaml, 'r') as config: |
220 | + config_yaml = Path(dir_path, "..", "..", "config.yaml") |
221 | + with open(config_yaml, "r") as config: |
222 | loaded_config = yaml.safe_load(config.read()) |
223 | |
224 | # Load the dict with the default values |
225 | - default_values = {config: value['default'] for (config, value) in loaded_config['options'].items()} |
226 | + default_values = {config: value["default"] for (config, value) in loaded_config["options"].items()} |
227 | |
228 | return default_values |
229 | |
230 | @@ -57,52 +57,52 @@ def get_juju_settings_default_value() -> list: |
231 | JUJU_SETTINGS_DEFAULT = get_juju_settings_default_value() |
232 | |
233 | TEST_JUJU_SETTINGS = { |
234 | - 'empty_image_path': { |
235 | - 'config': {'mm_pd_bot_cfg': 'dummy'}, |
236 | - 'logger': ["ERROR:root:Required setting empty: image_path"], |
237 | - 'expected': 'Required setting(s) empty: image_path', |
238 | + "empty_image_path": { |
239 | + "config": {"mm_pd_bot_cfg": "dummy"}, |
240 | + "logger": ["ERROR:root:Required setting empty: image_path"], |
241 | + "expected": "Required setting(s) empty: image_path", |
242 | }, |
243 | - 'empty_mm_pd_bot_cfg': { |
244 | - 'config': {'image_path': 'mm_pd_bot:devel'}, |
245 | - 'logger': ["ERROR:root:Required setting empty: mm_pd_bot_cfg"], |
246 | - 'expected': 'Required setting(s) empty: mm_pd_bot_cfg', |
247 | + "empty_mm_pd_bot_cfg": { |
248 | + "config": {"image_path": "mm_pd_bot:devel"}, |
249 | + "logger": ["ERROR:root:Required setting empty: mm_pd_bot_cfg"], |
250 | + "expected": "Required setting(s) empty: mm_pd_bot_cfg", |
251 | }, |
252 | - 'empty_all_settings': { |
253 | - 'config': {}, |
254 | - 'logger': ["ERROR:root:Required setting empty: image_path", "ERROR:root:Required setting empty: mm_pd_bot_cfg"], |
255 | - 'expected': 'Required setting(s) empty: image_path, mm_pd_bot_cfg', |
256 | + "empty_all_settings": { |
257 | + "config": {}, |
258 | + "logger": ["ERROR:root:Required setting empty: image_path", "ERROR:root:Required setting empty: mm_pd_bot_cfg"], |
259 | + "expected": "Required setting(s) empty: image_path, mm_pd_bot_cfg", |
260 | }, |
261 | } |
262 | |
263 | |
264 | VALIDATE_MM_PD_BOT_CFG = { |
265 | - 'good_configuration': { |
266 | - 'config': {'image_path': 'mm_pd_bot:devel', 'mm_pd_bot_cfg': get_cfg_content("good_configuration")}, |
267 | - 'expected': True, |
268 | - 'logger': [], |
269 | + "good_configuration": { |
270 | + "config": {"image_path": "mm_pd_bot:devel", "mm_pd_bot_cfg": get_cfg_content("good_configuration")}, |
271 | + "expected": True, |
272 | + "logger": [], |
273 | }, |
274 | - 'bad_formatted_configuration': { |
275 | - 'config': {'image_path': 'mm_pd_bot:devel', 'mm_pd_bot_cfg': "[PagerDuty"}, |
276 | - 'expected': "Error while parsing mm_pd_bot_cfg setting", |
277 | - 'logger': ["ERROR:root:Error while parsing mm_pd_bot_cfg setting"], |
278 | + "bad_formatted_configuration": { |
279 | + "config": {"image_path": "mm_pd_bot:devel", "mm_pd_bot_cfg": "[PagerDuty"}, |
280 | + "expected": "Error while parsing mm_pd_bot_cfg setting", |
281 | + "logger": ["ERROR:root:Error while parsing mm_pd_bot_cfg setting"], |
282 | }, |
283 | - 'missing_sections': { |
284 | - 'config': {'image_path': 'mm_pd_bot:devel', 'mm_pd_bot_cfg': get_cfg_content('missing_sections')}, |
285 | - 'expected': "Required section(s) missing in bot configuration file: " |
286 | + "missing_sections": { |
287 | + "config": {"image_path": "mm_pd_bot:devel", "mm_pd_bot_cfg": get_cfg_content("missing_sections")}, |
288 | + "expected": "Required section(s) missing in bot configuration file: " |
289 | "MattermostBot, Prometheus, httpd, nickname to email", |
290 | - 'logger': [ |
291 | + "logger": [ |
292 | "ERROR:root:required section missing in bot configuration file: httpd", |
293 | "ERROR:root:required section missing in bot configuration file: MattermostBot", |
294 | "ERROR:root:required section missing in bot configuration file: Prometheus", |
295 | "ERROR:root:required section missing in bot configuration file: nickname to email", |
296 | ], |
297 | }, |
298 | - 'missing_options': { |
299 | - 'config': {'image_path': 'mm_pd_bot:devel', 'mm_pd_bot_cfg': get_cfg_content('missing_options')}, |
300 | - 'expected': "Required option(s) missing in section MattermostBot: bot_team, bot_url, " |
301 | + "missing_options": { |
302 | + "config": {"image_path": "mm_pd_bot:devel", "mm_pd_bot_cfg": get_cfg_content("missing_options")}, |
303 | + "expected": "Required option(s) missing in section MattermostBot: bot_team, bot_url, " |
304 | "Required option(s) missing in section PagerDuty: api-token, " |
305 | "Required option(s) missing in section httpd: hostname, listen-ip, listen-port, magic-uuid", |
306 | - 'logger': [ |
307 | + "logger": [ |
308 | "ERROR:root:required option api-token missing in section PagerDuty", |
309 | "ERROR:root:required option bot_team missing in section MattermostBot", |
310 | "ERROR:root:required option bot_url missing in section MattermostBot", |
311 | @@ -112,52 +112,52 @@ VALIDATE_MM_PD_BOT_CFG = { |
312 | "ERROR:root:required option magic-uuid missing in section httpd", |
313 | ], |
314 | }, |
315 | - 'no_valid_authentication': { |
316 | - 'config': {'mm_pd_bot_cfg': get_cfg_content('no_valid_authentication')}, |
317 | - 'expected': "bot_token or bot_login/bot_password in MattermostBot section required", |
318 | - 'logger': ["ERROR:root:bot_token or bot_login/bot_password in MattermostBot section required"], |
319 | + "no_valid_authentication": { |
320 | + "config": {"mm_pd_bot_cfg": get_cfg_content("no_valid_authentication")}, |
321 | + "expected": "bot_token or bot_login/bot_password in MattermostBot section required", |
322 | + "logger": ["ERROR:root:bot_token or bot_login/bot_password in MattermostBot section required"], |
323 | }, |
324 | - 'both_authentication_method': { |
325 | - 'config': {'mm_pd_bot_cfg': get_cfg_content('both_authentication_method')}, |
326 | - 'expected': "bot_token and bot_login are both set. Pick one of them", |
327 | - 'logger': ["ERROR:root:bot_token and bot_login are both set. Pick one of them"], |
328 | + "both_authentication_method": { |
329 | + "config": {"mm_pd_bot_cfg": get_cfg_content("both_authentication_method")}, |
330 | + "expected": "bot_token and bot_login are both set. Pick one of them", |
331 | + "logger": ["ERROR:root:bot_token and bot_login are both set. Pick one of them"], |
332 | }, |
333 | } |
334 | |
335 | VALIDATE_POD_SPEC = { |
336 | - 'basic': { |
337 | - 'config': {'image_path': 'mm_pd_bot:devel', 'mm_pd_bot_cfg': get_cfg_content('good_configuration')}, |
338 | - 'pod_spec': { |
339 | - 'version': 3, # otherwise resources are ignored |
340 | - 'containers': [ |
341 | + "basic": { |
342 | + "config": {"image_path": "mm_pd_bot:devel", "mm_pd_bot_cfg": get_cfg_content("good_configuration")}, |
343 | + "pod_spec": { |
344 | + "version": 3, # otherwise resources are ignored |
345 | + "containers": [ |
346 | { |
347 | - 'name': 'mm-pd-bot', |
348 | - 'imageDetails': { |
349 | - 'imagePath': 'mm_pd_bot:devel', |
350 | + "name": "mm-pd-bot", |
351 | + "imageDetails": { |
352 | + "imagePath": "mm_pd_bot:devel", |
353 | }, |
354 | - 'imagePullPolicy': 'Always', |
355 | - 'ports': [{'containerPort': 2160, 'protocol': 'TCP'}], |
356 | - 'envConfig': {'MM_PD_BOT_CFG': get_cfg_content('good_configuration')}, |
357 | + "imagePullPolicy": "Always", |
358 | + "ports": [{"containerPort": 2160, "protocol": "TCP"}], |
359 | + "envConfig": {"MM_PD_BOT_CFG": get_cfg_content("good_configuration")}, |
360 | } |
361 | ], |
362 | }, |
363 | }, |
364 | - 'private_registry': { |
365 | - 'config': { |
366 | - 'image_path': 'mm_pd_bot:devel', |
367 | - 'image_username': 'rockity', |
368 | - 'image_password': 'rock', |
369 | - 'mm_pd_bot_cfg': get_cfg_content('good_configuration'), |
370 | + "private_registry": { |
371 | + "config": { |
372 | + "image_path": "mm_pd_bot:devel", |
373 | + "image_username": "rockity", |
374 | + "image_password": "rock", |
375 | + "mm_pd_bot_cfg": get_cfg_content("good_configuration"), |
376 | }, |
377 | - 'pod_spec': { |
378 | - 'version': 3, # otherwise resources are ignored |
379 | - 'containers': [ |
380 | + "pod_spec": { |
381 | + "version": 3, # otherwise resources are ignored |
382 | + "containers": [ |
383 | { |
384 | - 'name': 'mm-pd-bot', |
385 | - 'imageDetails': {'imagePath': 'mm_pd_bot:devel', 'username': 'rockity', 'password': 'rock'}, |
386 | - 'imagePullPolicy': 'Always', |
387 | - 'ports': [{'containerPort': 2160, 'protocol': 'TCP'}], |
388 | - 'envConfig': {'MM_PD_BOT_CFG': get_cfg_content('good_configuration')}, |
389 | + "name": "mm-pd-bot", |
390 | + "imageDetails": {"imagePath": "mm_pd_bot:devel", "username": "rockity", "password": "rock"}, |
391 | + "imagePullPolicy": "Always", |
392 | + "ports": [{"containerPort": 2160, "protocol": "TCP"}], |
393 | + "envConfig": {"MM_PD_BOT_CFG": get_cfg_content("good_configuration")}, |
394 | } |
395 | ], |
396 | }, |
397 | @@ -166,124 +166,124 @@ VALIDATE_POD_SPEC = { |
398 | |
399 | |
400 | VALIDATE_POD_SPEC_AND_INGRESS = { |
401 | - 'basic': { |
402 | - 'config': {'image_path': 'mm_pd_bot:devel', 'mm_pd_bot_cfg': get_cfg_content('good_configuration')}, |
403 | - 'pod_spec': { |
404 | - 'version': 3, # otherwise resources are ignored |
405 | - 'containers': [ |
406 | + "basic": { |
407 | + "config": {"image_path": "mm_pd_bot:devel", "mm_pd_bot_cfg": get_cfg_content("good_configuration")}, |
408 | + "pod_spec": { |
409 | + "version": 3, # otherwise resources are ignored |
410 | + "containers": [ |
411 | { |
412 | - 'name': 'mm-pd-bot', |
413 | - 'imageDetails': {'imagePath': 'mm_pd_bot:devel'}, |
414 | - 'imagePullPolicy': 'Always', |
415 | - 'ports': [{'containerPort': 2160, 'protocol': 'TCP'}], |
416 | - 'envConfig': {'MM_PD_BOT_CFG': get_cfg_content('good_configuration')}, |
417 | + "name": "mm-pd-bot", |
418 | + "imageDetails": {"imagePath": "mm_pd_bot:devel"}, |
419 | + "imagePullPolicy": "Always", |
420 | + "ports": [{"containerPort": 2160, "protocol": "TCP"}], |
421 | + "envConfig": {"MM_PD_BOT_CFG": get_cfg_content("good_configuration")}, |
422 | } |
423 | ], |
424 | - 'kubernetesResources': { |
425 | - 'ingressResources': [ |
426 | + "kubernetesResources": { |
427 | + "ingressResources": [ |
428 | { |
429 | - 'name': 'mm-pd-bot-ingress', |
430 | - 'spec': { |
431 | - 'rules': [ |
432 | + "name": "mm-pd-bot-ingress", |
433 | + "spec": { |
434 | + "rules": [ |
435 | { |
436 | - 'host': 'mm-pd-bot.example.com', |
437 | - 'http': { |
438 | - 'paths': [ |
439 | + "host": "mm-pd-bot.example.com", |
440 | + "http": { |
441 | + "paths": [ |
442 | { |
443 | - 'path': '/bdddcacb-ab42-40ac-9106-4275c1db1519/', |
444 | - 'backend': {'serviceName': 'mm-pd-bot', 'servicePort': 2160}, |
445 | + "path": "/bdddcacb-ab42-40ac-9106-4275c1db1519/", |
446 | + "backend": {"serviceName": "mm-pd-bot", "servicePort": 2160}, |
447 | }, |
448 | ], |
449 | }, |
450 | }, |
451 | ], |
452 | }, |
453 | - 'annotations': {'nginx.ingress.kubernetes.io/ssl-redirect': 'false'}, |
454 | + "annotations": {"nginx.ingress.kubernetes.io/ssl-redirect": "false"}, |
455 | }, |
456 | ], |
457 | }, |
458 | }, |
459 | }, |
460 | - 'ssl': { |
461 | - 'config': { |
462 | - 'image_path': 'mm_pd_bot:devel', |
463 | - 'mm_pd_bot_cfg': get_cfg_content('ssl_configuration'), |
464 | - 'ingress_whitelist_source_range': '10.0.69.0/24', |
465 | - 'tls_secret_name': 'mm_pd_bot_secret', |
466 | + "ssl": { |
467 | + "config": { |
468 | + "image_path": "mm_pd_bot:devel", |
469 | + "mm_pd_bot_cfg": get_cfg_content("ssl_configuration"), |
470 | + "ingress_whitelist_source_range": "10.0.69.0/24", |
471 | + "tls_secret_name": "mm_pd_bot_secret", |
472 | }, |
473 | - 'pod_spec': { |
474 | - 'version': 3, # otherwise resources are ignored |
475 | - 'containers': [ |
476 | + "pod_spec": { |
477 | + "version": 3, # otherwise resources are ignored |
478 | + "containers": [ |
479 | { |
480 | - 'name': 'mm-pd-bot', |
481 | - 'imageDetails': {'imagePath': 'mm_pd_bot:devel'}, |
482 | - 'imagePullPolicy': 'Always', |
483 | - 'ports': [{'containerPort': 2160, 'protocol': 'TCP'}], |
484 | - 'envConfig': {'MM_PD_BOT_CFG': get_cfg_content('ssl_configuration')}, |
485 | + "name": "mm-pd-bot", |
486 | + "imageDetails": {"imagePath": "mm_pd_bot:devel"}, |
487 | + "imagePullPolicy": "Always", |
488 | + "ports": [{"containerPort": 2160, "protocol": "TCP"}], |
489 | + "envConfig": {"MM_PD_BOT_CFG": get_cfg_content("ssl_configuration")}, |
490 | } |
491 | ], |
492 | - 'kubernetesResources': { |
493 | - 'ingressResources': [ |
494 | + "kubernetesResources": { |
495 | + "ingressResources": [ |
496 | { |
497 | - 'name': 'mm-pd-bot-ingress', |
498 | - 'spec': { |
499 | - 'rules': [ |
500 | + "name": "mm-pd-bot-ingress", |
501 | + "spec": { |
502 | + "rules": [ |
503 | { |
504 | - 'host': 'mm-pd-bot.example.com', |
505 | - 'http': { |
506 | - 'paths': [ |
507 | + "host": "mm-pd-bot.example.com", |
508 | + "http": { |
509 | + "paths": [ |
510 | { |
511 | - 'path': '/bdddcacb-ab42-40ac-9106-4275c1db1519/', |
512 | - 'backend': {'serviceName': 'mm-pd-bot', 'servicePort': 2160}, |
513 | + "path": "/bdddcacb-ab42-40ac-9106-4275c1db1519/", |
514 | + "backend": {"serviceName": "mm-pd-bot", "servicePort": 2160}, |
515 | }, |
516 | ], |
517 | }, |
518 | }, |
519 | ], |
520 | - 'tls': [{'hosts': ['mm-pd-bot.example.com'], 'secretName': 'mm_pd_bot_secret'}], |
521 | + "tls": [{"hosts": ["mm-pd-bot.example.com"], "secretName": "mm_pd_bot_secret"}], |
522 | }, |
523 | - 'annotations': {'nginx.ingress.kubernetes.io/whitelist-source-range': '10.0.69.0/24'}, |
524 | + "annotations": {"nginx.ingress.kubernetes.io/whitelist-source-range": "10.0.69.0/24"}, |
525 | }, |
526 | ], |
527 | }, |
528 | }, |
529 | }, |
530 | - 'ssl_without_whitelist': { |
531 | - 'config': { |
532 | - 'image_path': 'mm_pd_bot:devel', |
533 | - 'mm_pd_bot_cfg': get_cfg_content('ssl_configuration'), |
534 | - 'tls_secret_name': 'mm_pd_bot_secret', |
535 | + "ssl_without_whitelist": { |
536 | + "config": { |
537 | + "image_path": "mm_pd_bot:devel", |
538 | + "mm_pd_bot_cfg": get_cfg_content("ssl_configuration"), |
539 | + "tls_secret_name": "mm_pd_bot_secret", |
540 | }, |
541 | - 'pod_spec': { |
542 | - 'version': 3, # otherwise resources are ignored |
543 | - 'containers': [ |
544 | + "pod_spec": { |
545 | + "version": 3, # otherwise resources are ignored |
546 | + "containers": [ |
547 | { |
548 | - 'name': 'mm-pd-bot', |
549 | - 'imageDetails': {'imagePath': 'mm_pd_bot:devel'}, |
550 | - 'imagePullPolicy': 'Always', |
551 | - 'ports': [{'containerPort': 2160, 'protocol': 'TCP'}], |
552 | - 'envConfig': {'MM_PD_BOT_CFG': get_cfg_content('ssl_configuration')}, |
553 | + "name": "mm-pd-bot", |
554 | + "imageDetails": {"imagePath": "mm_pd_bot:devel"}, |
555 | + "imagePullPolicy": "Always", |
556 | + "ports": [{"containerPort": 2160, "protocol": "TCP"}], |
557 | + "envConfig": {"MM_PD_BOT_CFG": get_cfg_content("ssl_configuration")}, |
558 | } |
559 | ], |
560 | - 'kubernetesResources': { |
561 | - 'ingressResources': [ |
562 | + "kubernetesResources": { |
563 | + "ingressResources": [ |
564 | { |
565 | - 'name': 'mm-pd-bot-ingress', |
566 | - 'spec': { |
567 | - 'rules': [ |
568 | + "name": "mm-pd-bot-ingress", |
569 | + "spec": { |
570 | + "rules": [ |
571 | { |
572 | - 'host': 'mm-pd-bot.example.com', |
573 | - 'http': { |
574 | - 'paths': [ |
575 | + "host": "mm-pd-bot.example.com", |
576 | + "http": { |
577 | + "paths": [ |
578 | { |
579 | - 'path': '/bdddcacb-ab42-40ac-9106-4275c1db1519/', |
580 | - 'backend': {'serviceName': 'mm-pd-bot', 'servicePort': 2160}, |
581 | + "path": "/bdddcacb-ab42-40ac-9106-4275c1db1519/", |
582 | + "backend": {"serviceName": "mm-pd-bot", "servicePort": 2160}, |
583 | }, |
584 | ], |
585 | }, |
586 | }, |
587 | ], |
588 | - 'tls': [{'hosts': ['mm-pd-bot.example.com'], 'secretName': 'mm_pd_bot_secret'}], |
589 | + "tls": [{"hosts": ["mm-pd-bot.example.com"], "secretName": "mm_pd_bot_secret"}], |
590 | }, |
591 | }, |
592 | ], |
593 | diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py |
594 | index 27bbaf3..d56fcde 100755 |
595 | --- a/tests/unit/test_charm.py |
596 | +++ b/tests/unit/test_charm.py |
597 | @@ -39,8 +39,8 @@ class TestMmPdBotK8sCharmBlockedStatus(unittest.TestCase): |
598 | """Cleanup the harness.""" |
599 | self.harness.cleanup() |
600 | |
601 | - @patch('charm.MmPdBotK8sCharm._validate_mm_pd_bot_configuration') |
602 | - @patch('charm.MmPdBotK8sCharm._check_juju_settings') |
603 | + @patch("charm.MmPdBotK8sCharm._validate_mm_pd_bot_configuration") |
604 | + @patch("charm.MmPdBotK8sCharm._check_juju_settings") |
605 | def test_check_for_config_problems(self, mock_juju, mock_mm_pd_bot): |
606 | """Check the calls for config problems.""" |
607 | self.harness.charm._check_for_config_problems() |
608 | @@ -51,47 +51,47 @@ class TestMmPdBotK8sCharmBlockedStatus(unittest.TestCase): |
609 | """Check the required juju settings.""" |
610 | for scenario, values in TEST_JUJU_SETTINGS.items(): |
611 | with self.subTest(scenario=scenario): |
612 | - with self.assertLogs(level='ERROR') as logger: |
613 | + with self.assertLogs(level="ERROR") as logger: |
614 | with self.assertRaises(MmPdBotK8sCharmConfigError) as exc: |
615 | self.harness.update_config(JUJU_SETTINGS_DEFAULT) # Load the default values |
616 | - self.harness.update_config(values['config']) |
617 | + self.harness.update_config(values["config"]) |
618 | self.harness.charm._check_juju_settings() |
619 | - self.assertEqual(sorted(logger.output), sorted(values['logger'])) |
620 | - self.assertEqual(str(exc.exception), values['expected']) |
621 | + self.assertEqual(sorted(logger.output), sorted(values["logger"])) |
622 | + self.assertEqual(str(exc.exception), values["expected"]) |
623 | self.harness.update_config(JUJU_SETTINGS_DEFAULT) # You need to clean the config after each run |
624 | |
625 | def test_validate_mm_pd_bot_configuration(self): |
626 | """Check the MM_PD_BOT_CFG string is a valid INI.""" |
627 | for scenario, values in VALIDATE_MM_PD_BOT_CFG.items(): |
628 | with self.subTest(scenario=scenario): |
629 | - self.harness.update_config(values['config']) |
630 | - if values['expected'] is True: |
631 | + self.harness.update_config(values["config"]) |
632 | + if values["expected"] is True: |
633 | self.harness.charm._validate_mm_pd_bot_configuration() |
634 | else: |
635 | - with self.assertLogs(level='ERROR') as logger: |
636 | + with self.assertLogs(level="ERROR") as logger: |
637 | with self.assertRaises(MmPdBotK8sCharmConfigError) as exc: |
638 | self.harness.charm._validate_mm_pd_bot_configuration() |
639 | - self.assertEqual(str(exc.exception), values['expected']) |
640 | - self.assertEqual(sorted(logger.output), sorted(values['logger'])) |
641 | + self.assertEqual(str(exc.exception), values["expected"]) |
642 | + self.assertEqual(sorted(logger.output), sorted(values["logger"])) |
643 | self.harness.update_config(JUJU_SETTINGS_DEFAULT) # You need to clean the config after each run |
644 | |
645 | def test_load_mm_pd_bot_configuration(self): |
646 | """Test the loading of the configuration for the bot.""" |
647 | - config = VALIDATE_MM_PD_BOT_CFG['good_configuration']['config']['mm_pd_bot_cfg'] |
648 | + config = VALIDATE_MM_PD_BOT_CFG["good_configuration"]["config"]["mm_pd_bot_cfg"] |
649 | loaded_config = self.harness.charm._load_mm_pd_bot_configuration(config) |
650 | self.assertIsInstance(loaded_config, configparser.ConfigParser) |
651 | |
652 | - config = VALIDATE_MM_PD_BOT_CFG['bad_formatted_configuration']['config']['mm_pd_bot_cfg'] |
653 | + config = VALIDATE_MM_PD_BOT_CFG["bad_formatted_configuration"]["config"]["mm_pd_bot_cfg"] |
654 | with self.assertRaises(MmPdBotK8sCharmConfigError) as exc: |
655 | loaded_config = self.harness.charm._load_mm_pd_bot_configuration(config) |
656 | - self.assertEqual(str(exc.exception), VALIDATE_MM_PD_BOT_CFG['bad_formatted_configuration']['expected']) |
657 | + self.assertEqual(str(exc.exception), VALIDATE_MM_PD_BOT_CFG["bad_formatted_configuration"]["expected"]) |
658 | |
659 | def test_configure_pod(self): |
660 | """Test the pod configuration.""" |
661 | mock_event = MagicMock() |
662 | |
663 | # Good configuration but not leader |
664 | - self.harness.update_config(VALIDATE_MM_PD_BOT_CFG['good_configuration']['config']) |
665 | + self.harness.update_config(VALIDATE_MM_PD_BOT_CFG["good_configuration"]["config"]) |
666 | self.harness.set_leader(False) |
667 | self.harness.charm.unit.status = BlockedStatus("Testing") |
668 | self.harness.charm.configure_pod(mock_event) |
669 | @@ -99,11 +99,11 @@ class TestMmPdBotK8sCharmBlockedStatus(unittest.TestCase): |
670 | self.harness.update_config(JUJU_SETTINGS_DEFAULT) # You need to clean the config after each run |
671 | |
672 | # Good configuration and leader |
673 | - self.harness.update_config(VALIDATE_MM_PD_BOT_CFG['good_configuration']['config']) |
674 | + self.harness.update_config(VALIDATE_MM_PD_BOT_CFG["good_configuration"]["config"]) |
675 | self.harness.set_leader(True) |
676 | self.harness.charm.unit.status = BlockedStatus("Testing") |
677 | self.harness.charm.configure_pod(mock_event) |
678 | - with self.assertLogs(level='INFO') as logger: |
679 | + with self.assertLogs(level="INFO") as logger: |
680 | self.harness.charm.configure_pod(mock_event) |
681 | self.assertEqual( |
682 | sorted(logger.output), |
683 | @@ -113,8 +113,8 @@ class TestMmPdBotK8sCharmBlockedStatus(unittest.TestCase): |
684 | self.harness.update_config(JUJU_SETTINGS_DEFAULT) # You need to clean the config after each run |
685 | |
686 | # Bad configuration and leader |
687 | - config = VALIDATE_MM_PD_BOT_CFG['bad_formatted_configuration']['config'] |
688 | - expected = VALIDATE_MM_PD_BOT_CFG['bad_formatted_configuration']['expected'] |
689 | + config = VALIDATE_MM_PD_BOT_CFG["bad_formatted_configuration"]["config"] |
690 | + expected = VALIDATE_MM_PD_BOT_CFG["bad_formatted_configuration"]["expected"] |
691 | self.harness.update_config(config) |
692 | self.harness.set_leader(True) |
693 | self.harness.charm.configure_pod(mock_event) |
694 | @@ -125,26 +125,26 @@ class TestMmPdBotK8sCharmBlockedStatus(unittest.TestCase): |
695 | """Check the crafting of the pod spec.""" |
696 | for scenario, values in VALIDATE_POD_SPEC.items(): |
697 | with self.subTest(scenario=scenario): |
698 | - self.harness.update_config(values['config']) |
699 | + self.harness.update_config(values["config"]) |
700 | self.harness.charm.bot_config = self.harness.charm._load_mm_pd_bot_configuration( |
701 | - values['config']['mm_pd_bot_cfg'] |
702 | + values["config"]["mm_pd_bot_cfg"] |
703 | ) |
704 | - self.assertEqual(self.harness.charm._make_pod_spec(), values['pod_spec']) |
705 | + self.assertEqual(self.harness.charm._make_pod_spec(), values["pod_spec"]) |
706 | self.harness.update_config(JUJU_SETTINGS_DEFAULT) # You need to clean the config after each run |
707 | |
708 | def test_update_pod_spec_for_k8s_ingress(self): |
709 | """Check the crafting of the ingress part of the pod spec.""" |
710 | for scenario, values in VALIDATE_POD_SPEC_AND_INGRESS.items(): |
711 | with self.subTest(scenario=scenario): |
712 | - self.harness.update_config(values['config']) |
713 | + self.harness.update_config(values["config"]) |
714 | self.harness.charm.bot_config = self.harness.charm._load_mm_pd_bot_configuration( |
715 | - values['config']['mm_pd_bot_cfg'] |
716 | + values["config"]["mm_pd_bot_cfg"] |
717 | ) |
718 | pod_spec = self.harness.charm._make_pod_spec() |
719 | self.harness.charm._update_pod_spec_for_k8s_ingress(pod_spec) |
720 | - self.assertEqual(pod_spec, values['pod_spec']) |
721 | + self.assertEqual(pod_spec, values["pod_spec"]) |
722 | self.harness.update_config(JUJU_SETTINGS_DEFAULT) # You need to clean the config after each run |
723 | |
724 | |
725 | -if __name__ == '__main__': |
726 | +if __name__ == "__main__": |
727 | unittest.main() |
+1