Skip to content

Commit 434120f

Browse files
committed
feat: adding deployment commands
1 parent 2733a95 commit 434120f

File tree

9 files changed

+204
-118
lines changed

9 files changed

+204
-118
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from kubernetes import client, config
2+
from lifeguard_k8s.settings import (
3+
LIFEGUARD_KUBERNETES_CONFIG,
4+
)
5+
6+
7+
def _load_config():
8+
if LIFEGUARD_KUBERNETES_CONFIG:
9+
config.load_kube_config(LIFEGUARD_KUBERNETES_CONFIG)
10+
else:
11+
config.load_incluster_config()
12+
13+
14+
def get_client():
15+
_load_config()
16+
return client.CoreV1Api()
17+
18+
19+
def get_apps_client():
20+
_load_config()
21+
return client.AppsV1Api()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from lifeguard_k8s.infrastructure import get_apps_client
2+
3+
4+
def scale_a_deployment(namespace, deployment_name, replicas):
5+
apps_v1 = get_apps_client()
6+
apps_v1.patch_namespaced_deployment_scale(
7+
deployment_name, namespace, {"spec": {"replicas": replicas}}
8+
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from lifeguard_k8s.infrastructure import get_client, get_apps_client
2+
3+
4+
def get_namespace_infos(namespace):
5+
"""
6+
Return current main infos of a namespace
7+
"""
8+
infos = {"pods": [], "deployments": []}
9+
10+
v1 = get_client()
11+
apps_v1 = get_apps_client()
12+
13+
pods = v1.list_namespaced_pod(namespace)
14+
deployments = apps_v1.list_namespaced_deployment(namespace)
15+
16+
for pod in pods.items:
17+
infos["pods"].append(
18+
{
19+
"name": pod.metadata.name,
20+
"status": pod.status.phase,
21+
"containers": [
22+
{
23+
"name": container.name,
24+
"ready": container.ready,
25+
"restart_count": container.restart_count,
26+
}
27+
for container in pod.status.container_statuses
28+
],
29+
}
30+
)
31+
32+
for deployment in deployments.items:
33+
infos["deployments"].append(
34+
{
35+
"name": deployment.metadata.name,
36+
"replicas": deployment.status.replicas,
37+
"ready_replicas": deployment.status.ready_replicas,
38+
"unavailable_replicas": deployment.status.unavailable_replicas,
39+
}
40+
)
41+
return infos
Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
from kubernetes import client, config
1+
from lifeguard_k8s.infrastructure import get_client
22
from lifeguard_k8s.settings import (
3-
LIFEGUARD_KUBERNETES_CONFIG,
43
LIFEGUARD_KUBERNETES_READ_LOG_MAX_SIZE,
54
)
65

@@ -24,46 +23,10 @@ def _exists_success_pod_after_job(job_pod, pods):
2423
return False
2524

2625

27-
def _get_clients():
28-
if LIFEGUARD_KUBERNETES_CONFIG:
29-
config.load_kube_config(LIFEGUARD_KUBERNETES_CONFIG)
30-
else:
31-
config.load_incluster_config()
32-
33-
return client.CoreV1Api()
34-
35-
36-
def get_namespace_infos(namespace):
37-
"""
38-
Return current main infos of a namespace
39-
"""
40-
infos = {"pods": []}
41-
42-
v1 = _get_clients()
43-
pods = v1.list_namespaced_pod(namespace)
44-
45-
for pod in pods.items:
46-
infos["pods"].append(
47-
{
48-
"name": pod.metadata.name,
49-
"status": pod.status.phase,
50-
"containers": [
51-
{
52-
"name": container.name,
53-
"ready": container.ready,
54-
"restart_count": container.restart_count,
55-
}
56-
for container in pod.status.container_statuses
57-
],
58-
}
59-
)
60-
return infos
61-
62-
6326
def get_not_running_pods(namespace):
6427
not_running_pods = []
6528

66-
v1 = _get_clients()
29+
v1 = get_client()
6730
pods = v1.list_namespaced_pod(namespace)
6831

6932
for pod in pods.items:
@@ -80,12 +43,12 @@ def get_not_running_pods(namespace):
8043

8144

8245
def delete_a_pod(namespace, pod_name):
83-
v1 = _get_clients()
46+
v1 = get_client()
8447
v1.delete_namespaced_pod(pod_name, namespace)
8548

8649

8750
def get_events_from_pod(namespace, pod_name):
88-
v1 = _get_clients()
51+
v1 = get_client()
8952
events = v1.list_namespaced_event(
9053
namespace, field_selector=f"involvedObject.name={pod_name}"
9154
)
@@ -109,6 +72,6 @@ def get_last_error_event_from_pod(namespace, pod_name):
10972

11073

11174
def get_logs_from_pod(namespace, pod_name):
112-
v1 = _get_clients()
75+
v1 = get_client()
11376
log = v1.read_namespaced_pod_log(pod_name, namespace)
11477
return log[-LIFEGUARD_KUBERNETES_READ_LOG_MAX_SIZE:]

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
setup(
88
name="lifeguard-k8s",
9-
version="1.2.1",
9+
version="1.3.0",
1010
url="https://github.com/LifeguardSystem/lifeguard-k8s",
1111
author="Diego Rubin",
1212
author_email="[email protected]",

tests/infrastructure/__init__.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from unittest.mock import MagicMock
2+
3+
4+
def build_pod(status, container_status, pod_name, kind="ReplicaSet"):
5+
container_statuses = MagicMock(name="container_statuses")
6+
container_statuses.ready = container_status
7+
container_statuses.restart_count = 0
8+
container_statuses.name = "container_name"
9+
10+
owner_reference = MagicMock(name="owner_reference")
11+
owner_reference.kind = kind
12+
owner_reference.name = pod_name
13+
14+
pod = MagicMock(name="pod")
15+
pod.status = MagicMock(name="status")
16+
pod.status.phase = status
17+
pod.status.container_statuses = [container_statuses]
18+
pod.metadata.name = pod_name
19+
pod.metadata.owner_references = [owner_reference]
20+
21+
return pod
22+
23+
24+
def build_deployment(name, replicas, ready_replicas):
25+
deployment = MagicMock(name="deployment")
26+
deployment.metadata.name = name
27+
deployment.status.replicas = replicas
28+
deployment.status.ready_replicas = ready_replicas
29+
deployment.status.unavailable_replicas = 0
30+
return deployment
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from unittest import TestCase
2+
from unittest.mock import patch
3+
4+
from lifeguard_k8s.infrastructure.deployments import scale_a_deployment
5+
6+
7+
class InfrastructureDeploymentsTests(TestCase):
8+
@patch("lifeguard_k8s.infrastructure.config")
9+
@patch("lifeguard_k8s.infrastructure.client")
10+
def test_scale_a_deployment(self, mock_client, _mock_config):
11+
patch_namespaced_deployment_scale = (
12+
mock_client.AppsV1Api.return_value.patch_namespaced_deployment_scale
13+
)
14+
patch_namespaced_deployment_scale.return_value = ""
15+
16+
scale_a_deployment("namespace", "deployment_name", 1)
17+
18+
patch_namespaced_deployment_scale.assert_called_with(
19+
"deployment_name", "namespace", {"spec": {"replicas": 1}}
20+
)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from unittest import TestCase
2+
from unittest.mock import patch
3+
4+
from tests.infrastructure import build_pod, build_deployment
5+
6+
from lifeguard_k8s.infrastructure.namespaces import get_namespace_infos
7+
8+
9+
class InfrastructureNamespacesTests(TestCase):
10+
@patch("lifeguard_k8s.infrastructure.config")
11+
@patch("lifeguard_k8s.infrastructure.client")
12+
def test_get_namespace_infos(self, mock_client, _mock_config):
13+
pod = build_pod("Running", True, "pod_name")
14+
deployment = build_deployment("deployment_name", 1, 1)
15+
16+
mock_client.CoreV1Api.return_value.list_namespaced_pod.return_value.items = [
17+
pod
18+
]
19+
20+
mock_client.AppsV1Api.return_value.list_namespaced_deployment.return_value.items = [
21+
deployment
22+
]
23+
24+
self.assertEqual(
25+
get_namespace_infos("namespace"),
26+
{
27+
"deployments": [
28+
{
29+
"name": "deployment_name",
30+
"ready_replicas": 1,
31+
"replicas": 1,
32+
"unavailable_replicas": 0,
33+
}
34+
],
35+
"pods": [
36+
{
37+
"containers": [
38+
{
39+
"name": "container_name",
40+
"ready": True,
41+
"restart_count": 0,
42+
}
43+
],
44+
"name": "pod_name",
45+
"status": "Running",
46+
}
47+
],
48+
},
49+
)

0 commit comments

Comments
 (0)