I'm wondering if there's any way to use a patch to "/root/subdir", which will either create "root" if it doesn't exist (plus "subdir"), or simply add or replace "subdir" if "root" already exists.
Example:
patchesJson6902:
- target:
kind: MyKind
name: config
version: v1beta1
group: mygroup.com
patch: |-
- op: replace
path: /spec/array/0/spec/newField
value: test
If /spec/array/0/spec exists already, then everything succeeds. Otherwise, I get:
% kustomize build --load-restrictor LoadRestrictionsNone
Error: replace operation does not apply: doc is missing path: /spec/array/0/spec/newField: missing value
I realize that "replace" effectively won't do this, but is there a way to achieve this behavior?
The most frequent issue that arises while using kubectl kustomize for Json6902 patching is the failure to recognize that "add" might occasionally behave like "replace”. The same problem & its solution is explained in this Medium blog by Paul Dally.
By themselves, Kubernetes patches are made to work with resources that already exist; they do not automatically support adding missing directories to the path. However, if the "/root" directory doesn't already exist, you can create it and then use a strategic merge patch to modify "/root/subdir" in order to get the desired behavior.
Strategic Merge patch :
Refer to this official Kubernetes doc for more information about Strategic Merge patch.
This patch attempts to merge the provided spec section which includes the nested “newfield” if the “spec/array/0/spec” does not exist, it will be created with the specified “newField” value By following this approach you can effectively create or update the nested structure within your kubernetes resources using patches.
EDIT1: (Based on your comment) Your problem with the inline patch style most likely stems from the fact that deep merges are automatically performed by strategic merge patches.
The patch that just contains the /spec/array/0/spec/newfield definition overwrites the entire object with an empty object that only contains the specified field when the /spec field is absent from the original object. As a result, certain current fields are accidentally removed. Here how to adjust your inline patch to achieve the desired behavior.
Method 1 : Patch with existing spec preservation:
Using the newField key, the patch explicitly specifies the /spec/array/0/spec structure. Since the patch includes the complete /spec section, Kubernetes executes a deep merge, adding the missing nested structure and updating the newField value while retaining any existing fields within the /spec object.
Method 2 : Strategic merge patch with sub fields : A strategic merging patch with sub-fields is used in another method.
This patch is similar to the previous one, but it only defines the desired /spec/array/0/spec/newField element.
If you wish to clearly explain the full hierarchical structure, use the first method. For a more condensed patch that assumes the remainder of the /spec object is already available, use the second method.
Refer to this document for more information