Hi,
I submitted a kubectl plugin,based on kube-rs, to krew-index. One of the reviewer got error when trying to use it with gcp.
https://github.com/kubernetes-sigs/krew-index/pull/294#issuecomment-549704461
thread 'main' panicked at 'failed to load kubeconfig: Error { inner: Error loading kube config: Missing GOOGLE_APPLICATION_CREDENTIALS env }', src/libcore/result.rs:1084:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. [1] 95119 abort kubectl view-allocationsDoesn't work well on GCP. :(
Ideally you shouldn't need $GOOGLE_APPLICATION_CREDENTIALS, kubectl doesn't. It just calls intogcloud config config-helper --format=jsonto get an access_token+expiration.
Can you help or provide me some guidance for a PR ?
Presumably it should shell out to gcloud config using some sort of ExecCredential setup. There's already some machinery in exec.rs for doing this, it might do with better error handling. However, it was kind of just grabbed from upstream in https://github.com/clux/kube-rs/pull/20 . Haven not gotten much experience with it myself.
It might help to clarify what the success conditions are (e.g. what a working config looks like that kubectl can work with), and how it fails with kube. Going to tag as help wanted for now.
Maybe a generic hack (until there is a full implementation able to update kubeconfig) could be to run a command like kubectl custer-info to trigger a refresh of token (for gke, oidc,...) ?
What you're looking for is codified at https://github.com/kubernetes/client-go/blob/master/plugin/pkg/client/auth/gcp/gcp.go
Basically, the command to execute to get creds is gcloud config config-helper --format=json. This cmd is provided in kubeconfig entry created by GKE, such as:
users:
- name: gke_ahmetb-demo_us-central1-b_gke-cluster
user:
auth-provider:
config:
access-token: [....]
cmd-args: config config-helper --format=json
cmd-path: /usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin/gcloud
expiry: "2019-11-15T01:55:55Z"
expiry-key: '{.credential.token_expiry}'
token-key: '{.credential.access_token}'
name: gcp
This object tells you:
Then you cache this value by updating kubeconfig file entry's access-token and expiry fields.
Based on expiration date in kubeconfig file, you either use the existing token cached in this file, or get a new one (and cache it).
Alternatively, you can shell out to gcloud auth print-access-token from this client library, which just prints a token, but similarly you'd need to handle refreshing yourself (and this cmd doesn't tell you when it expires, but it's 3600s) 鈥揳nd again, each invocation of this command calls https://www.googleapis.com/oauth2/v4/token to get a brand new token.
A mechanism to shell out to the cmd-path with cmd-args and execute the jsonpath at token-key now exists via #328 in 0.43.0.
There might be some more stuff missing for this issue, as I've not been able to cross reference with a live GCP cluster yet, so please re-open if anyone spots something!
Most helpful comment
What you're looking for is codified at https://github.com/kubernetes/client-go/blob/master/plugin/pkg/client/auth/gcp/gcp.go
Basically, the command to execute to get creds is
gcloud config config-helper --format=json. This cmd is provided in kubeconfig entry created by GKE, such as:This object tells you:
Then you cache this value by updating kubeconfig file entry's
access-tokenandexpiryfields.Based on expiration date in kubeconfig file, you either use the existing token cached in this file, or get a new one (and cache it).
Alternatively, you can shell out to
gcloud auth print-access-tokenfrom this client library, which just prints a token, but similarly you'd need to handle refreshing yourself (and this cmd doesn't tell you when it expires, but it's 3600s) 鈥揳nd again, each invocation of this command callshttps://www.googleapis.com/oauth2/v4/tokento get a brand new token.