Skip to content

Commit

Permalink
using the new context subresource for status operations (fabric8io#5005)
Browse files Browse the repository at this point in the history
* using the new context subresource for status operations

* using the new context subresource for status operations

* using subresource for approval
  • Loading branch information
shawkins committed Apr 21, 2023
1 parent c03eccf commit 3db8c80
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -707,14 +707,14 @@ protected T handleCreate(T resource) throws InterruptedException, IOException {
return handleCreate(resource, getType());
}

protected T handleUpdate(T updated, boolean status) throws InterruptedException, IOException {
protected T handleUpdate(T updated) throws InterruptedException, IOException {
updateApiVersion(updated);
return handleUpdate(updated, getType(), status);
return handleUpdate(updated, getType());
}

protected T handlePatch(PatchContext context, T current, T updated, boolean status) throws InterruptedException, IOException {
protected T handlePatch(PatchContext context, T current, T updated) throws InterruptedException, IOException {
updateApiVersion(updated);
return handlePatch(context, current, updated, getType(), status);
return handlePatch(context, current, updated, getType());
}

protected <S> S handleScale(S scaleParam, Class<S> scaleType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public HasMetadataOperation(OperationContext ctx, Class<T> type, Class<L> listTy
public T edit(UnaryOperator<T> function) {
T item = getItemOrRequireFromServer();
T clone = clone(item);
return patch(null, clone, function.apply(item), false);
return patch(null, clone, function.apply(item));
}

private T clone(T item) {
Expand All @@ -76,32 +76,36 @@ private T clone(T item) {
public T editStatus(UnaryOperator<T> function) {
T item = getItemOrRequireFromServer();
T clone = clone(item);
return patch(null, clone, function.apply(item), true);
return statusSubresource().patch(null, clone, function.apply(item));
}

private HasMetadataOperation<T, L, R> statusSubresource() {
return newInstance(context.withSubresource("status"));
}

@Override
public T accept(Consumer<T> consumer) {
T item = getItemOrRequireFromServer();
T clone = clone(item);
consumer.accept(item);
return patch(null, clone, item, false);
return patch(null, clone, item);
}

@Override
public T edit(Visitor... visitors) {
T item = getItemOrRequireFromServer();
T clone = clone(item);
return patch(null, clone, context.getHandler(item).edit(item).accept(visitors).build(), false);
return patch(null, clone, context.getHandler(item).edit(item).accept(visitors).build());
}

@Override
public T replace() {
return replace(getItem(), false);
return handleReplace(getItem());
}

@Override
public T replaceStatus() {
return replace(getItem(), true);
return statusSubresource().replace();
}

/**
Expand All @@ -117,15 +121,15 @@ protected T modifyItemForReplaceOrPatch(Supplier<T> current, T item) {

@Override
public T update() {
return this.update(getItem(), false);
return this.update(getItem());
}

@Override
public T updateStatus() {
return this.update(getItem(), true);
return statusSubresource().update();
}

protected T update(T item, boolean status) {
protected T update(T item) {
String existingResourceVersion = KubernetesResourceUtil.getResourceVersion(item);
try {
if (existingResourceVersion == null) {
Expand All @@ -134,7 +138,7 @@ protected T update(T item, boolean status) {
item = clone(item);
item.getMetadata().setResourceVersion(resourceVersion);
}
return handleUpdate(item, status);
return handleUpdate(item);
} catch (KubernetesClientException e) {
throw KubernetesClientException.launderThrowable(forOperationType(UPDATE_OPERATION), e);
} catch (InterruptedException e) {
Expand All @@ -148,15 +152,15 @@ protected T update(T item, boolean status) {
/**
* base replace operation, which is effectively a forced update with retries
*/
protected T replace(T item, boolean status) {
protected T handleReplace(T item) {
String fixedResourceVersion = getResourceVersion();
Exception caught = null;
int maxTries = 10;
item = clone(item);
if (item.getMetadata() == null) {
item.setMetadata(new ObjectMeta());
}
if (!status) {
if (context.getSubresource() == null) {
try {
item = modifyItemForReplaceOrPatch(this::requireFromServer, item);
} catch (Exception e) {
Expand All @@ -180,7 +184,7 @@ protected T replace(T item, boolean status) {
final UnaryOperator<T> visitor = resource -> {
try {
resource.getMetadata().setResourceVersion(resourceVersion);
return handleUpdate(resource, status);
return handleUpdate(resource);
} catch (Exception e) {
throw KubernetesClientException.launderThrowable(forOperationType(REPLACE_OPERATION), e);
}
Expand Down Expand Up @@ -212,7 +216,7 @@ protected T replace(T item, boolean status) {
* Perform a patch. If the base is not provided and one is required, it will
* be fetched from the server.
*/
protected T patch(PatchContext context, T base, T item, boolean status) {
protected T patch(PatchContext context, T base, T item) {
if ((context == null || context.getPatchType() == PatchType.JSON) && base == null) {
if (base == null) {
base = requireFromServer();
Expand All @@ -227,7 +231,7 @@ protected T patch(PatchContext context, T base, T item, boolean status) {
final T theBase = base;
final UnaryOperator<T> visitor = resource -> {
try {
return handlePatch(context, theBase, resource, status);
return handlePatch(context, theBase, resource);
} catch (Exception e) {
throw KubernetesClientException.launderThrowable(forOperationType(PATCH_OPERATION), e);
}
Expand All @@ -237,34 +241,34 @@ protected T patch(PatchContext context, T base, T item, boolean status) {

@Override
public T patchStatus() {
return patch(PatchContext.of(PatchType.JSON_MERGE), null, getNonNullItem(), true);
return statusSubresource().patch(PatchContext.of(PatchType.JSON_MERGE), null, getNonNullItem());
}

@Override
public T patch() {
return patch(null, null, getNonNullItem(), false);
return patch(null, null, getNonNullItem());
}

@Override
public T patch(PatchContext patchContext) {
return patch(patchContext, null, getNonNullItem(), false);
return patch(patchContext, null, getNonNullItem());
}

@Override
public T patchStatus(T item) {
return patch(PatchContext.of(PatchType.JSON_MERGE), getItem(), clone(item), true);
return statusSubresource().patch(PatchContext.of(PatchType.JSON_MERGE), getItem(), clone(item));
}

@Override
public T patch(PatchContext patchContext, T item) {
return patch(patchContext, getItem(), clone(item), false);
return patch(patchContext, getItem(), clone(item));
}

@Override
public T patch(PatchContext patchContext, String patch) {
try {
final T got = getItemOrRequireFromServer();
return handlePatch(patchContext, got, convertToJson(patch), getType(), false);
return handlePatch(patchContext, got, convertToJson(patch), getType());
} catch (InterruptedException interruptedException) {
Thread.currentThread().interrupt();
throw KubernetesClientException.launderThrowable(forOperationType(PATCH_OPERATION), interruptedException);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,7 @@ public URL getResourceUrl(String namespace, String name, String... subresources)
return new URL(URLUtils.join(getNamespacedUrl(namespace).toString(), path));
}

public URL getResourceUrl(String namespace, String name, boolean status) throws MalformedURLException {
if (status) {
return getResourceUrl(namespace, name, "status");
}

public URL getResourceUrl(String namespace, String name) throws MalformedURLException {
return getResourceUrl(namespace, name, subresource);
}

Expand Down Expand Up @@ -354,17 +350,16 @@ protected <T, I> T handleCreate(I resource, Class<T> outputType) throws Interrup
*
* @param updated updated object
* @param type type of the object provided
* @param status if this is only the status subresource
* @param <T> template argument provided
*
* @return returns de-serialized version of api server response
* @throws IOException IOException
*/
protected <T> T handleUpdate(T updated, Class<T> type, boolean status) throws IOException {
protected <T> T handleUpdate(T updated, Class<T> type) throws IOException {
updated = correctNamespace(updated);
HttpRequest.Builder requestBuilder = httpClient.newHttpRequestBuilder()
.put(JSON, JSON_MAPPER.writeValueAsString(updated))
.url(getResourceURLForWriteOperation(getResourceUrl(checkNamespace(updated), checkName(updated), status)));
.url(getResourceURLForWriteOperation(getResourceUrl(checkNamespace(updated), checkName(updated))));
return handleResponse(requestBuilder, type);
}

Expand All @@ -378,14 +373,13 @@ protected <T> T handleUpdate(T updated, Class<T> type, boolean status) throws IO
* @param current current object
* @param updated updated object
* @param type type of object
* @param status if this is only the status subresource
* @param <T> template argument provided
*
* @return returns de-serialized version of api server response
* @throws InterruptedException Interrupted Exception
* @throws IOException IOException
*/
protected <T> T handlePatch(PatchContext patchContext, T current, T updated, Class<T> type, boolean status)
protected <T> T handlePatch(PatchContext patchContext, T current, T updated, Class<T> type)
throws InterruptedException, IOException {
String patchForUpdate;
if (current != null && (patchContext == null || patchContext.getPatchType() == PatchType.JSON)) {
Expand Down Expand Up @@ -416,7 +410,7 @@ protected <T> T handlePatch(PatchContext patchContext, T current, T updated, Cla
patchForUpdate = Serialization.asJson(updated);
current = updated; // use the updated to determine the path
}
return handlePatch(patchContext, current, patchForUpdate, type, status);
return handlePatch(patchContext, current, patchForUpdate, type);
}

/**
Expand All @@ -426,18 +420,17 @@ protected <T> T handlePatch(PatchContext patchContext, T current, T updated, Cla
* @param current current object
* @param patchForUpdate Patch string
* @param type type of object
* @param status if this is only the status subresource
* @param <T> template argument provided
* @return returns de-serialized version of api server response
* @throws InterruptedException Interrupted Exception
* @throws IOException IOException in case of network errors
*/
protected <T> T handlePatch(PatchContext patchContext, T current, String patchForUpdate, Class<T> type, boolean status)
protected <T> T handlePatch(PatchContext patchContext, T current, String patchForUpdate, Class<T> type)
throws InterruptedException, IOException {
String bodyContentType = getContentTypeFromPatchContextOrDefault(patchContext);
HttpRequest.Builder requestBuilder = httpClient.newHttpRequestBuilder()
.patch(bodyContentType, patchForUpdate)
.url(getResourceURLForPatchOperation(getResourceUrl(checkNamespace(current), checkName(current), status),
.url(getResourceURLForPatchOperation(getResourceUrl(checkNamespace(current), checkName(current)),
patchContext));
return handleResponse(requestBuilder, type);
}
Expand Down Expand Up @@ -491,17 +484,8 @@ protected <T> T handleGet(URL resourceUrl, Class<T> type) throws InterruptedExce
return handleResponse(requestBuilder, type);
}

protected <T extends HasMetadata> T handleApproveOrDeny(T csr, Class<T> type) throws IOException, InterruptedException {
String uri = URLUtils.join(getResourceUrl(null, csr.getMetadata().getName(), false).toString(), "approval");
HttpRequest.Builder requestBuilder = httpClient.newHttpRequestBuilder()
.put(JSON, JSON_MAPPER.writeValueAsString(csr)).uri(uri);
return handleResponse(requestBuilder, type);
}

/**
* Send a raw get - where the type should be one of String, Reader, InputStream
* <br>
* NOTE: Currently does not utilize the retry logic
*/
protected <T> T handleRawGet(URL resourceUrl, Class<T> type) throws IOException {
HttpRequest.Builder requestBuilder = httpClient.newHttpRequestBuilder().url(resourceUrl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public T updateImage(Map<String, String> containerToImageMap) {
}

protected T sendPatchedObject(T oldObject, T updatedObject) {
return this.patch(null, oldObject, updatedObject, false);
return this.patch(null, oldObject, updatedObject);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,11 @@
import io.fabric8.kubernetes.api.model.certificates.v1.CertificateSigningRequestStatus;
import io.fabric8.kubernetes.api.model.certificates.v1.CertificateSigningRequestStatusBuilder;
import io.fabric8.kubernetes.client.Client;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.dsl.CertificateSigningRequestResource;
import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperation;
import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
import io.fabric8.kubernetes.client.dsl.internal.OperationContext;

import java.io.IOException;

public class CertificateSigningRequestOperationsImpl extends
HasMetadataOperation<CertificateSigningRequest, CertificateSigningRequestList, CertificateSigningRequestResource<CertificateSigningRequest>>
implements CertificateSigningRequestResource<CertificateSigningRequest> {
Expand Down Expand Up @@ -60,16 +57,9 @@ public CertificateSigningRequest deny(CertificateSigningRequestCondition certifi

private CertificateSigningRequest addStatusToCSRAndSubmit(
CertificateSigningRequestCondition certificateSigningRequestCondition) {
try {
CertificateSigningRequest fromServerCsr = get();
fromServerCsr.setStatus(createCertificateSigningRequestStatus(certificateSigningRequestCondition));
return handleApproveOrDeny(fromServerCsr, CertificateSigningRequest.class);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw KubernetesClientException.launderThrowable(forOperationType("approval " + type), ie);
} catch (IOException e) {
throw KubernetesClientException.launderThrowable(forOperationType("approval " + type), e);
}
CertificateSigningRequest fromServerCsr = get();
fromServerCsr.setStatus(createCertificateSigningRequestStatus(certificateSigningRequestCondition));
return newInstance(context.withSubresource("approval")).update(fromServerCsr);
}

private CertificateSigningRequestStatus createCertificateSigningRequestStatus(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,11 @@
import io.fabric8.kubernetes.api.model.certificates.v1beta1.CertificateSigningRequestStatus;
import io.fabric8.kubernetes.api.model.certificates.v1beta1.CertificateSigningRequestStatusBuilder;
import io.fabric8.kubernetes.client.Client;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.dsl.V1beta1CertificateSigningRequestResource;
import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperation;
import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
import io.fabric8.kubernetes.client.dsl.internal.OperationContext;

import java.io.IOException;

public class CertificateSigningRequestOperationsImpl extends
HasMetadataOperation<CertificateSigningRequest, CertificateSigningRequestList, V1beta1CertificateSigningRequestResource<CertificateSigningRequest>>
implements V1beta1CertificateSigningRequestResource<CertificateSigningRequest> {
Expand Down Expand Up @@ -67,15 +64,8 @@ private CertificateSigningRequestStatus createCertificateSigningRequestStatus(

private CertificateSigningRequest addStatusToCSRAndSubmit(
CertificateSigningRequestCondition certificateSigningRequestCondition) {
try {
CertificateSigningRequest fromServerCsr = get();
fromServerCsr.setStatus(createCertificateSigningRequestStatus(certificateSigningRequestCondition));
return handleApproveOrDeny(fromServerCsr, CertificateSigningRequest.class);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw KubernetesClientException.launderThrowable(forOperationType("approval " + type), ie);
} catch (IOException e) {
throw KubernetesClientException.launderThrowable(forOperationType("approval " + type), e);
}
CertificateSigningRequest fromServerCsr = get();
fromServerCsr.setStatus(createCertificateSigningRequestStatus(certificateSigningRequestCondition));
return newInstance(context.withSubresource("approval")).update(fromServerCsr);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,19 +159,18 @@ void getResourceURL() throws MalformedURLException {
@Test
void getResourceURLStatus() throws MalformedURLException {
OperationSupport pods = new OperationSupport(operationSupport.context.withPlural("pods"));
assertThat(pods.getResourceUrl("default", "pod-1", true))
OperationSupport podsStatus = new OperationSupport(operationSupport.context.withPlural("pods").withSubresource("status"));
assertThat(podsStatus.getResourceUrl("default", "pod-1"))
.hasToString("https://kubernetes.default.svc/api/v1/namespaces/default/pods/pod-1/status");
assertThat(pods.getResourceUrl("default", "pod-1", false))
assertThat(pods.getResourceUrl("default", "pod-1"))
.hasToString("https://kubernetes.default.svc/api/v1/namespaces/default/pods/pod-1");

OperationSupport podsSubresource = new OperationSupport(pods.context.withSubresource("ephemeralcontainers"));
assertThat(podsSubresource.getResourceUrl("default", "pod-1", true))
.hasToString("https://kubernetes.default.svc/api/v1/namespaces/default/pods/pod-1/status");
assertThat(podsSubresource.getResourceUrl("default", "pod-1", false))
assertThat(podsSubresource.getResourceUrl("default", "pod-1"))
.hasToString("https://kubernetes.default.svc/api/v1/namespaces/default/pods/pod-1/ephemeralcontainers");

assertThrows(KubernetesClientException.class, () -> {
operationSupport.getResourceUrl("default", null, true);
podsStatus.getResourceUrl("default", null);
}, "status requires name");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ void testDeny() {

private CertificateSigningRequestBuilder createCertificateSigningRequest() {
return new CertificateSigningRequestBuilder()
.withNewMetadata().withName("my-cert").endMetadata()
.withNewMetadata().withName("my-cert").withResourceVersion("1").endMetadata()
.withNewSpec()
.withSignerName("fabric8io.com/kubernetes-java-client")
.addToGroups("system:authenticated")
Expand Down
Loading

0 comments on commit 3db8c80

Please sign in to comment.