Is There a Way in "Kubectl Patch" to Delete a Specific Object in an Array Without Specifying the Index?

When I use "kubectl patch" to delete a specific object in an array, I need to first check the index of that specific object, and then do the kubectl patch with the json/yaml path.

For example, I have an resource contains multiple port object:

spec:
  clusterIP: 100.12.143.76
  externalTrafficPolicy: Cluster
  ports:
  - name: object1
    nodePort: 30681
    port: 1234
    protocol: TCP
    targetPort: 1234
  - name: object2
    nodePort: 31805
    port: 9876
    protocol: TCP
    targetPort: 9876

If I need to remove the "object1" in the ports, here is the command I am using now (kong-proxy is the name of this service resource):

kubectl patch service kong-proxy --type=json -p='[{"op": "remove", "path": "/spec/ports/0"}]' -n kong

By doing the command above, it deletes the object at index "0" which with the name "object1".

But this requires the person to know the correct index number in advance, and if there are too many objects in an array, it will be hard to manage and calculate the index.

Therefore I wonder without writing a separate bash script, is there a way that I can delete the object with an identifier in it.

Such as:

kubectl patch service kong-proxy --type=json -p='[{"op": "remove", "path": "/spec/ports/{name:object1}"}]' -n kong

2 Answers

I'm afraid it's not possible. The kubectl patch --type=json command uses JSON Patch under the hood, which in turn uses JSON Pointer. JSON Pointer standard is pretty simple and does not provide filtering/matching functionality.

What you could do as a work around is using jq to find the array index, before calling kubectl patch:

INDEX=$(kubectl get svc kong-proxy -n kong -o json  | jq '.spec.ports | map(.name == "object1") | index(true)')

kubectl patch svc kong-proxy --type=json -p="[{'op': 'remove', 'path': '/spec/ports/$INDEX'}]" -n kong
2

For anyone who stumbles across this post, instead of patch command, try this:

kubectl get <resource> <resource-name> -o json | jq 'del(.<path-to-array>.<array-name>[] | select(."<field-name>"=="<field-value>"))' | kubectl apply -f -

Replace everything inside "<>" with appropriate values.

Explanation:

First, get the resource's json output, then modify the output inline using jq (delete array element) and finally apply the newly formed json directly.

EDIT:

Use this approach if array elements have no key/field to select them by:

kubectl get <resource> <resource-name> -o json | jq ".<path-to-array>.<array-name> -= [\"<value-to-delete>\"]" | kubectl apply -f -

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest