Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using the new context subresource for status operations #5005

Merged
merged 5 commits into from
Apr 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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