Skip to content

Commit

Permalink
adding support for patchStatus and detection of patch type
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins authored and manusa committed May 21, 2021
1 parent ed08377 commit cc4945f
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#### Bugs

#### Improvements
* Fix #3135 added mock crud support for patch status, and will return exceptions for unsupported patch types

#### Dependency Upgrade

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.fabric8.kubernetes.api.model.StatusCause;
import io.fabric8.kubernetes.api.model.StatusCauseBuilder;
import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
import io.fabric8.kubernetes.client.dsl.base.OperationSupport;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.kubernetes.client.utils.Utils;
import io.fabric8.mockwebserver.Context;
Expand All @@ -34,6 +35,7 @@
import io.fabric8.mockwebserver.crud.ResponseComposer;
import io.fabric8.zjsonpatch.JsonDiff;
import io.fabric8.zjsonpatch.JsonPatch;
import okhttp3.MediaType;
import okhttp3.mockwebserver.MockResponse;

import java.io.IOException;
Expand Down Expand Up @@ -98,7 +100,7 @@ public synchronized MockResponse dispatch(RecordedRequest request) {
case PUT:
return handleReplace(path, request.getBody().readUtf8());
case PATCH:
return handlePatch(path, request.getBody().readUtf8());
return handlePatch(path, request.getBody().readUtf8(), request.getHeader("Content-Type"));
case GET:
return detectWatchMode(path)? handleWatch(path): handleGet(path);
case DELETE:
Expand Down Expand Up @@ -167,10 +169,10 @@ public MockResponse handleGet(String path) {
*
* @param path path of resource
* @param s object
* @param contentType
* @return The {@link MockResponse}
*/
@Override
public MockResponse handlePatch(String path, String s) {
public MockResponse handlePatch(String path, String s, String contentType) {
MockResponse response = new MockResponse();
String body = fetchResource(path);
if (body == null) {
Expand All @@ -179,9 +181,27 @@ public MockResponse handlePatch(String path, String s) {
try {
JsonNode patch = context.getMapper().readTree(s);
JsonNode source = context.getMapper().readTree(body);
JsonNode status = removeStatus(source);
JsonNode status = null;

if (!isStatusPath(path)) {
status = removeStatus(source);
}

if (contentType != null) {
MediaType type = MediaType.parse(contentType);
if (!type.subtype().equals(OperationSupport.JSON_PATCH.subtype())) {
response.setResponseCode(HttpURLConnection.HTTP_UNSUPPORTED_TYPE);
return response;
}
}
JsonNode updated = JsonPatch.apply(patch, source);
// restore the old status

if (isStatusPath(path)) {
status = removeStatus(updated);
updated = context.getMapper().readTree(body);
}

// restore the status
if (status == null) {
removeStatus(updated);
} else {
Expand Down Expand Up @@ -220,7 +240,7 @@ public MockResponse handlePatch(String path, String s) {
response.setResponseCode(HttpURLConnection.HTTP_ACCEPTED);
response.setBody(updatedAsString);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
response.setResponseCode(HTTP_UNPROCESSABLE_ENTITY);
}
}
return response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,68 @@ public void statusHandling() {
assertEquals(originalUid, result.getMetadata().getUid());
}

@Test
public void jsonPatchStatus() {
KubernetesServer kubernetesServer = new KubernetesServer(false, true);
kubernetesServer.before();
KubernetesClient kubernetesClient = kubernetesServer.getClient();
Pod pod = new PodBuilder().withNewMetadata()
.withName("name")
.withNamespace("test") // required until https://github.com/fabric8io/mockwebserver/pull/59
.endMetadata()
.build();
Pod result = kubernetesClient.pods().create(pod);

// should be null after create
assertNull(result.getStatus());

pod.setStatus(new PodStatusBuilder().withHostIP("1.2.3.4").build());
Map<String, String> labels = new HashMap<>();
labels.put("app", "core");

pod.getMetadata().setLabels(labels);

result = kubernetesClient.pods()
.inNamespace(pod.getMetadata().getNamespace())
.withName(pod.getMetadata().getName())
.editStatus(p->pod);

assertNotNull(result.getStatus().getHostIP());
assertNull(result.getMetadata().getLabels());
}

/**
* merge patch is not supported yet
*/
@Test
public void patchStatus() {
KubernetesServer kubernetesServer = new KubernetesServer(false, true);
kubernetesServer.before();
KubernetesClient kubernetesClient = kubernetesServer.getClient();
Pod pod = new PodBuilder().withNewMetadata()
.withName("name")
.withNamespace("test") // required until https://github.com/fabric8io/mockwebserver/pull/59
.endMetadata()
.build();
Pod result = kubernetesClient.pods().create(pod);

// should be null after create
assertNull(result.getStatus());

pod.setStatus(new PodStatusBuilder().withHostIP("1.2.3.4").build());
Map<String, String> labels = new HashMap<>();
labels.put("app", "core");

pod.getMetadata().setLabels(labels);

KubernetesClientException exception = assertThrows(KubernetesClientException.class, () -> kubernetesClient.pods()
.inNamespace(pod.getMetadata().getNamespace())
.withName(pod.getMetadata().getName())
.patchStatus(pod));
Assertions.assertEquals(HttpURLConnection.HTTP_UNSUPPORTED_TYPE, exception.getCode());

}

@Test
public void createConflict() {
KubernetesServer kubernetesServer = new KubernetesServer(false, true);
Expand Down

0 comments on commit cc4945f

Please sign in to comment.