Skip to content

Conversation

macsux
Copy link
Contributor

@macsux macsux commented Apr 6, 2020

No description provided.

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Apr 6, 2020
@macsux
Copy link
Contributor Author

macsux commented Apr 6, 2020

/assign @brendandburns

@tg123
Copy link
Member

tg123 commented Apr 6, 2020

IMHO, it is better to have token refresh via rest api than via cli

@macsux
Copy link
Contributor Author

macsux commented Apr 6, 2020 via email

@macsux
Copy link
Contributor Author

macsux commented Apr 6, 2020

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"]);
Copy link
Contributor

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?

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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; }
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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

Copy link
Contributor Author

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

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Apr 7, 2020
@brendandburns
Copy link
Contributor

I'm ok with the TokenProvider refactor in a different PR. Please add a unit test for the GCP Token Provider and I think this is ready to merge.

@macsux macsux force-pushed the feature/authenticators branch 2 times, most recently from 5489e8f to 572e0e1 Compare April 20, 2020 18:40
@brendandburns
Copy link
Contributor

Looks good, but I think there is a stray unneeded test cases in there?

@macsux
Copy link
Contributor Author

macsux commented Apr 22, 2020

I think there is a stray unneeded test cases in there
What do you mean?

@brendandburns
Copy link
Contributor

tests/KubernetesClient.Tests/Authentication/GcpTokenProvider.cs doesn't appear to actually be testing anything? There are no asserts in that file, it just creates the token provider.

@macsux
Copy link
Contributor Author

macsux commented Apr 22, 2020

Accidental checked in file - removed

@brendandburns
Copy link
Contributor

@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.

@brendandburns
Copy link
Contributor

Looks like there are some formatting fixes needed. Please run dotnet format --exclude src/KubernetesClient/generated

@macsux macsux force-pushed the feature/authenticators branch 2 times, most recently from 53757b8 to 1d1ff1b Compare April 23, 2020 21:05
@macsux macsux force-pushed the feature/authenticators branch from 1d1ff1b to 8a4b7dc Compare April 26, 2020 22:25
@brendandburns
Copy link
Contributor

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Apr 28, 2020
@k8s-ci-robot
Copy link
Contributor

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 28, 2020
@k8s-ci-robot k8s-ci-robot merged commit ae9dd04 into kubernetes-client:master Apr 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants