Skip to content
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

User: <username> does not have appropriate auth credentials in kubeconfig #226

Closed
cilerler opened this issue Dec 21, 2018 · 5 comments · Fixed by #227
Closed

User: <username> does not have appropriate auth credentials in kubeconfig #226

cilerler opened this issue Dec 21, 2018 · 5 comments · Fixed by #227

Comments

@cilerler
Copy link
Contributor

Examples are based on

var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
IKubernetes client = new Kubernetes(config);

where it doesn't work out of the box and according to #91 workaround is simply

> kubectl proxy
Starting to serve on 127.0.0.1:8001

and calling it as

var config = new KubernetesClientConfiguration {  Host = "http://127.0.0.1:8001" };

for development environment.

What is the step-by-step instruction to make this work on production environment for Kubernetes on Google (meaning no kubectl proxy workaround )

@brendandburns
Copy link
Contributor

You need to add code here:

https://github.com/kubernetes-client/csharp/blob/master/src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs#L240

That adds support for the GKE authProvider.

In truth, that code should really be abstracted out into a generic IAuthenticator interface that is then implemented by various authenticators. That's what we've done in other libraries, eg:

https://github.com/kubernetes-client/java/tree/master/util/src/main/java/io/kubernetes/client/util/authenticators

@cilerler
Copy link
Contributor Author

cilerler commented Dec 22, 2018

@brendanburns please do not close it.

This issue is a request for step-by-step instruction. Meaning someone who knows and understands Kubernetes, Kubernetes-Client and Google Cloud Kubernetes Engine should review it and document it.

Based on what you provided, I did add the code below

                if (userDetails.UserCredentials.AuthProvider.Name == "gcp" &&
                    userDetails.UserCredentials.AuthProvider.Config != null &&
                    userDetails.UserCredentials.AuthProvider.Config.ContainsKey("access-token"))
                {
                    var config = userDetails.UserCredentials.AuthProvider.Config;
                    const string keyExpire = "expiry";
                    if (config.ContainsKey(keyExpire))
                    {
                        if (DateTimeOffset.TryParse(config[keyExpire], out DateTimeOffset expires))
                        {
                            if (DateTimeOffset.Compare(expires, DateTimeOffset.Now) <= 0)
                            {
                                throw new KubeConfigException("Refresh not supported.");
                            }
                        }
                    }
                    AccessToken = config["access-token"];
                    userCredentialsFound = true;
                }

and ran the code below.

            var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
            IKubernetes client = new Kubernetes(config);
            Console.WriteLine("Starting Request!");

            var list = client.ListNamespacedPod("default");
            if (list == null)
            {
                throw new NotImplementedException();
            }
            foreach (var item in list.Items)
            {
                Console.WriteLine(item.Metadata.Name);
            }

            Console.ReadLine();

Unfortunately list returns null.

@cilerler
Copy link
Contributor Author

in here

    internal class WatcherDelegatingHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            var originResponse = await base.SendAsync(request, cancellationToken);

            if (originResponse.IsSuccessStatusCode)
            {
                var query = QueryHelpers.ParseQuery(request.RequestUri.Query);

                if (query.TryGetValue("watch", out var values) && values.Any(v => v == "true"))
                {
                    originResponse.Content = new LineSeparatedHttpContent(originResponse.Content);
                }
            }
            return originResponse;
        }

originalResponse returns as 401 Unauthorized

and request looks like this

image

And service account has the necessary permission

@brendandburns
Copy link
Contributor

That code looks correct. I suspect that your authentication token is expired or some such.

See the code here:
https://github.com/kubernetes-client/java/blob/master/util/src/main/java/io/kubernetes/client/util/authenticators/GCPAuthenticator.java#L44

For checking for expiration in Java.

If you want to track implementing auth for GKE, please file a separate issue (similar to #135 but for GKE auth)

I think that the code that you wrote above should be correct, but I don't have a GKE cluster to test on, I know that the Java code in GCPAuthenticator.java works correctly.

@cilerler
Copy link
Contributor Author

You were right. It is an expired token issue.

Upon your message, I ran kubectl get pods -n default from the command prompt to make sure it retrieves a valid token and then ran it through the library and it worked.. Thank you!

Since AKS refresh token is left as NotImplemented, I did the same thing for GKE and added a pull request so at least existing library supports both platform without refresh token parts now.

k8s-ci-robot pushed a commit that referenced this issue Dec 24, 2018
fixes #226

neither GCP one nor Azure one supports renew expired token feature
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants