2

I want to change (edit/add) labels on pods with specific labels. I have the following code:

public void changeLabelsForPodFilterByLabels(String namespace, Map<String, String> filterByLabels, Map<String, String> newLabels) {
    try {
        V1PodList podList = coreV1Api.listNamespacedPod(namespace, null, null, null, null, null, null, null, false);
        List<V1Pod> podsFilteredByLabel = filterPodsByLabels(podList.getItems(), filterByLabels);
        List<V1Pod> labelModifiedPods = addLabels(podsFilteredByLabel, newLabels);
        List<V1Pod> updatedPods = updatePods(namespace, labelModifiedPods);
    } catch (ApiException e) {
        logger.error("API Exception", e);
        logger.error(e.getMessage());
        logger.error(e.getResponseBody());
    }
}


private List<V1Pod> filterPodsByLabels(List<V1Pod> pods, Map<String, String> labels) {
    List<V1Pod> filteredPods = new ArrayList<>();
    logger.info("Input labels: " + labels.toString());
    for(V1Pod pod: pods) {
        logger.info("Pod: " + pod.getMetadata().getName());
        Map<String, String> podLabels = pod.getMetadata().getLabels();
        logger.info("Labels:" + podLabels.toString());
        if (podLabels.entrySet().containsAll(labels.entrySet())) {
            filteredPods.add(pod);
        }
    }
    return filteredPods;
}


private List<V1Pod> addLabels(List<V1Pod> pods, Map<String, String> newLabels) {
    List<V1Pod> updatedPods = new ArrayList<>();
    for (V1Pod pod: pods) {
        pod.getMetadata().setLabels(newLabels);
        updatedPods.add(pod);
    }
    return updatedPods;
}


private List<V1Pod> updatePods(String namespace, List<V1Pod> updatedPods) throws ApiException {

    for (V1Pod pod: updatedPods){
        V1Patch patch = new V1Patch();
        coreV1Api.patchNamespacedPod(pod.getMetadata().getName(), namespace, null, null, null, null, false);
    }
    return null;
}

Based on the example from here and from this thread and this thread I understand that a body should be provided as parameter to coreV1Api.patchNamespacedPod method.

Can someone provide an example on how a body should look like? Further, in the examples linked above I see that there is the notion of operation (defined by op field). What are the available operations (link to the docs would help)?

Dependencies:

<dependency>
    <groupId>io.kubernetes</groupId>
    <artifactId>client-java</artifactId>
    <version>6.0.1</version>
</dependency>

Later edit

I've changed the library version to 8.0.2 and now I was able to change the code as follows:

private List<V1Pod> updatePods(String namespace, List<V1Pod> updatedPods) throws ApiException {

    for (V1Pod pod: updatedPods){
        String body = generateBody("demo", "myvalue");
        V1Patch patch = new V1Patch(body);
        coreV1Api.patchNamespacedPod(pod.getMetadata().getName(), namespace, patch, null, null, null, false);
    }
    return null;
}

public String generateBody(String labelKey, String newLabelValue){
    return String.format("[{\"op\": \"add\", \"path\": \"/metadata/labels/%s\", \"value\": \"%s\"}]", labelKey, newLabelValue);
}

The above questions are still available because now I receive errors regarding the bad format/form of the body.

io.kubernetes.client.openapi.ApiException: Unprocessable Entity

florin
  • 719
  • 12
  • 31

1 Answers1

2

You could use JsonObject instead of String for body argument.
For example:

JsonObject item = new JsonObject();
item.add("op", new JsonPrimitive("add"));
item.add("path", new JsonPrimitive("/metadata/labels"));

JsonObject label = new JsonObject();
label.addProperty("demo", "myvalue");
item.add("value", label);
JsonArray body = new JsonArray();
body.add(item);

coreV1Api.patchNamespacedPod(pod.getMetadata().getName(), namespace, body, null, null, null, false);
卢声远 Shengyuan Lu
  • 31,208
  • 22
  • 85
  • 130