How to properly patch a configmap?

Viewed 275

I have a configmap that looks like this:

apiVersion: v1
data:
  nginx.conf: "events {worker_connections  1024;
.
.
.
}"
kind: ConfigMap
metadata:
  name: nginx-cfg
  namespace: nginx

I want to add a new line of text to the begining of nginx.conf:

apiVersion: v1
data:
   nginx.conf: " <some line of new text here>
   events {worker_connections  1024;
  .
  .
  .
  }"
kind: ConfigMap
metadata:
   name: nginx-cfg
   namespace: nginx

I use this patch command to make changes:

kubectl patch configmap/nginx-cfg \
      -n nginx \
      --type merge \
      -p '{"data":{"nginx.conf":{"load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so"}}}'

but got an error: Error from server: Invalid JSON Patch. What shoud I do to fix the error?

Thank you for your help!

1 Answers

The error is because you're trying to go into file block. If you remove the braces:

-p '{"data":{"nginx.conf":{"load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so"}}}'

to:

-p '{"data":{"nginx.conf":"load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so"}}'

Then the patch will then succeed, but would overwrite the config file contents:

$ kubectl patch configmap/nginx-cfg --type merge -p '{"data":{"nginx.conf":"load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so"}}' -o yaml
apiVersion: v1
data:
  nginx.conf: load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so
kind: ConfigMap
metadata:
  name: nginx-cfg

If you want to patch the contents of that field, then you have a few options:

a) Dump the configmap, modify the confimap locally using sed or similar tools, then kubectl replace it back. Note the "\ \ \ \ " is intentional to pad the line within the yaml

kubectl get configmap nginx-cfg -o yaml >nginx-cfg.yaml

sed -i '/nginx\.conf.*/a  \ \ \ \ load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so nginx-cfg.yaml #Or whatever edits you need to make

kubectl replace -f nginx-cfg.yaml

b) Extract the config block itself using kubectl get configmap nginx-cfg -o jsonpath="{.data.nginx\.conf}", dump it to disk, modify the block, then kubectl create configmap using that and replace

kubectl get configmap nginx-cfg -o jsonpath="{.data.nginx\.conf}" >nginx.conf

sed -i '1 i\load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so' nginx.conf #Or whatever edits you need to make

kubectl create configmap --dry-run=client --from-file=nginx.conf nginx-cfg -o yaml | kubectl replace -f -

c) Using some pipes to do the edits in-line (only useful if it's single line change. Otherwise, it's worth doing one of the above instead). This gets the yaml, edits it in-line, then feeds it back into kubectl to replace the existing configmap

kubectl get configmap nginx-cfg -o yaml | \
  sed '/nginx\.conf.*/a  \ \ \ \ load_module /usr/lib/nginx/modules/ngx_http_vhost_traffic_status_module.so' | \
  kubectl replace -f -

Related