Skip to content

Commit 40a7763

Browse files
authored
refactor: change rolling restart/pause/resume to use rfc6902 JSON patch (6723)
Change rolling restart/pause/resume to use rfc6902 JSON patch Fixes #6658 --- review: style checks Signed-off-by: Marc Nuri <[email protected]>
1 parent e305dad commit 40a7763

File tree

3 files changed

+116
-29
lines changed

3 files changed

+116
-29
lines changed

kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollingUpdater.java

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@
4545
import java.security.NoSuchAlgorithmException;
4646
import java.time.ZoneOffset;
4747
import java.time.format.DateTimeFormatter;
48+
import java.util.Collections;
4849
import java.util.Date;
4950
import java.util.HashMap;
5051
import java.util.List;
51-
import java.util.Map;
5252
import java.util.Objects;
5353
import java.util.concurrent.CompletableFuture;
5454
import java.util.concurrent.Future;
@@ -169,8 +169,8 @@ public T rollUpdate(T oldObj, T newObj) {
169169
}
170170
}
171171

172-
private static <T> T applyPatch(Resource<T> resource, Map<String, Object> map, KubernetesSerialization serialization) {
173-
return resource.patch(PatchContext.of(PatchType.STRATEGIC_MERGE), serialization.asJson(map));
172+
private static <T> T applyPatch(Resource<T> resource, List<Object> list, KubernetesSerialization serialization) {
173+
return resource.patch(PatchContext.of(PatchType.JSON), serialization.asJson(list));
174174
}
175175

176176
public static <T extends HasMetadata> T resume(RollableScalableResourceOperation<T, ?, ?> resource) {
@@ -185,35 +185,30 @@ public static <T extends HasMetadata> T restart(RollableScalableResourceOperatio
185185
return applyPatch(resource, RollingUpdater.requestPayLoadForRolloutRestart(), resource.getKubernetesSerialization());
186186
}
187187

188-
public static Map<String, Object> requestPayLoadForRolloutPause() {
189-
Map<String, Object> jsonPatchPayload = new HashMap<>();
190-
Map<String, Object> spec = new HashMap<>();
191-
spec.put("paused", true);
192-
jsonPatchPayload.put("spec", spec);
193-
return jsonPatchPayload;
188+
public static List<Object> requestPayLoadForRolloutPause() {
189+
HashMap<String, Object> patch = new HashMap<>();
190+
patch.put("op", "add");
191+
patch.put("path", "/spec/paused");
192+
patch.put("value", true);
193+
return Collections.singletonList(patch);
194194
}
195195

196-
public static Map<String, Object> requestPayLoadForRolloutResume() {
197-
Map<String, Object> jsonPatchPayload = new HashMap<>();
198-
Map<String, Object> spec = new HashMap<>();
199-
spec.put("paused", null);
200-
jsonPatchPayload.put("spec", spec);
201-
return jsonPatchPayload;
196+
public static List<Object> requestPayLoadForRolloutResume() {
197+
HashMap<String, Object> patch = new HashMap<>();
198+
patch.put("op", "remove");
199+
patch.put("path", "/spec/paused");
200+
return Collections.singletonList(patch);
202201
}
203202

204-
public static Map<String, Object> requestPayLoadForRolloutRestart() {
205-
Map<String, Object> jsonPatchPayload = new HashMap<>();
206-
Map<String, String> annotations = new HashMap<>();
207-
annotations.put("kubectl.kubernetes.io/restartedAt",
203+
public static List<Object> requestPayLoadForRolloutRestart() {
204+
HashMap<String, Object> patch = new HashMap<>();
205+
HashMap<String, Object> value = new HashMap<>();
206+
patch.put("op", "replace");
207+
patch.put("path", "/spec/template/metadata/annotations");
208+
value.put("kubectl.kubernetes.io/restartedAt",
208209
new Date().toInstant().atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
209-
Map<String, Object> templateMetadata = new HashMap<>();
210-
templateMetadata.put("annotations", annotations);
211-
Map<String, Object> template = new HashMap<>();
212-
template.put("metadata", templateMetadata);
213-
Map<String, Object> deploymentSpec = new HashMap<>();
214-
deploymentSpec.put("template", template);
215-
jsonPatchPayload.put("spec", deploymentSpec);
216-
return jsonPatchPayload;
210+
patch.put("value", value);
211+
return Collections.singletonList(patch);
217212
}
218213

219214
/**

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/DeploymentCrudTest.java

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import static org.junit.jupiter.api.Assertions.assertEquals;
3131
import static org.junit.jupiter.api.Assertions.assertFalse;
3232
import static org.junit.jupiter.api.Assertions.assertNotNull;
33+
import static org.junit.jupiter.api.Assertions.assertNull;
3334
import static org.junit.jupiter.api.Assertions.assertTrue;
3435

3536
@EnableKubernetesMockClient(crud = true)
@@ -125,4 +126,95 @@ void testReplace() {
125126
assertFalse(replacedDeployment.getMetadata().getLabels().isEmpty());
126127
assertEquals("one", replacedDeployment.getMetadata().getLabels().get("testKey"));
127128
}
129+
130+
@Test
131+
@DisplayName("Should pause resource")
132+
void testPause() {
133+
// Given
134+
Deployment deployment1 = new DeploymentBuilder().withNewMetadata()
135+
.withName("d1")
136+
.withNamespace("ns1")
137+
.addToLabels("testKey", "testValue")
138+
.endMetadata()
139+
.withNewSpec()
140+
.endSpec()
141+
.build();
142+
client.apps().deployments().inNamespace("ns1").create(deployment1);
143+
144+
// When
145+
client.apps()
146+
.deployments()
147+
.inNamespace("ns1")
148+
.withName("d1")
149+
.rolling()
150+
.pause();
151+
Deployment updatedDeployment = client.apps().deployments().inNamespace("ns1").withName("d1").get();
152+
153+
// Then
154+
assertNotNull(updatedDeployment);
155+
assertEquals(true, updatedDeployment.getSpec().getPaused());
156+
}
157+
158+
@Test
159+
@DisplayName("Should resume rollout")
160+
void testRolloutResume() throws InterruptedException {
161+
// Given
162+
Deployment deployment1 = new DeploymentBuilder().withNewMetadata()
163+
.withName("d1")
164+
.withNamespace("ns1")
165+
.addToLabels("testKey", "testValue")
166+
.endMetadata()
167+
.withNewSpec()
168+
.withPaused(true)
169+
.endSpec()
170+
.build();
171+
client.apps().deployments().inNamespace("ns1").create(deployment1);
172+
173+
// When
174+
client.apps()
175+
.deployments()
176+
.inNamespace("ns1")
177+
.withName("d1")
178+
.rolling()
179+
.resume();
180+
Deployment updatedDeployment = client.apps().deployments().inNamespace("ns1").withName("d1").get();
181+
182+
// Then
183+
assertNotNull(updatedDeployment);
184+
assertNull(updatedDeployment.getSpec().getPaused());
185+
}
186+
187+
@Test
188+
@DisplayName("Should restart rollout")
189+
void testRolloutRestart() throws InterruptedException {
190+
// Given
191+
Deployment deployment1 = new DeploymentBuilder().withNewMetadata()
192+
.withName("d1")
193+
.withNamespace("ns1")
194+
.addToLabels("testKey", "testValue")
195+
.endMetadata()
196+
.withNewSpec()
197+
.withNewTemplate()
198+
.withNewMetadata()
199+
.addToAnnotations("", "")
200+
.endMetadata()
201+
.endTemplate()
202+
.endSpec()
203+
.build();
204+
client.apps().deployments().inNamespace("ns1").create(deployment1);
205+
206+
// When
207+
client.apps()
208+
.deployments()
209+
.inNamespace("ns1")
210+
.withName("d1")
211+
.rolling()
212+
.restart();
213+
Deployment updatedDeployment = client.apps().deployments().inNamespace("ns1").withName("d1").get();
214+
215+
// Then
216+
assertNotNull(updatedDeployment);
217+
assertNotNull(
218+
updatedDeployment.getSpec().getTemplate().getMetadata().getAnnotations().get("kubectl.kubernetes.io/restartedAt"));
219+
}
128220
}

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/DeploymentTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ void testRolloutPause() throws InterruptedException {
622622
// Then
623623
RecordedRequest recordedRequest = server.getLastRequest();
624624
assertEquals("PATCH", recordedRequest.getMethod());
625-
assertEquals("{\"spec\":{\"paused\":true}}", recordedRequest.getBody().readUtf8());
625+
assertEquals("[{\"op\":\"add\",\"path\":\"/spec/paused\",\"value\":true}]", recordedRequest.getBody().readUtf8());
626626
}
627627

628628
@Test
@@ -652,7 +652,7 @@ void testRolloutResume() throws InterruptedException {
652652
RecordedRequest recordedRequest = server.getLastRequest();
653653
assertNotNull(deployment);
654654
assertEquals("PATCH", recordedRequest.getMethod());
655-
assertEquals("{\"spec\":{\"paused\":null}}", recordedRequest.getBody().readUtf8());
655+
assertEquals("[{\"op\":\"remove\",\"path\":\"/spec/paused\"}]", recordedRequest.getBody().readUtf8());
656656
}
657657

658658
@Test

0 commit comments

Comments
 (0)