Fix black errors
[osm/N2VC.git] / n2vc / tests / unit / test_k8s_helm3_conn.py
1 ##
2 # Licensed under the Apache License, Version 2.0 (the "License"); you may
3 # not use this file except in compliance with the License. You may obtain
4 # a copy of the License at
5 #
6 # http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 # License for the specific language governing permissions and limitations
12 # under the License.
13 #
14 # For those usages not covered by the Apache License, Version 2.0 please
15 # contact: alfonso.tiernosepulveda@telefonica.com
16 ##
17
18 import asynctest
19 import logging
20
21 from asynctest.mock import Mock, patch
22 from osm_common.dbmemory import DbMemory
23 from osm_common.fslocal import FsLocal
24 from n2vc.k8s_helm3_conn import K8sHelm3Connector, K8sException
25
26 __author__ = "Isabel Lloret <illoret@indra.es>"
27
28
29 class TestK8sHelm3Conn(asynctest.TestCase):
30 logging.basicConfig(level=logging.DEBUG)
31 logger = logging.getLogger(__name__)
32 logger.setLevel(logging.DEBUG)
33
34 @patch("n2vc.k8s_helm_base_conn.EnvironConfig")
35 async def setUp(self, mock_env):
36 mock_env.return_value = {"stablerepourl": "https://charts.helm.sh/stable"}
37 self.db = Mock(DbMemory())
38 self.fs = asynctest.Mock(FsLocal())
39 self.fs.path = "./tmp/"
40 self.namespace = "testk8s"
41 self.cluster_id = "helm3_cluster_id"
42 self.cluster_uuid = self.cluster_id
43 # pass fake kubectl and helm commands to make sure it does not call actual commands
44 K8sHelm3Connector._check_file_exists = asynctest.Mock(return_value=True)
45 cluster_dir = self.fs.path + self.cluster_id
46 self.env = {
47 "HELM_CACHE_HOME": "{}/.cache/helm".format(cluster_dir),
48 "HELM_CONFIG_HOME": "{}/.config/helm".format(cluster_dir),
49 "HELM_DATA_HOME": "{}/.local/share/helm".format(cluster_dir),
50 "KUBECONFIG": "{}/.kube/config".format(cluster_dir),
51 }
52 self.helm_conn = K8sHelm3Connector(self.fs, self.db, log=self.logger)
53 self.logger.debug("Set up executed")
54
55 @asynctest.fail_on(active_handles=True)
56 async def test_init_env(self):
57 k8s_creds = "false_credentials_string"
58 self.helm_conn._get_namespaces = asynctest.CoroutineMock(return_value=[])
59 self.helm_conn._create_namespace = asynctest.CoroutineMock()
60 self.helm_conn.repo_list = asynctest.CoroutineMock(return_value=[])
61 self.helm_conn.repo_add = asynctest.CoroutineMock()
62
63 k8scluster_uuid, installed = await self.helm_conn.init_env(
64 k8s_creds, namespace=self.namespace, reuse_cluster_uuid=self.cluster_id
65 )
66
67 self.assertEqual(
68 k8scluster_uuid,
69 self.cluster_id,
70 "Check cluster_uuid",
71 )
72 self.helm_conn._get_namespaces.assert_called_once_with(self.cluster_id)
73 self.helm_conn._create_namespace.assert_called_once_with(
74 self.cluster_id, self.namespace
75 )
76 self.helm_conn.repo_list.assert_called_once_with(k8scluster_uuid)
77 self.helm_conn.repo_add.assert_called_once_with(
78 k8scluster_uuid, "stable", "https://charts.helm.sh/stable"
79 )
80 self.helm_conn.fs.reverse_sync.assert_called_once_with(
81 from_path=self.cluster_id
82 )
83 self.logger.debug(f"cluster_uuid: {k8scluster_uuid}")
84
85 @asynctest.fail_on(active_handles=True)
86 async def test_repo_add(self):
87 repo_name = "bitnami"
88 repo_url = "https://charts.bitnami.com/bitnami"
89 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=(0, ""))
90
91 await self.helm_conn.repo_add(self.cluster_uuid, repo_name, repo_url)
92
93 self.helm_conn.fs.sync.assert_called_once_with(from_path=self.cluster_id)
94 self.helm_conn.fs.reverse_sync.assert_called_once_with(
95 from_path=self.cluster_id
96 )
97 self.assertEqual(
98 self.helm_conn._local_async_exec.call_count,
99 2,
100 "local_async_exec expected 2 calls, called {}".format(
101 self.helm_conn._local_async_exec.call_count
102 ),
103 )
104
105 repo_update_command = (
106 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 repo update {}"
107 ).format(repo_name)
108 repo_add_command = (
109 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 repo add {} {}"
110 ).format(repo_name, repo_url)
111 calls = self.helm_conn._local_async_exec.call_args_list
112 call0_kargs = calls[0][1]
113 self.assertEqual(
114 call0_kargs.get("command"),
115 repo_add_command,
116 "Invalid repo add command: {}".format(call0_kargs.get("command")),
117 )
118 self.assertEqual(
119 call0_kargs.get("env"),
120 self.env,
121 "Invalid env for add command: {}".format(call0_kargs.get("env")),
122 )
123 call1_kargs = calls[1][1]
124 self.assertEqual(
125 call1_kargs.get("command"),
126 repo_update_command,
127 "Invalid repo update command: {}".format(call1_kargs.get("command")),
128 )
129 self.assertEqual(
130 call1_kargs.get("env"),
131 self.env,
132 "Invalid env for update command: {}".format(call1_kargs.get("env")),
133 )
134
135 @asynctest.fail_on(active_handles=True)
136 async def test_repo_list(self):
137 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
138
139 await self.helm_conn.repo_list(self.cluster_uuid)
140
141 self.helm_conn.fs.sync.assert_called_once_with(from_path=self.cluster_id)
142 self.helm_conn.fs.reverse_sync.assert_called_once_with(
143 from_path=self.cluster_id
144 )
145 command = "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 repo list --output yaml"
146 self.helm_conn._local_async_exec.assert_called_with(
147 command=command, env=self.env, raise_exception_on_error=False
148 )
149
150 @asynctest.fail_on(active_handles=True)
151 async def test_repo_remove(self):
152 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
153 repo_name = "bitnami"
154 await self.helm_conn.repo_remove(self.cluster_uuid, repo_name)
155
156 self.helm_conn.fs.sync.assert_called_once_with(from_path=self.cluster_id)
157 self.helm_conn.fs.reverse_sync.assert_called_once_with(
158 from_path=self.cluster_id
159 )
160 command = "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 repo remove {}".format(
161 repo_name
162 )
163 self.helm_conn._local_async_exec.assert_called_with(
164 command=command, env=self.env, raise_exception_on_error=True
165 )
166
167 @asynctest.fail_on(active_handles=True)
168 async def test_install(self):
169 kdu_model = "stable/openldap:1.2.2"
170 kdu_instance = "stable-openldap-0005399828"
171 db_dict = {}
172 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
173 self.helm_conn._status_kdu = asynctest.CoroutineMock(return_value=None)
174 self.helm_conn._store_status = asynctest.CoroutineMock()
175 self.kdu_instance = "stable-openldap-0005399828"
176 self.helm_conn.generate_kdu_instance_name = Mock(return_value=self.kdu_instance)
177 self.helm_conn._get_namespaces = asynctest.CoroutineMock(return_value=[])
178 self.helm_conn._namespace_exists = asynctest.CoroutineMock(
179 side_effect=self.helm_conn._namespace_exists
180 )
181 self.helm_conn._create_namespace = asynctest.CoroutineMock()
182
183 await self.helm_conn.install(
184 self.cluster_uuid,
185 kdu_model,
186 self.kdu_instance,
187 atomic=True,
188 namespace=self.namespace,
189 db_dict=db_dict,
190 )
191
192 self.helm_conn._namespace_exists.assert_called_once()
193 self.helm_conn._get_namespaces.assert_called_once()
194 self.helm_conn._create_namespace.assert_called_once_with(
195 self.cluster_id, self.namespace
196 )
197 self.helm_conn.fs.sync.assert_has_calls(
198 [
199 asynctest.call(from_path=self.cluster_id),
200 asynctest.call(from_path=self.cluster_id),
201 ]
202 )
203 self.helm_conn.fs.reverse_sync.assert_has_calls(
204 [
205 asynctest.call(from_path=self.cluster_id),
206 asynctest.call(from_path=self.cluster_id),
207 ]
208 )
209 self.helm_conn._store_status.assert_called_with(
210 cluster_id=self.cluster_id,
211 kdu_instance=kdu_instance,
212 namespace=self.namespace,
213 db_dict=db_dict,
214 operation="install",
215 )
216 command = (
217 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 "
218 "install stable-openldap-0005399828 --atomic --output yaml "
219 "--timeout 300s --namespace testk8s stable/openldap --version 1.2.2"
220 )
221 self.helm_conn._local_async_exec.assert_called_with(
222 command=command, env=self.env, raise_exception_on_error=False
223 )
224
225 # Exception test if namespace could not being created for some reason
226 self.helm_conn._namespace_exists.return_value = False
227 self.helm_conn._create_namespace.side_effect = Exception()
228
229 with self.assertRaises(K8sException):
230 await self.helm_conn.install(
231 self.cluster_uuid,
232 kdu_model,
233 self.kdu_instance,
234 atomic=True,
235 namespace=self.namespace,
236 db_dict=db_dict,
237 )
238
239 @asynctest.fail_on(active_handles=True)
240 async def test_namespace_exists(self):
241 self.helm_conn._get_namespaces = asynctest.CoroutineMock()
242
243 self.helm_conn._get_namespaces.return_value = ["testk8s", "kube-system"]
244 result = await self.helm_conn._namespace_exists(self.cluster_id, self.namespace)
245 self.helm_conn._get_namespaces.assert_called_once()
246 self.assertEqual(result, True)
247
248 self.helm_conn._get_namespaces.reset_mock()
249 result = await self.helm_conn._namespace_exists(
250 self.cluster_id, "none-exists-namespace"
251 )
252 self.helm_conn._get_namespaces.assert_called_once()
253 self.assertEqual(result, False)
254
255 @asynctest.fail_on(active_handles=True)
256 async def test_upgrade(self):
257 kdu_model = "stable/openldap:1.2.3"
258 kdu_instance = "stable-openldap-0005399828"
259 db_dict = {}
260 instance_info = {
261 "chart": "openldap-1.2.2",
262 "name": kdu_instance,
263 "namespace": self.namespace,
264 "revision": 1,
265 "status": "DEPLOYED",
266 }
267 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
268 self.helm_conn._store_status = asynctest.CoroutineMock()
269 self.helm_conn.get_instance_info = asynctest.CoroutineMock(
270 return_value=instance_info
271 )
272
273 await self.helm_conn.upgrade(
274 self.cluster_uuid, kdu_instance, kdu_model, atomic=True, db_dict=db_dict
275 )
276 self.helm_conn.fs.sync.assert_called_with(from_path=self.cluster_id)
277 self.helm_conn.fs.reverse_sync.assert_has_calls(
278 [
279 asynctest.call(from_path=self.cluster_id),
280 asynctest.call(from_path=self.cluster_id),
281 ]
282 )
283 self.helm_conn._store_status.assert_called_with(
284 cluster_id=self.cluster_id,
285 kdu_instance=kdu_instance,
286 namespace=self.namespace,
287 db_dict=db_dict,
288 operation="upgrade",
289 )
290 command = (
291 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config "
292 "/usr/bin/helm3 upgrade stable-openldap-0005399828 stable/openldap "
293 "--namespace testk8s --atomic --output yaml --timeout 300s "
294 "--reuse-values --version 1.2.3"
295 )
296 self.helm_conn._local_async_exec.assert_called_with(
297 command=command, env=self.env, raise_exception_on_error=False
298 )
299
300 @asynctest.fail_on(active_handles=True)
301 async def test_scale(self):
302 kdu_model = "stable/openldap:1.2.3"
303 kdu_instance = "stable-openldap-0005399828"
304 db_dict = {}
305 instance_info = {
306 "chart": "openldap-1.2.3",
307 "name": kdu_instance,
308 "namespace": self.namespace,
309 "revision": 1,
310 "status": "DEPLOYED",
311 }
312 repo_list = [
313 {
314 "name": "stable",
315 "url": "https://kubernetes-charts.storage.googleapis.com/",
316 }
317 ]
318 kdu_values = """
319 # Default values for openldap.
320 # This is a YAML-formatted file.
321 # Declare variables to be passed into your templates.
322
323 replicaCount: 1
324 dummy-app:
325 replicas: 2
326 """
327
328 self.helm_conn.repo_list = asynctest.CoroutineMock(return_value=repo_list)
329 self.helm_conn.values_kdu = asynctest.CoroutineMock(return_value=kdu_values)
330 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
331 self.helm_conn._store_status = asynctest.CoroutineMock()
332 self.helm_conn.get_instance_info = asynctest.CoroutineMock(
333 return_value=instance_info
334 )
335
336 # TEST-1
337 await self.helm_conn.scale(
338 kdu_instance,
339 2,
340 "",
341 kdu_model=kdu_model,
342 cluster_uuid=self.cluster_uuid,
343 atomic=True,
344 db_dict=db_dict,
345 )
346 command = (
347 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config "
348 "/usr/bin/helm3 upgrade stable-openldap-0005399828 stable/openldap "
349 "--namespace testk8s --atomic --output yaml --set replicaCount=2 --timeout 1800s "
350 "--reuse-values --version 1.2.3"
351 )
352 self.helm_conn._local_async_exec.assert_called_once_with(
353 command=command, env=self.env, raise_exception_on_error=False
354 )
355 # TEST-2
356 await self.helm_conn.scale(
357 kdu_instance,
358 3,
359 "dummy-app",
360 kdu_model=kdu_model,
361 cluster_uuid=self.cluster_uuid,
362 atomic=True,
363 db_dict=db_dict,
364 )
365 command = (
366 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config "
367 "/usr/bin/helm3 upgrade stable-openldap-0005399828 stable/openldap "
368 "--namespace testk8s --atomic --output yaml --set dummy-app.replicas=3 --timeout 1800s "
369 "--reuse-values --version 1.2.3"
370 )
371 self.helm_conn._local_async_exec.assert_called_with(
372 command=command, env=self.env, raise_exception_on_error=False
373 )
374 self.helm_conn.fs.reverse_sync.assert_called_with(from_path=self.cluster_id)
375 self.helm_conn._store_status.assert_called_with(
376 cluster_id=self.cluster_id,
377 kdu_instance=kdu_instance,
378 namespace=self.namespace,
379 db_dict=db_dict,
380 operation="scale",
381 )
382
383 @asynctest.fail_on(active_handles=True)
384 async def test_rollback(self):
385 kdu_instance = "stable-openldap-0005399828"
386 db_dict = {}
387 instance_info = {
388 "chart": "openldap-1.2.3",
389 "name": kdu_instance,
390 "namespace": self.namespace,
391 "revision": 2,
392 "status": "DEPLOYED",
393 }
394 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
395 self.helm_conn._store_status = asynctest.CoroutineMock()
396 self.helm_conn.get_instance_info = asynctest.CoroutineMock(
397 return_value=instance_info
398 )
399
400 await self.helm_conn.rollback(
401 self.cluster_uuid, kdu_instance=kdu_instance, revision=1, db_dict=db_dict
402 )
403 self.helm_conn.fs.sync.assert_called_with(from_path=self.cluster_id)
404 self.helm_conn.fs.reverse_sync.assert_called_once_with(
405 from_path=self.cluster_id
406 )
407 self.helm_conn._store_status.assert_called_with(
408 cluster_id=self.cluster_id,
409 kdu_instance=kdu_instance,
410 namespace=self.namespace,
411 db_dict=db_dict,
412 operation="rollback",
413 )
414 command = (
415 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 "
416 "rollback stable-openldap-0005399828 1 --namespace=testk8s --wait"
417 )
418 self.helm_conn._local_async_exec.assert_called_once_with(
419 command=command, env=self.env, raise_exception_on_error=False
420 )
421
422 @asynctest.fail_on(active_handles=True)
423 async def test_uninstall(self):
424 kdu_instance = "stable-openldap-0005399828"
425 instance_info = {
426 "chart": "openldap-1.2.2",
427 "name": kdu_instance,
428 "namespace": self.namespace,
429 "revision": 3,
430 "status": "DEPLOYED",
431 }
432 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
433 self.helm_conn._store_status = asynctest.CoroutineMock()
434 self.helm_conn.get_instance_info = asynctest.CoroutineMock(
435 return_value=instance_info
436 )
437
438 await self.helm_conn.uninstall(self.cluster_uuid, kdu_instance)
439 self.helm_conn.fs.sync.assert_called_with(from_path=self.cluster_id)
440 self.helm_conn.fs.reverse_sync.assert_called_once_with(
441 from_path=self.cluster_id
442 )
443 command = (
444 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 uninstall {} --namespace={}"
445 ).format(kdu_instance, self.namespace)
446 self.helm_conn._local_async_exec.assert_called_once_with(
447 command=command, env=self.env, raise_exception_on_error=True
448 )
449
450 @asynctest.fail_on(active_handles=True)
451 async def test_get_services(self):
452 kdu_instance = "test_services_1"
453 service = {"name": "testservice", "type": "LoadBalancer"}
454 self.helm_conn._local_async_exec_pipe = asynctest.CoroutineMock(
455 return_value=("", 0)
456 )
457 self.helm_conn._parse_services = Mock(return_value=["testservice"])
458 self.helm_conn._get_service = asynctest.CoroutineMock(return_value=service)
459
460 services = await self.helm_conn.get_services(
461 self.cluster_uuid, kdu_instance, self.namespace
462 )
463 self.helm_conn.fs.sync.assert_called_once_with(from_path=self.cluster_id)
464 self.helm_conn.fs.reverse_sync.assert_called_once_with(
465 from_path=self.cluster_id
466 )
467 self.helm_conn._parse_services.assert_called_once()
468 command1 = (
469 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 get manifest {} --namespace=testk8s"
470 ).format(kdu_instance)
471 command2 = "/usr/bin/kubectl get --namespace={} -f -".format(self.namespace)
472 self.helm_conn._local_async_exec_pipe.assert_called_once_with(
473 command1, command2, env=self.env, raise_exception_on_error=True
474 )
475 self.assertEqual(
476 services, [service], "Invalid service returned from get_service"
477 )
478
479 @asynctest.fail_on(active_handles=True)
480 async def test_get_service(self):
481 service_name = "service1"
482
483 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
484 await self.helm_conn.get_service(
485 self.cluster_uuid, service_name, self.namespace
486 )
487
488 self.helm_conn.fs.sync.assert_called_once_with(from_path=self.cluster_id)
489 self.helm_conn.fs.reverse_sync.assert_called_once_with(
490 from_path=self.cluster_id
491 )
492 command = (
493 "/usr/bin/kubectl --kubeconfig=./tmp/helm3_cluster_id/.kube/config "
494 "--namespace=testk8s get service service1 -o=yaml"
495 )
496 self.helm_conn._local_async_exec.assert_called_once_with(
497 command=command, env=self.env, raise_exception_on_error=True
498 )
499
500 @asynctest.fail_on(active_handles=True)
501 async def test_inspect_kdu(self):
502 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
503
504 kdu_model = "stable/openldap:1.2.4"
505 repo_url = "https://kubernetes-charts.storage.googleapis.com/"
506 await self.helm_conn.inspect_kdu(kdu_model, repo_url)
507
508 command = (
509 "/usr/bin/helm3 show all openldap --repo "
510 "https://kubernetes-charts.storage.googleapis.com/ "
511 "--version 1.2.4"
512 )
513 self.helm_conn._local_async_exec.assert_called_with(command=command)
514
515 @asynctest.fail_on(active_handles=True)
516 async def test_help_kdu(self):
517 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
518
519 kdu_model = "stable/openldap:1.2.4"
520 repo_url = "https://kubernetes-charts.storage.googleapis.com/"
521 await self.helm_conn.help_kdu(kdu_model, repo_url)
522
523 command = (
524 "/usr/bin/helm3 show readme openldap --repo "
525 "https://kubernetes-charts.storage.googleapis.com/ "
526 "--version 1.2.4"
527 )
528 self.helm_conn._local_async_exec.assert_called_with(command=command)
529
530 @asynctest.fail_on(active_handles=True)
531 async def test_values_kdu(self):
532 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
533
534 kdu_model = "stable/openldap:1.2.4"
535 repo_url = "https://kubernetes-charts.storage.googleapis.com/"
536 await self.helm_conn.values_kdu(kdu_model, repo_url)
537
538 command = (
539 "/usr/bin/helm3 show values openldap --repo "
540 "https://kubernetes-charts.storage.googleapis.com/ "
541 "--version 1.2.4"
542 )
543 self.helm_conn._local_async_exec.assert_called_with(command=command)
544
545 @asynctest.fail_on(active_handles=True)
546 async def test_get_values_kdu(self):
547 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
548
549 kdu_instance = "stable-openldap-0005399828"
550 await self.helm_conn.get_values_kdu(
551 kdu_instance, self.namespace, self.env["KUBECONFIG"]
552 )
553
554 command = (
555 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 get values "
556 "stable-openldap-0005399828 --namespace=testk8s --output yaml"
557 )
558 self.helm_conn._local_async_exec.assert_called_with(command=command)
559
560 @asynctest.fail_on(active_handles=True)
561 async def test_instances_list(self):
562 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
563
564 await self.helm_conn.instances_list(self.cluster_uuid)
565 self.helm_conn.fs.sync.assert_called_once_with(from_path=self.cluster_id)
566 self.helm_conn.fs.reverse_sync.assert_called_once_with(
567 from_path=self.cluster_id
568 )
569 command = "/usr/bin/helm3 list --all-namespaces --output yaml"
570 self.helm_conn._local_async_exec.assert_called_once_with(
571 command=command, env=self.env, raise_exception_on_error=True
572 )
573
574 @asynctest.fail_on(active_handles=True)
575 async def test_status_kdu(self):
576 kdu_instance = "stable-openldap-0005399828"
577 self.helm_conn._local_async_exec = asynctest.CoroutineMock(return_value=("", 0))
578
579 await self.helm_conn._status_kdu(
580 self.cluster_id, kdu_instance, self.namespace, yaml_format=True
581 )
582 command = (
583 "env KUBECONFIG=./tmp/helm3_cluster_id/.kube/config /usr/bin/helm3 status {} --namespace={} --output yaml"
584 ).format(kdu_instance, self.namespace)
585 self.helm_conn._local_async_exec.assert_called_once_with(
586 command=command,
587 env=self.env,
588 raise_exception_on_error=True,
589 show_error_log=False,
590 )
591
592 @asynctest.fail_on(active_handles=True)
593 async def test_store_status(self):
594 kdu_instance = "stable-openldap-0005399828"
595 db_dict = {}
596 status = {
597 "info": {
598 "description": "Install complete",
599 "status": {
600 "code": "1",
601 "notes": "The openldap helm chart has been installed",
602 },
603 }
604 }
605 self.helm_conn._status_kdu = asynctest.CoroutineMock(return_value=status)
606 self.helm_conn.write_app_status_to_db = asynctest.CoroutineMock(
607 return_value=status
608 )
609
610 await self.helm_conn._store_status(
611 cluster_id=self.cluster_id,
612 kdu_instance=kdu_instance,
613 namespace=self.namespace,
614 db_dict=db_dict,
615 operation="install",
616 )
617 self.helm_conn._status_kdu.assert_called_once_with(
618 cluster_id=self.cluster_id,
619 kdu_instance=kdu_instance,
620 namespace=self.namespace,
621 yaml_format=False,
622 )
623 self.helm_conn.write_app_status_to_db.assert_called_once_with(
624 db_dict=db_dict,
625 status="Install complete",
626 detailed_status=str(status),
627 operation="install",
628 )
629
630 @asynctest.fail_on(active_handles=True)
631 async def test_reset_uninstall_false(self):
632 self.helm_conn._uninstall_sw = asynctest.CoroutineMock()
633
634 await self.helm_conn.reset(self.cluster_uuid, force=False, uninstall_sw=False)
635 self.helm_conn.fs.sync.assert_called_once_with(from_path=self.cluster_id)
636 self.helm_conn.fs.file_delete.assert_called_once_with(
637 self.cluster_id, ignore_non_exist=True
638 )
639 self.helm_conn._uninstall_sw.assert_not_called()
640
641 @asynctest.fail_on(active_handles=True)
642 async def test_reset_uninstall(self):
643 kdu_instance = "stable-openldap-0021099429"
644 instances = [
645 {
646 "app_version": "2.4.48",
647 "chart": "openldap-1.2.3",
648 "name": kdu_instance,
649 "namespace": self.namespace,
650 "revision": "1",
651 "status": "deployed",
652 "updated": "2020-10-30 11:11:20.376744191 +0000 UTC",
653 }
654 ]
655 self.helm_conn._get_namespace = Mock(return_value=self.namespace)
656 self.helm_conn._uninstall_sw = asynctest.CoroutineMock()
657 self.helm_conn.instances_list = asynctest.CoroutineMock(return_value=instances)
658 self.helm_conn.uninstall = asynctest.CoroutineMock()
659
660 await self.helm_conn.reset(self.cluster_uuid, force=True, uninstall_sw=True)
661 self.helm_conn.fs.sync.assert_called_once_with(from_path=self.cluster_id)
662 self.helm_conn.fs.file_delete.assert_called_once_with(
663 self.cluster_id, ignore_non_exist=True
664 )
665 self.helm_conn._get_namespace.assert_called_once_with(
666 cluster_uuid=self.cluster_uuid
667 )
668 self.helm_conn.instances_list.assert_called_once_with(
669 cluster_uuid=self.cluster_uuid
670 )
671 self.helm_conn.uninstall.assert_called_once_with(
672 cluster_uuid=self.cluster_uuid, kdu_instance=kdu_instance
673 )
674 self.helm_conn._uninstall_sw.assert_called_once_with(
675 cluster_id=self.cluster_id, namespace=self.namespace
676 )
677
678 @asynctest.fail_on(active_handles=True)
679 async def test_sync_repos_add(self):
680 repo_list = [
681 {
682 "name": "stable",
683 "url": "https://kubernetes-charts.storage.googleapis.com/",
684 }
685 ]
686 self.helm_conn.repo_list = asynctest.CoroutineMock(return_value=repo_list)
687
688 def get_one_result(*args, **kwargs):
689 if args[0] == "k8sclusters":
690 return {
691 "_admin": {
692 "helm_chart_repos": ["4b5550a9-990d-4d95-8a48-1f4614d6ac9c"]
693 }
694 }
695 elif args[0] == "k8srepos":
696 return {
697 "_id": "4b5550a9-990d-4d95-8a48-1f4614d6ac9c",
698 "type": "helm-chart",
699 "name": "bitnami",
700 "url": "https://charts.bitnami.com/bitnami",
701 }
702
703 self.helm_conn.db.get_one = asynctest.Mock()
704 self.helm_conn.db.get_one.side_effect = get_one_result
705
706 self.helm_conn.repo_add = asynctest.CoroutineMock()
707 self.helm_conn.repo_remove = asynctest.CoroutineMock()
708
709 deleted_repo_list, added_repo_dict = await self.helm_conn.synchronize_repos(
710 self.cluster_uuid
711 )
712 self.helm_conn.repo_remove.assert_not_called()
713 self.helm_conn.repo_add.assert_called_once_with(
714 self.cluster_uuid, "bitnami", "https://charts.bitnami.com/bitnami"
715 )
716 self.assertEqual(deleted_repo_list, [], "Deleted repo list should be empty")
717 self.assertEqual(
718 added_repo_dict,
719 {"4b5550a9-990d-4d95-8a48-1f4614d6ac9c": "bitnami"},
720 "Repos added should include only one bitnami",
721 )
722
723 @asynctest.fail_on(active_handles=True)
724 async def test_sync_repos_delete(self):
725 repo_list = [
726 {
727 "name": "stable",
728 "url": "https://kubernetes-charts.storage.googleapis.com/",
729 },
730 {"name": "bitnami", "url": "https://charts.bitnami.com/bitnami"},
731 ]
732 self.helm_conn.repo_list = asynctest.CoroutineMock(return_value=repo_list)
733
734 def get_one_result(*args, **kwargs):
735 if args[0] == "k8sclusters":
736 return {"_admin": {"helm_chart_repos": []}}
737
738 self.helm_conn.db.get_one = asynctest.Mock()
739 self.helm_conn.db.get_one.side_effect = get_one_result
740
741 self.helm_conn.repo_add = asynctest.CoroutineMock()
742 self.helm_conn.repo_remove = asynctest.CoroutineMock()
743
744 deleted_repo_list, added_repo_dict = await self.helm_conn.synchronize_repos(
745 self.cluster_uuid
746 )
747 self.helm_conn.repo_add.assert_not_called()
748 self.helm_conn.repo_remove.assert_called_once_with(self.cluster_uuid, "bitnami")
749 self.assertEqual(
750 deleted_repo_list, ["bitnami"], "Deleted repo list should be bitnami"
751 )
752 self.assertEqual(added_repo_dict, {}, "No repos should be added")