Kustomize: How to patch items in `List`?

Created on 28 Nov 2018  路  5Comments  路  Source: kubernetes-sigs/kustomize

Some times resources are defined as items in a list, e.g. https://github.com/awslabs/aws-service-operator/blob/master/configs/aws-service-operator.yaml

How shall we patch them in kustomize?

Got an error message: Error: failed to find an object with gvk.Gvk{Group:"apps", Version:"v1beta1", Kind:"Deployment"} to apply the patch

When using the patch

kind: Deployment
apiVersion: apps/v1beta1
metadata:
  name: aws-service-operator
  namespace: aws-service-operator
...

For the item

apiVersion: v1
kind: List
items:
...
- kind: Deployment
  apiVersion: apps/v1beta1
  metadata:
    name: aws-service-operator
    namespace: aws-service-operator
kinbug

Most helpful comment

@yujunz It's not particularly intuitive in that the official documentation quite literally tells you to refer to the code.

To solve this problem, Strategic Merge Patch uses the go struct tag of the API objects to determine what lists should be merged and which ones should not.

What it really means is that each resource type has a "special key" that is used as an identifier, if you specify that in your patch it will look-up based on that key. In practice it would seem that you need to specify the patchMergeKey as the first key-value pair of list entries in your patch.

For example, the patchMergeKey for a container is name:

https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/core/v1/types.go#L2102

Thus, a patch for a Deployment might look like:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
        - name: myapp
          image: xxxxxxxxxxxx.dkr.ecr.ap-southeast-2.amazonaws.com/mycompany/mynamespace/myapp:1.0.0

The above patch replaces the image of the container with the name "myapp" with the image value specified in this patch.

All 5 comments

@yujunz It's not particularly intuitive in that the official documentation quite literally tells you to refer to the code.

To solve this problem, Strategic Merge Patch uses the go struct tag of the API objects to determine what lists should be merged and which ones should not.

What it really means is that each resource type has a "special key" that is used as an identifier, if you specify that in your patch it will look-up based on that key. In practice it would seem that you need to specify the patchMergeKey as the first key-value pair of list entries in your patch.

For example, the patchMergeKey for a container is name:

https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/core/v1/types.go#L2102

Thus, a patch for a Deployment might look like:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
        - name: myapp
          image: xxxxxxxxxxxx.dkr.ecr.ap-southeast-2.amazonaws.com/mycompany/mynamespace/myapp:1.0.0

The above patch replaces the image of the container with the name "myapp" with the image value specified in this patch.

Thanks @Benjamin-Dobell

If the deployment is NOT in List, the patch will work as expected.

The problem is that it is wrapped in a List. So it fails to find the Deployment. And I don't know how to specify the special key for a List.

apiVersion: v1
kind: List
items: []

There is no metadata in a List, even a name. So we may needs a different way to handle it.

@yujunz I know it's used internally, but is List part of the public API?

Nonetheless, kustomize also supports a JSON patch strategy that can be used to achieve what you want:

kustomization.yaml

patchesJson6902:
  - target:
      version: v1
      kind: List
    path: patch.yaml

patch.yaml

- op: replace
  path: /items/0/spec/template/spec/containers/0/image
  value: xxxxxxxxxxxx.dkr.ecr.ap-southeast-2.amazonaws.com/mycompany/mynamespace/myapp:1.0.0

@yujunz I know it's used internally, but is List part of the public API?

I think so, @Benjamin-Dobell . It is included in Kubernetes testdata

Nonetheless, kustomize also supports a JSON patch strategy that can be used to achieve what you want:

This could be a work around, but not precise enough. What we want is finding a specified item in the list and patch it, while the workaround is targeting a hardcoded item.

@yujunz This issue should be fixed by #637 , which let kustomize recognize resources/patches in List.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lionelvillard picture lionelvillard  路  4Comments

Liujingfang1 picture Liujingfang1  路  6Comments

mgoodness picture mgoodness  路  4Comments

wuestkamp picture wuestkamp  路  3Comments

drekle picture drekle  路  4Comments