简体   繁体   中英

kubectl patch secret with bash gcloud identity-token, heredoc and printf

I want to create a simple k8s cronjob to keep a gcp identity token fresh in a secret.

A relatively simple problem that I am not able to solve

Given

kubectl patch secret token-test --type json -p=<< END
[
   {
     "op": "replace",
     "path": "/data/token.jwt",
     "value": "$(gcloud auth print-identity-token | base64 )"
   }
]
END

I want this to be applied with kubectl patch secret token-test --type json -p=$(printf "'%s'" "$json")

I have tried many variants, the weird thing is that if I paste in the result of the heredoc insted of printf it works. But all my efforts fails with (also tried a json doc on a single line)

$ kubectl patch secret token-test --type json -p=$(printf "'%s'" "$json")
error: unable to parse "'[{": yaml: found unexpected end of stream

Whereas this actually works:

printf "'%s'" "$json"|pbcopy 
kubectl patch secret sudo-token-test --type json -p '[{ "op": "replace","path": "/data/token.jwt","value": "ZX...Zwo="}]'
secret/token-test patched

I cannot understand what is different when it fails. I understand bash is a bit tricky when it comes to string handling, but I am not sure if this is a bash issue or an issue in kubectl.

$ json='[{ "op": "replace","path": "/data/token.jwt","value": "'"$(gcloud auth print-identity-token | base64 )"'"}]'
$ kubectl patch secret token-test --type json -p="$json"
secret/token-test patched

By appending the string insted of interpolating in the heredoc this was solved. Still don't know why the other approach failed though

It's a slight different approach but, howabout:

printf "foo" > test

kubectl create secret generic freddie \
--namespace=default \
--from-file=./test

kubectl get secret/freddie \
--namespace=default \
--output=jsonpath="{.data.test}" \
| base64 --decode
foo

X="$(printf "bar" | base64)"

kubectl patch secret/freddie \
--namespace=default \
--patch="{\"data\":{\"test\":\"${X}\"}}"

kubectl get secret/freddie \
--namespace=default \
--output=jsonpath="{.data.test}" \
| base64 --decode
bar

NOTE it's not a best practice to use your user ( gcloud auth print-identity-token ) credentials in this way. Service Accounts are preferred. Service Accounts are intended for machine (rather than a human) auth and they can be more easily revoked.

User credentials grant the bearer all the powers of the user account (and this is likely extensive).

There's a portable alternative in which you create a Kubernetes secret from a Service Account key:

 kubectl create secret generic your-key \\ --from-file=your-key.json=/path/to/your-key.json

There's a cool-kids who use GKE-mostly approach called Workload Identity

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM