I have a project that need to update cloneset yaml
YAML document something like:
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
generation: 1
...
spec:
...
...
volumeClaimTemplates:
- metadata:
creationTimestamp: null
name: data1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 60G
- metadata:
creationTimestamp: null
name: data2
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 60G
status:
availableReplicas: 1
I want to patch volumeClaimTemplates based on metadata.name
If name is not specified, storages for all volumeClaimTemplates are updated, and if name is specified and is matched, storages for a specific name are updated, if name is specified, but name don't match, return error
matchVolumeTemplateName=${1-all}
storage="$2"
if [[ ${matchVolumeTemplateName} == "all" ]]; then
./bin/yq e -i ".spec.volumeClaimTemplates[].spec.resources.requests.storage = \"${storage}\"" "cloneset_modifystorage.yml"
else
./bin/yq e -i ".spec.volumeClaimTemplates[] | select(.metadata.name == "\"${matchVolumeTemplateName}\"").spec.resources.requests.storage |= \"${storage}\"" "cloneset_modifystorage.yml"
fi
However, with the above code, only part of the YAML data will be output if a match is found
for the specified name, and the file will be empty if name don't match, for example matchVolumeTemplateName=data3
# cloneset_modifystorage.yml
# matchVolumeTemplateName = data1 storage = 90G
# Other data of K8S YAML is lost
metadata:
creationTimestamp: null
name: data1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 90G
As a result, other data information about K8S is missing , and an empty file is printed instead of an error when a name match fails.
I really appreciate any help with this.
You can simplify things by passing shell variables to the yq
command directly instead of interpolating them with double-quotes
match="${1-all}"
storage="$2"
if [[ $match == "all" ]]; then
s="$storage" yq e '.spec.volumeClaimTemplates[].spec.resources.requests.storage = env(s)' cloneset_modifystorage.yml
else
m="$match" s="$storage" yq e '(.spec.volumeClaimTemplates[] | select(.metadata.name == env(m)).spec.resources.requests.storage) |= env(s)' cloneset_modifystorage.yml
fi
The values m
and s
can be looked up the env() function directly inside the yq filter expression. The key logic in the else part would be to add the parens( ( )
) around the filter to produce the resulting output at the whole root node level and not at the sub element level
Verify the output in either cases and add the -i
flag for in-place replacement.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.