-
Notifications
You must be signed in to change notification settings - Fork 309
Allow token refresh for GCP #402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow token refresh for GCP #402
Conversation
/assign @brendandburns |
IMHO, it is better to have token refresh via rest api than via cli |
While I agree, you would need to setup a whole oauth2 authentication
mechanism from scratch. The current method is to read token from kubectl
config. This works well for local runs when you're using current context of
kubectl, and not appropriate for service deployments. To setup standalone
auth, you will need to provide clientid, secret and manage token lifecycle
manually. I think both should be supported - kubectl for local and rest
when you're doing actual development.
As a side note, current implementation of local kubectl config is deeply
flawed for all providers. It only reads current access token when
kubernetes object is constructed. Once that token is expired, the app will
stop worrying.
…On Mon., Apr. 6, 2020, 5:50 p.m. Boshi Lian, ***@***.***> wrote:
IMHO, it is better to have token refresh via rest api than via cli
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#402 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAINFWASO635S2CBG6FG5ETRLJFBDANCNFSM4MCQ6NWQ>
.
|
As we're supporting reading tokens out of kubectl config, there's limited information available there. There's no way to gain access to clientid/secret/refreshtoken using current approach. Given that it is still desirable to be able to allow apps to authenticate using creds found in current kubectl context, I propose the current authenticator be renamed to something like KubectlGcp, and another one built to support token management via REST for when you want to configure authentication explicitly. |
} | ||
|
||
AccessToken = config["access-token"]; | ||
TokenProvider = new GcpTokenProvider(config["cmd-path"]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know the expected details of a GCP kubeconfig, but is this field present in all configs?
Are the GCP kubeconfig contents documented anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe google "documents" it as it automatically configures context for you, but it is the way they do it. To be safe I can make this behavior apply only when the specified field is present
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think I prefer that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found where this is coming from and in case of "gcp" it will always be present as it's hardcoded behavior of official go client. https://github.com/kubernetes/client-go/blob/master/plugin/pkg/client/auth/gcp/gcp.go
Imo no reason to do the extra check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, can you add a pointer to this "documentation" in a comment
e.g.
``// docs: https://github.com/kubernetes/client-go/blob/master/plugin/pkg/client/auth/gcp/gcp.go#L58`
|
||
namespace k8s.Authentication | ||
{ | ||
public class GcpTokenProvider : ITokenProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file needs a unit test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you expect the unit test to look? This class is 90% call to an external process which a) doesn't exist in unit test environment
b) requires to be authenticated / configured in order to respond correctly
I can certainly try to create a shell script to mock of what gcloud cli returns, though I question the value of such test. Beyond invoking external command, the rest of this class is just two lines of json querying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's sufficient logic (e.g. return code != 0 -> failure, etc) that I think it deserves a test.
There's an equivalent test for the Javascript client here:
https://github.com/kubernetes-client/javascript/blob/master/src/exec_auth_test.ts
@@ -76,5 +77,7 @@ public partial class KubernetesClientConfiguration | |||
/// </summary> | |||
/// <value>The access token.</value> | |||
public string AccessToken { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like instead of both having an AccessToken field and a TokenProvider field, we should just switch to TokenProvider everywhere and use a StaticTokenProvider
or somesuch for the static token case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue atm is tokens actually expire. This is very noticeable with GCP provider which issues short lived tokens - KubernetesClient stops working after about 10 minutes. After that token is done, you need to interact with kubectl to force it to get a new token, and re-read it by recreating KubernetesClient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I get the problem, what I'm suggesting is that we remove the AccessToken
field in favor of a TokenProvider
everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to do this for AKS, but the cluster that I just spun up seems to use certs for authentication, as I got client-key-data, client-certificate-data, and token in my config file. The current code seems to be written where there's access_token. Under what scenario would this be so?
I feel like if we're supporting kubectl current context authentication, then we need to support all different types of authentication that kubectl uses, which includes
- OIDC - discover endpoints automatically
- external CLI to get token (like gcp)
- hardcoded / static (aks seems to use static token + cert)
- Oauth2 - hardcoded endpoints
Would be good to see a sample of what AWS EKS config looks like, I don't have one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this is where all the different built in authenticators are defined
https://github.com/kubernetes/client-go/tree/master/plugin/pkg/client/auth
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on my research, it seems there are 3 out of the box authentication providers that kubectl uses: gcp, azure & oidc, and each of these would translate to their own unique token provider. They are as listed in the above URL. These act very much like HttpMessageHandlers. The selection of the provider is dependent on
users:
user:
auth-provider:
name: XXX
My implementation for gcp is actually correct. Ideally, we want to have separate implementation for the other two types of providers. I propose that is done in a separate PR.
I won't be able to code for azure plugin because I'm lacking an AKS cluster that is integrated with Azure AD. I can't set this up as you need to be Azure tenant admin to configure this, and I don't have those rights in my org. If someone wants to provide me with AKS cluster that is enabled for Azure AD integration, I would be happy to create that token authenticator. The instructions on how to set this up are here: https://docs.microsoft.com/en-us/azure/aks/azure-ad-integration
I'm ok with the |
5489e8f
to
572e0e1
Compare
tests/KubernetesClient.Tests/Authentication/GcpTokenProvider.cs
Outdated
Show resolved
Hide resolved
Looks good, but I think there is a stray unneeded test cases in there? |
|
|
Accidental checked in file - removed |
@macsux I resolved some merge/rebase conflicts, can you double check the code looks right and then this is ready to merge. Thanks for the patience. |
Looks like there are some formatting fixes needed. Please run |
53757b8
to
1d1ff1b
Compare
1d1ff1b
to
8a4b7dc
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: brendandburns, macsux The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
No description provided.