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

Using the Helm SDK when no kubeconfig is available #7377

Open
Sh4d1 opened this issue Jan 10, 2020 · 42 comments · Fixed by #7373
Open

Using the Helm SDK when no kubeconfig is available #7377

Sh4d1 opened this issue Jan 10, 2020 · 42 comments · Fixed by #7373
Labels
feature help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.

Comments

@Sh4d1
Copy link
Contributor

Sh4d1 commented Jan 10, 2020

Currently when using helm SDK, a RESTClientGetter is needed. This is trivial when a kubeconfig file is available. However when the program only have access to the CA, token/certs and url in memory, it becomes a bit more complicated.

In fact the program needs to implement the following interfaces:

  • ToRESTConfig() (*rest.Config, error)
  • ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error)
  • ToRESTMapper() (meta.RESTMapper, error)

Of course it can still be done with some magic, but then it is also needed to create a new abstraction over the namespace with the ToRawKubeConfigLoader() method.

A fix would be to add a Namespace field to the kube client in order to lighten a bit the custom implementation written to use Helm3 without a kubeconfig

@mmellison
Copy link

Likewise, most of our apps have a reference to *rest.Config but not much else. It's easy to implement all of the given interfaces except ToRawKubeConfigLoader.

I think simpler initialization would help reduce the barrier to entry on getting started with the SDK.

@bacongobbler
Copy link
Member

How does this differ from #7135? If they are the same feature request, can you please close one to keep the conversation in one ticket? Thanks!

@Sh4d1
Copy link
Contributor Author

Sh4d1 commented Jan 15, 2020

@bacongobbler its not the same. #7135 is about the Namespace flag on the different actions. This one is about an easier use of the sdk when no kubeconfig is available

@mmellison
Copy link

Is there a reason this was closed? Unless I'm mistaken, I don't see how #7373 addresses this in any way?

I think the intention of this issue was that it requires a lot of boilerplate to set up the Helm SDK in an environment where a standard kubeconfig doesn't exist, and so it would be a huge benefit to have an easier way to bootstrap the SDK.

@bacongobbler
Copy link
Member

Merging #7373 automatically closes this issue as @Sh4d1 mentioned “Fixes #7377 (kind of)”. GitHub checks for the presence of “closes” or “fixes” proceeded by an issue number to mark issues as automatically closed once the PR is merged.

Re-opening.

@bacongobbler bacongobbler reopened this Feb 11, 2020
@bacongobbler bacongobbler changed the title Over engineering when using Helm SDK without a kubeconfig Using the Helm SDK when no kubeconfig is available Jun 3, 2020
@bacongobbler
Copy link
Member

Is anyone planning to work on this, or shall I close this one out as inactive? Haven't seen any activity on this ticket for months.

@mmellison
Copy link

We're still looking forward to improvements made in this area. Checking out the latest improvements made to the Helm SDK and upgrading to the latest 3.x version is near the top of our backlog.

I will report back soon.

@bacongobbler
Copy link
Member

We're still looking forward to improvements made in this area.

There have been no changes to this particular area of the code, which is why I'm reaching out.

I am asking if anyone from the community has looked into submitting a pull request to help improve this area, or if anyone may be able provide more insight on how they worked around this in their own projects.

Marking this as "help wanted" to signify that we aren't looking into this, but we are looking for guidance from the community to help make improvements in this area of the code, either in the form of pull requests or documentation.

@bacongobbler bacongobbler added the help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. label Jun 3, 2020
@lemonli
Copy link
Contributor

lemonli commented Jun 4, 2020

@bacongobbler I am interested on this. I have used the helm SDK with token/cert as auth-info instead of kubeconfig in our project to manage multi-cluster helm.
Please assign me?

@vadasambar
Copy link

I was looking into the codebase for the places where the RESTClientGetter interface is being used and if we could get rid of it altogether and convert it into rest.Config and use that everywhere in the client sdk code , like a native kubernetes go client (one you create using client go library) and possibly everywhere else as well.

Something like

  • Helm cli reads kubeconfig -> Helm code converts it into rest.Config -> Passes it to the helm sdk
  • Code using helm sdk creates/gets rest.Config -> Passes it to the helm sdk

Places where RESTClientGetter is used

Interface

type RESTClientGetter interface {
	// ToRESTConfig returns restconfig
	ToRESTConfig() (*rest.Config, error) // NO NEED
	// ToDiscoveryClient returns discovery client
	ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error)
	// ToRESTMapper returns a restmapper
	ToRESTMapper() (meta.RESTMapper, error) // NOT USED ANYWHERE
	// ToRawKubeConfigLoader return kubeconfig loader as-is
	ToRawKubeConfigLoader() clientcmd.ClientConfig
}

ToDiscoveryClient()

dc, err := c.RESTClientGetter.ToDiscoveryClient()

// helm/pkg/action/action.go:237
237: // capabilities builds a Capabilities from discovery information.
238: func (c *Configuration) getCapabilities() (*chartutil.Capabilities, error) {
239: 	if c.Capabilities != nil {
240: 		return c.Capabilities, nil
241: 	}
242: 	dc, err := c.RESTClientGetter.ToDiscoveryClient()
243: 	if err != nil {
244: 		return nil, errors.Wrap(err, "could not get Kubernetes discovery client")
245: 	}

discoveryClient, err := i.cfg.RESTClientGetter.ToDiscoveryClient()

// helm/pkg/action/install.go:149
149: 		// Invalidate the local cache, since it will not have the new CRDs
150: 		// present.
151: 		discoveryClient, err := i.cfg.RESTClientGetter.ToDiscoveryClient()
152: 		if err != nil {
153: 			return err
154: 		}

We might need to implement a function that returns discoveryClient ourselves.

ToRawKubeConfigLoader()

if ns, _, err := s.config.ToRawKubeConfigLoader().Namespace(); err == nil {

// helm/pkg/cli/environment.go:148
148: // Namespace gets the namespace from the configuration
149: func (s *EnvSettings) Namespace() string {
150: 	if ns, _, err := s.config.ToRawKubeConfigLoader().Namespace(); err == nil {
151: 		return ns
152: 	}
153: 	return "default"
154: }

if ns, _, err := c.Factory.ToRawKubeConfigLoader().Namespace(); err == nil {

// helm/pkg/kube/client.go:130
130: func (c *Client) namespace() string {
131: 	if c.Namespace != "" {
132: 		return c.Namespace
133: 	}
134: 	if ns, _, err := c.Factory.ToRawKubeConfigLoader().Namespace(); err == nil {
135: 		return ns
136: 	}
137: 	return v1.NamespaceDefault
138: }

If we could find a way to get the namespace through some other way (maybe store it in some struct or allow it to be passed as a parameter), we can get rid of ToRawKubeConfigLoader().

ToRawKubeConfigLoader() clientcmd.ClientConfig

// helm/pkg/kube/factory.go:28
28: type Factory interface {
29: 	// ToRawKubeConfigLoader return kubeconfig loader as-is
30: 	ToRawKubeConfigLoader() clientcmd.ClientConfig
31: 	// KubernetesClientSet gives you back an external clientset
32: 	KubernetesClientSet() (*kubernetes.Clientset, error)

Same here. If ToRawKubeConfigLoader is only being used for getting the namespace, we should be able to get rid of this method altogether (unless I am missing something).

From my limited knowledge of the codebase, I think if we make the above changes, we should be able to get rid of the RESTClientGetter interface and use the rest.Config instead.

Note

  • If there are other places where the methods are being used, like if the RESTClientGetter is required for some library function which is outside Helm codebase, then we might have a problem.
  • I have a limited understanding of the codebase and I might be completely wrong in some places.

I am interested in this issue as well @bacongobbler. Maybe @lemonli and I can work on this together.

@github-actions
Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Nov 27, 2020
@mitar
Copy link

mitar commented Nov 29, 2020

Unstale.

@github-actions github-actions bot removed the Stale label Nov 30, 2020
@pytimer
Copy link

pytimer commented Dec 29, 2020

I use the helm sdk in my program, now i want to use rest.Config not kubeconfig, i already implement RESTClientGetter interface.
But ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) function return CachedDiscoveryInterface struct, i want not use cached, whether the helm sdk support discovery.DiscoveryInterface ?

@github-actions
Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Mar 30, 2021
@mitar
Copy link

mitar commented Mar 30, 2021

Unstale.

@github-actions github-actions bot removed the Stale label Mar 31, 2021
@github-actions
Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Jun 30, 2021
@mitar
Copy link

mitar commented Jul 15, 2021

Unstale.

@github-actions github-actions bot removed the Stale label Jul 16, 2021
@github-actions github-actions bot added the Stale label Nov 10, 2022
@mitar
Copy link

mitar commented Nov 10, 2022

Unstale.

@github-actions github-actions bot removed the Stale label Nov 11, 2022
@Segflow
Copy link

Segflow commented Dec 21, 2022

We are also waiting for a fix for this

@github-actions
Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Mar 22, 2023
@mitar
Copy link

mitar commented Mar 22, 2023

Unstale.

@github-actions github-actions bot removed the Stale label Mar 23, 2023
@github-actions
Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Jun 21, 2023
@mitar
Copy link

mitar commented Jun 21, 2023

Unstale.

@github-actions github-actions bot removed the Stale label Jun 22, 2023
@github-actions
Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Sep 21, 2023
@mitar
Copy link

mitar commented Sep 21, 2023

Unstale.

@github-actions github-actions bot removed the Stale label Sep 22, 2023
@dayeguilaiye
Copy link

dayeguilaiye commented Oct 27, 2023

Unstale.

I am facing the same problem now.

We have created a rest.Config from env/kubeconfig/userInput in the beginning of the program. Now we have to pass the kubeconfig file to other modules because helm SDK need it (While we already pass the rest.Config).

But it seems that helm client only need rest.Config and namespace info, the kubeconfig file itself is not necessary.

Is it possible to provide a function like NewRESTClientGetterFromConfig(cfg rest.Config, namespace string) RESTClientGetter ?

Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Jan 26, 2024
@mitar
Copy link

mitar commented Jan 26, 2024

Unstale.

@github-actions github-actions bot removed the Stale label Jan 27, 2024
Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Apr 26, 2024
@mitar
Copy link

mitar commented Apr 27, 2024

Unstale.

@github-actions github-actions bot removed the Stale label Apr 28, 2024
Copy link

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Jul 28, 2024
@mitar
Copy link

mitar commented Jul 28, 2024

Unstale.

@github-actions github-actions bot removed the Stale label Jul 29, 2024
@johnwrobinson
Copy link

Has there been any movement on this? I'd also like this feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.
Projects
None yet
Development

Successfully merging a pull request may close this issue.