Skip to content

Commit a7566b9

Browse files
authored
action rollout deployment implementation (#144)
* action rollout deployment implementation --------- Signed-off-by: Jorge Tapicha <jitapichab@gmail.com>
1 parent 1fa332a commit a7566b9

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
## [Unreleased][]
88

9+
### Added
10+
11+
* Rollout deployment action `chaosk8s.deployment.actions.rollout_deployment`
12+
913
[Unreleased]: https://github.com/chaostoolkit/chaostoolkit-kubernetes/compare/0.26.4...HEAD
1014

1115

chaosk8s/deployment/actions.py

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import datetime
12
import json
23
import os.path
34

@@ -10,7 +11,12 @@
1011

1112
from chaosk8s import create_k8s_api_client
1213

13-
__all__ = ["create_deployment", "delete_deployment", "scale_deployment"]
14+
__all__ = [
15+
"create_deployment",
16+
"delete_deployment",
17+
"scale_deployment",
18+
"rollout_deployment",
19+
]
1420

1521

1622
def create_deployment(spec_path: str, ns: str = "default", secrets: Secrets = None):
@@ -82,3 +88,33 @@ def scale_deployment(
8288
raise ActivityFailed(
8389
f"failed to scale '{name}' to {replicas} replicas: {str(e)}"
8490
)
91+
92+
93+
def rollout_deployment(
94+
name: str = None,
95+
ns: str = "default",
96+
secrets: Secrets = None,
97+
):
98+
"""
99+
Rolling the deployment. The `name` is the name of the deployment.
100+
"""
101+
api = create_k8s_api_client(secrets)
102+
103+
v1 = client.AppsV1Api(api)
104+
105+
now = datetime.datetime.now(datetime.timezone.utc)
106+
now = str(now.isoformat("T") + "Z")
107+
body = {
108+
"spec": {
109+
"template": {
110+
"metadata": {"annotations": {"kubectl.kubernetes.io/restartedAt": now}}
111+
}
112+
}
113+
}
114+
115+
try:
116+
v1.patch_namespaced_deployment(name=name, namespace=ns, body=body)
117+
except ApiException as e:
118+
raise ActivityFailed(
119+
f"failed to rollout the deployment '{name}'! Error: {str(e)}"
120+
)

tests/test_deployment.py

+36
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime, timezone
12
from unittest.mock import ANY, MagicMock, call, patch
23

34
import pytest
@@ -8,6 +9,7 @@
89
from chaosk8s.deployment.actions import (
910
create_deployment,
1011
delete_deployment,
12+
rollout_deployment,
1113
scale_deployment,
1214
)
1315
from chaosk8s.deployment.probes import (
@@ -183,3 +185,37 @@ def test_deployment_is_not_fully_available_when_it_should(cl, client, watch, has
183185
with pytest.raises(ActivityFailed) as x:
184186
deployment_fully_available("mysvc")
185187
assert "deployment 'mysvc' failed to recover within" in str(x.value)
188+
189+
190+
def _generate_mock_time():
191+
return datetime(2023, 6, 7, 10, 30, 0, tzinfo=timezone.utc)
192+
193+
194+
@patch("chaosk8s.deployment.actions.create_k8s_api_client", autospec=True)
195+
@patch("chaosk8s.deployment.actions.client", autospec=True)
196+
def test_rollout_deployment(client, api):
197+
v1 = MagicMock()
198+
client.AppsV1Api.return_value = v1
199+
mock_now = _generate_mock_time()
200+
201+
with patch("datetime.datetime") as mock_time:
202+
mock_time.now.return_value = mock_now
203+
mock_now_str = f'{mock_now.isoformat("T")}Z'
204+
205+
body = {
206+
"spec": {
207+
"template": {
208+
"metadata": {
209+
"annotations": {
210+
"kubectl.kubernetes.io/restartedAt": mock_now_str
211+
}
212+
}
213+
}
214+
}
215+
}
216+
217+
rollout_deployment("fake", "fake_ns")
218+
219+
v1.patch_namespaced_deployment.assert_called_with(
220+
name="fake", namespace="fake_ns", body=body
221+
)

0 commit comments

Comments
 (0)