Adding cluster-issuer annotation for TLS provisioning
[osm/devops.git] / installers / charm / mongodb-exporter / tests / test_pod_spec.py
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 from typing import NoReturn
24 import unittest
25
26 import pod_spec
27
28
29 class TestPodSpec(unittest.TestCase):
30 """Pod spec unit tests."""
31
32 def test_make_pod_ports(self) -> NoReturn:
33 """Testing make pod ports."""
34 port = 9216
35
36 expected_result = [
37 {
38 "name": "mongo-exporter",
39 "containerPort": port,
40 "protocol": "TCP",
41 }
42 ]
43
44 pod_ports = pod_spec._make_pod_ports(port)
45
46 self.assertListEqual(expected_result, pod_ports)
47
48 def test_make_pod_envconfig(self) -> NoReturn:
49 """Teting make pod envconfig."""
50 config = {}
51 relation_state = {
52 "mongodb_connection_string": "mongodb://mongo",
53 }
54
55 expected_result = {"MONGODB_URI": "mongodb://mongo"}
56
57 pod_envconfig = pod_spec._make_pod_envconfig(config, relation_state)
58
59 self.assertDictEqual(expected_result, pod_envconfig)
60
61 def test_make_pod_ingress_resources_without_site_url(self) -> NoReturn:
62 """Testing make pod ingress resources without site_url."""
63 config = {
64 "site_url": "",
65 "cluster_issuer": "",
66 }
67 app_name = "mongodb-exporter"
68 port = 9216
69
70 pod_ingress_resources = pod_spec._make_pod_ingress_resources(
71 config, app_name, port
72 )
73
74 self.assertIsNone(pod_ingress_resources)
75
76 def test_make_pod_ingress_resources(self) -> NoReturn:
77 """Testing make pod ingress resources."""
78 config = {
79 "site_url": "http://mongodb-exporter",
80 "cluster_issuer": "",
81 "ingress_whitelist_source_range": "",
82 }
83 app_name = "mongodb-exporter"
84 port = 9216
85
86 expected_result = [
87 {
88 "name": f"{app_name}-ingress",
89 "annotations": {
90 "nginx.ingress.kubernetes.io/ssl-redirect": "false",
91 },
92 "spec": {
93 "rules": [
94 {
95 "host": app_name,
96 "http": {
97 "paths": [
98 {
99 "path": "/",
100 "backend": {
101 "serviceName": app_name,
102 "servicePort": port,
103 },
104 }
105 ]
106 },
107 }
108 ]
109 },
110 }
111 ]
112
113 pod_ingress_resources = pod_spec._make_pod_ingress_resources(
114 config, app_name, port
115 )
116
117 self.assertListEqual(expected_result, pod_ingress_resources)
118
119 def test_make_pod_ingress_resources_with_whitelist_source_range(self) -> NoReturn:
120 """Testing make pod ingress resources with whitelist_source_range."""
121 config = {
122 "site_url": "http://mongodb-exporter",
123 "cluster_issuer": "",
124 "ingress_whitelist_source_range": "0.0.0.0/0",
125 }
126 app_name = "mongodb-exporter"
127 port = 9216
128
129 expected_result = [
130 {
131 "name": f"{app_name}-ingress",
132 "annotations": {
133 "nginx.ingress.kubernetes.io/ssl-redirect": "false",
134 "nginx.ingress.kubernetes.io/whitelist-source-range": config[
135 "ingress_whitelist_source_range"
136 ],
137 },
138 "spec": {
139 "rules": [
140 {
141 "host": app_name,
142 "http": {
143 "paths": [
144 {
145 "path": "/",
146 "backend": {
147 "serviceName": app_name,
148 "servicePort": port,
149 },
150 }
151 ]
152 },
153 }
154 ]
155 },
156 }
157 ]
158
159 pod_ingress_resources = pod_spec._make_pod_ingress_resources(
160 config, app_name, port
161 )
162
163 self.assertListEqual(expected_result, pod_ingress_resources)
164
165 def test_make_pod_ingress_resources_with_https(self) -> NoReturn:
166 """Testing make pod ingress resources with HTTPs."""
167 config = {
168 "site_url": "https://mongodb-exporter",
169 "cluster_issuer": "",
170 "ingress_whitelist_source_range": "",
171 "tls_secret_name": "",
172 }
173 app_name = "mongodb-exporter"
174 port = 9216
175
176 expected_result = [
177 {
178 "name": f"{app_name}-ingress",
179 "annotations": {},
180 "spec": {
181 "rules": [
182 {
183 "host": app_name,
184 "http": {
185 "paths": [
186 {
187 "path": "/",
188 "backend": {
189 "serviceName": app_name,
190 "servicePort": port,
191 },
192 }
193 ]
194 },
195 }
196 ],
197 "tls": [{"hosts": [app_name]}],
198 },
199 }
200 ]
201
202 pod_ingress_resources = pod_spec._make_pod_ingress_resources(
203 config, app_name, port
204 )
205
206 self.assertListEqual(expected_result, pod_ingress_resources)
207
208 def test_make_pod_ingress_resources_with_https_tls_secret_name(self) -> NoReturn:
209 """Testing make pod ingress resources with HTTPs and TLS secret name."""
210 config = {
211 "site_url": "https://mongodb-exporter",
212 "cluster_issuer": "",
213 "ingress_whitelist_source_range": "",
214 "tls_secret_name": "secret_name",
215 }
216 app_name = "mongodb-exporter"
217 port = 9216
218
219 expected_result = [
220 {
221 "name": f"{app_name}-ingress",
222 "annotations": {},
223 "spec": {
224 "rules": [
225 {
226 "host": app_name,
227 "http": {
228 "paths": [
229 {
230 "path": "/",
231 "backend": {
232 "serviceName": app_name,
233 "servicePort": port,
234 },
235 }
236 ]
237 },
238 }
239 ],
240 "tls": [
241 {"hosts": [app_name], "secretName": config["tls_secret_name"]}
242 ],
243 },
244 }
245 ]
246
247 pod_ingress_resources = pod_spec._make_pod_ingress_resources(
248 config, app_name, port
249 )
250
251 self.assertListEqual(expected_result, pod_ingress_resources)
252
253 def test_make_readiness_probe(self) -> NoReturn:
254 """Testing make readiness probe."""
255 port = 9216
256
257 expected_result = {
258 "httpGet": {
259 "path": "/api/health",
260 "port": port,
261 },
262 "initialDelaySeconds": 10,
263 "periodSeconds": 10,
264 "timeoutSeconds": 5,
265 "successThreshold": 1,
266 "failureThreshold": 3,
267 }
268
269 readiness_probe = pod_spec._make_readiness_probe(port)
270
271 self.assertDictEqual(expected_result, readiness_probe)
272
273 def test_make_liveness_probe(self) -> NoReturn:
274 """Testing make liveness probe."""
275 port = 9216
276
277 expected_result = {
278 "httpGet": {
279 "path": "/api/health",
280 "port": port,
281 },
282 "initialDelaySeconds": 60,
283 "timeoutSeconds": 30,
284 "failureThreshold": 10,
285 }
286
287 liveness_probe = pod_spec._make_liveness_probe(port)
288
289 self.assertDictEqual(expected_result, liveness_probe)
290
291 def test_make_pod_spec(self) -> NoReturn:
292 """Testing make pod spec."""
293 image_info = {"upstream-source": "bitnami/mongodb-exporter:latest"}
294 config = {
295 "site_url": "",
296 "cluster_issuer": "",
297 }
298 relation_state = {
299 "mongodb_connection_string": "mongodb://mongo",
300 }
301 app_name = "mongodb-exporter"
302 port = 9216
303
304 expected_result = {
305 "version": 3,
306 "containers": [
307 {
308 "name": app_name,
309 "imageDetails": image_info,
310 "imagePullPolicy": "Always",
311 "ports": [
312 {
313 "name": "mongo-exporter",
314 "containerPort": port,
315 "protocol": "TCP",
316 }
317 ],
318 "envConfig": {
319 "MONGODB_URI": "mongodb://mongo",
320 },
321 "kubernetes": {
322 "readinessProbe": {
323 "httpGet": {
324 "path": "/api/health",
325 "port": port,
326 },
327 "initialDelaySeconds": 10,
328 "periodSeconds": 10,
329 "timeoutSeconds": 5,
330 "successThreshold": 1,
331 "failureThreshold": 3,
332 },
333 "livenessProbe": {
334 "httpGet": {
335 "path": "/api/health",
336 "port": port,
337 },
338 "initialDelaySeconds": 60,
339 "timeoutSeconds": 30,
340 "failureThreshold": 10,
341 },
342 },
343 }
344 ],
345 "kubernetesResources": {"ingressResources": []},
346 }
347
348 spec = pod_spec.make_pod_spec(
349 image_info, config, relation_state, app_name, port
350 )
351
352 self.assertDictEqual(expected_result, spec)
353
354 def test_make_pod_spec_with_ingress(self) -> NoReturn:
355 """Testing make pod spec."""
356 image_info = {"upstream-source": "bitnami/mongodb-exporter:latest"}
357 config = {
358 "site_url": "https://mongodb-exporter",
359 "cluster_issuer": "",
360 "tls_secret_name": "mongodb-exporter",
361 "ingress_whitelist_source_range": "0.0.0.0/0",
362 }
363 relation_state = {
364 "mongodb_connection_string": "mongodb://mongo",
365 }
366 app_name = "mongodb-exporter"
367 port = 9216
368
369 expected_result = {
370 "version": 3,
371 "containers": [
372 {
373 "name": app_name,
374 "imageDetails": image_info,
375 "imagePullPolicy": "Always",
376 "ports": [
377 {
378 "name": "mongo-exporter",
379 "containerPort": port,
380 "protocol": "TCP",
381 }
382 ],
383 "envConfig": {
384 "MONGODB_URI": "mongodb://mongo",
385 },
386 "kubernetes": {
387 "readinessProbe": {
388 "httpGet": {
389 "path": "/api/health",
390 "port": port,
391 },
392 "initialDelaySeconds": 10,
393 "periodSeconds": 10,
394 "timeoutSeconds": 5,
395 "successThreshold": 1,
396 "failureThreshold": 3,
397 },
398 "livenessProbe": {
399 "httpGet": {
400 "path": "/api/health",
401 "port": port,
402 },
403 "initialDelaySeconds": 60,
404 "timeoutSeconds": 30,
405 "failureThreshold": 10,
406 },
407 },
408 }
409 ],
410 "kubernetesResources": {
411 "ingressResources": [
412 {
413 "name": "{}-ingress".format(app_name),
414 "annotations": {
415 "nginx.ingress.kubernetes.io/whitelist-source-range": config.get(
416 "ingress_whitelist_source_range"
417 ),
418 },
419 "spec": {
420 "rules": [
421 {
422 "host": app_name,
423 "http": {
424 "paths": [
425 {
426 "path": "/",
427 "backend": {
428 "serviceName": app_name,
429 "servicePort": port,
430 },
431 }
432 ]
433 },
434 }
435 ],
436 "tls": [
437 {
438 "hosts": [app_name],
439 "secretName": config.get("tls_secret_name"),
440 }
441 ],
442 },
443 }
444 ],
445 },
446 }
447
448 spec = pod_spec.make_pod_spec(
449 image_info, config, relation_state, app_name, port
450 )
451
452 self.assertDictEqual(expected_result, spec)
453
454 def test_make_pod_spec_without_image_info(self) -> NoReturn:
455 """Testing make pod spec without image_info."""
456 image_info = None
457 config = {
458 "site_url": "",
459 "cluster_issuer": "",
460 }
461 relation_state = {
462 "mongodb_connection_string": "mongodb://mongo",
463 }
464 app_name = "mongodb-exporter"
465 port = 9216
466
467 spec = pod_spec.make_pod_spec(
468 image_info, config, relation_state, app_name, port
469 )
470
471 self.assertIsNone(spec)
472
473 def test_make_pod_spec_without_relation_state(self) -> NoReturn:
474 """Testing make pod spec without relation_state."""
475 image_info = {"upstream-source": "bitnami/mongodb-exporter:latest"}
476 config = {
477 "site_url": "",
478 "cluster_issuer": "",
479 }
480 relation_state = {}
481 app_name = "mongodb-exporter"
482 port = 9216
483
484 with self.assertRaises(ValueError):
485 pod_spec.make_pod_spec(image_info, config, relation_state, app_name, port)
486
487
488 if __name__ == "__main__":
489 unittest.main()