Skip to content

Updated authentication for Kubernetes #186

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

Merged

Conversation

Bobbins228
Copy link
Contributor

@Bobbins228 Bobbins228 commented Jun 28, 2023

Update authentication for Kubernetes

references #185
#146
A user can now authenticate using their own k8s config file.

A user can authenticate with their token and server address.

All methods that used config.load_kube_config() have been updated to check if a user has already specified their own config file so it isn't overridden.

How to test the new authentication methods

git pull https://github.com/Bobbins228/codeflare-sdk.git
git checkout update-authentication
Run poetry build within the codeflare-sdk folder to build your own wheel.
Install the sdk with pip install codeflare_sdk-0.0.0.dev0-py3-none-any.whl
Import the necessary classes.

# Import pieces from codeflare-sdk
from codeflare_sdk.cluster.cluster import Cluster, ClusterConfiguration
from codeflare_sdk.cluster.auth import TokenAuthentication, KubeConfigFileAuthentication

Loading a user's own config file

auth = KubeConfigFileAuthentication(
            kube_config_path="/path/to/config"
        )
auth.load_kube_config()

Authenticating with token + server

Authenticating with certificate

auth = TokenAuthentication(
    token = "TOKEN",
    server = "SERVER",
    skip_tls=False,
    ca_cert_path="path/to/ca_bundle.crt"
)
auth.login()

Authenticating by skipping tls verification

auth = TokenAuthentication(
    token = "TOKEN",
    server = "SERVER",
    skip_tls=True
)
auth.login()

Logging out
auth.logout()

@Bobbins228
Copy link
Contributor Author

I have changed how the login works by using the kubernetes API to handle an authenticated user. This is independent of whether a user has a loaded config file already.

When a user logs out the default config file is loaded again.

Copy link
Collaborator

@Maxusmusti Maxusmusti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, just a few questions and nits to start

@carsonmh
Copy link
Contributor

Tested this out and works as expected. LGTM!

@Bobbins228 Bobbins228 force-pushed the update-authentication branch from cb3d49a to dc4acc7 Compare July 14, 2023 11:45
Copy link
Collaborator

@Maxusmusti Maxusmusti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick issue I noticed when testing. This is the current behavior when namespace cannot be found:

  • get_current_namespace() returns: "Unable to find current namespace please specify with namespace=<your_current_namespace>"
  • ClusterConfiguration() (without setting namespace) works and generates yaml when passed into cluster with namespace=Unable to find current namespace please specify with namespace=<your_current_namespace>

What we want is probably something more along the lines of:

  • get_current_namespace() returns None in that case and prints a message like "Unable to find current namespace"
  • Cluster(ClusterConfiguration() fails if the namespace in the configuration is set to None, and tells the user "Unable to find current namespace, please specify in your ClusterConfiguration with namespace=<your_current_namespace>"

@Maxusmusti
Copy link
Collaborator

So like after line 71 in cluster.py just check if namespace is still None, and if so then fail with that message

Copy link
Collaborator

@MichaelClifford MichaelClifford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks very good 👍

One thing though that is something of a simple change but, will impact a lot of the implementation. 😬

Can we make api_config_handler() and config_check() generic auth functions instead of class methods? It looks odd to invoke both authentication type classes on every call, especially when a users should only ever be using one anyways.

Is there any reason we can't separate these from the classes?

Copy link
Collaborator

@MichaelClifford MichaelClifford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes! :)

LGTM

Copy link
Collaborator

@Maxusmusti Maxusmusti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything seemed to work great, except one critical edge case:

  • When doing a token login, I can just pass in no token at all (or no server), and it leads to all sorts of broken behavior (those should not have defaults)
  • Also, when I pass in an incorrect token, it will still tell me I've "logged in", only to fail later down the line

Also, how are you obtaining/generating the ca cert that you are passing in when testing the Token approach? I'd like to test that as well, have just been testing with tls-skip for now.

EDIT: Realized if you're on RHEL the default path is probably where your ca cert bundle is, not sure how to do it on mac os though...

@Bobbins228
Copy link
Contributor Author

Everything seemed to work great, except one critical edge case:

  • When doing a token login, I can just pass in no token at all (or no server), and it leads to all sorts of broken behavior (those should not have defaults)
  • Also, when I pass in an incorrect token, it will still tell me I've "logged in", only to fail later down the line

Also, how are you obtaining/generating the ca cert that you are passing in when testing the Token approach? I'd like to test that as well, have just been testing with tls-skip for now.

EDIT: Realized if you're on RHEL the default path is probably where your ca cert bundle is, not sure how to do it on mac os though...

That was a great catch about default values for the token. I'll update the PR.
Yeah the default path is where the ca cert bundle is for RHEL and Openshift.

@Bobbins228
Copy link
Contributor Author

Looking into how we can pass an incorrect token and catch that and there doesn't seem to be any errors for when you set up the configuration even with bad credentials. Only when the api instance is used will an error be thrown e.g.cluster.up().

I found this, we can call get_api_group() to test if the credentials are correct and add in an error if that fails.

@Maxusmusti
Copy link
Collaborator

@Bobbins228 the get_api_group solution seems great to me!

Copy link
Collaborator

@Maxusmusti Maxusmusti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Maxusmusti Maxusmusti merged commit 2ced60d into project-codeflare:k8s-support Jul 20, 2023
Maxusmusti added a commit that referenced this pull request Jul 20, 2023
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 this pull request may close these issues.

4 participants