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

Proposal: kubelogin library usage #373

Closed
bcho opened this issue Dec 12, 2023 · 3 comments · Fixed by #386
Closed

Proposal: kubelogin library usage #373

bcho opened this issue Dec 12, 2023 · 3 comments · Fixed by #386
Assignees
Labels
enhancement New feature or request

Comments

@bcho
Copy link
Member

bcho commented Dec 12, 2023

This proposal provides an overview of enabling kubelogin to be used as a library.

Background

There are a few asks on importing kubelogin as library from both internal and external users. The latest one is #371. Here is a list of known library imports (ref):

The original design of kubelogin is to be consumed as a command line tool via the external credentials provider protocol. However, for 3rd party Kubernetes DevOps services, it's a common task to embed the same authentication flow into the product without the need of downloading kubelogin binary. In this case, we should enable the 3rd party service to import kubelogin as a library.

There are a few blockers for enabling this usage:

  • getToken call is not being exposed
  • TokenProvider is returning legacy adal.Token object
  • token.Options exposes CLI usage settings

getToken call is not being exposed

The most needed feature is to generate a token using user environment input. We can do it via getToken call. However, this function is private to 3rd party library usage. We should expose this function along with the options structure.

TokenProvider is returning legacy adal.Token object

Even though kubelogin is making use of azidentity internally, for local caching compatibility, the getToken function and TokenProvider interface are still returning the legacy adal.Token object. To avoid introducing legacy dependencies to 3rd party services, we should not expose this legacy interface anymore. Ideally, a string only representation should be used instead of pinning on a specific Azure SDK version as his approach can decouple the dependencies.

token.Options exposes CLI usage settings

The current Options struct contains a long list of fields, some of them are for configuring CLI behavior, for example: TokenCacheDir). To avoid exposing unnecessary details, library usage should not allow users to consume these fields.

Proposal

Goals

The goals for library mode as follow:

  • CLI and library mode implementations stay in the same repository: all kubelogin related code should stay under the Azure/kubelogin repository.
  • Minimum export for library usage: to reduce the risk of future breaking changes and implementations lock in, we aim to introduce minimum data structures and functions for library usage. Other CLI or internal implementations should not be importable by 3rd party libraries. If more features are needed, we can export more in the future.

Overview

We propose to convert the kubelogin module into this new project layout:

image

Implementations under the "exposed for library usage" section can be imported. Example usages:

GetAccessToken

package mypackage

import (
  "context"
  "fmt"  
  
  "github.com/Azure/kubelogin/pkg/token"
)

func RequestAzureAccessToken(ctx context.Context) (string, error) {
  options, err := token.OptionsWithEnv() // we will also provide Options() for minimum usage
  if err != nil {
    return "", fmt.Errorf("OptionsWithEnv: %w", err)
  }

  // adjust options as needed

  tokenProvider, err := token.GetTokenProvider(options)
  if err != nil {
    return "", fmt.Errorf("GetTokenProvider: %w", err)
  }

  accessToken, err := tokenProvider.GetAccessToken(ctx)
  if err != nil {
    return "", fmt.Errorf("GetAccessToken: %w", err)
  }

  return accessToken, nil  
}

Compatibility

Library users are expected to use the pkg/token.Options object for configuring the token retrieval behavior. This object will be converted into internal data models (for example, pkg/internal/token.Options). Hence, there is no backward compatibility issue for this change. For future extension, we can add new optional fields to this object. This approach provides forward compatibility.

Misc: Caching

Caching functionality is designed for CLI usage. In library mode, this functionality will be disabled by default. Library users can implement their own caching solution. If there is high demand for caching support, we can still expose it to library consumers in the future.

Conversion Steps

We expect to implement this change in following phases:

  1. Move current sub folders under pkg to pkg/internal
  2. Move root level main entry to cmd/kubelogin package
  3. Update the internal TokenProvider interface to return library agnostic token interface
  4. Define root level TokenOptions object and export required types and constants
  5. Implement library usages and adjust internal implementations as needed
  6. Bump kubelogin version following semantic version best practice

Migration Steps For Existing Libraries

  • For crossplane's usage, we will convert it to the GetAccessToken example above.
  • For argo-cd's usage, we will convert it to use a new implementation as GetAccessToken example above, then dump to output using formatJSON function.
@bcho bcho added the enhancement New feature or request label Dec 12, 2023
@bcho bcho self-assigned this Dec 12, 2023
@bcho
Copy link
Member Author

bcho commented Dec 18, 2023

Giving no comments / objects raised in the past week, I will consider this proposal as accepted. Will work on this change this week.

@bcho
Copy link
Member Author

bcho commented Dec 20, 2023

PR for argo-cd: argoproj/argo-cd#16661
PR for crossplane-helm: crossplane-contrib/provider-helm#207

@bcho
Copy link
Member Author

bcho commented Jan 17, 2024

Closing this as we have published the library mode. Will continue work on the integration.

@bcho bcho closed this as completed Jan 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant