kubectl-utils/pkg/kube/client.go (72 lines of code) (raw):

// Copyright 2025 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package kube import ( "fmt" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) // Client is a facade around the various kube interfaces type Client struct { clientConfig clientcmd.ClientConfig DyanmicClient dynamic.Interface DiscoveryClient discovery.DiscoveryInterface } func NewClient(kubeconfig string) (*Client, error) { clientConfig, err := loadKubeconfig(kubeconfig) if err != nil { return nil, err } restConfig, err := clientConfig.ClientConfig() if err != nil { return nil, fmt.Errorf("building kubernetes API configuration: %w", err) } httpClient, err := rest.HTTPClientFor(restConfig) if err != nil { return nil, fmt.Errorf("building http client for rest config: %w", err) } dynamicClient, err := dynamic.NewForConfigAndClient(restConfig, httpClient) if err != nil { return nil, fmt.Errorf("building dynamic client: %w", err) } discoveryClient, err := buildDiscoveryClient(restConfig, httpClient) if err != nil { return nil, err } return &Client{ clientConfig: clientConfig, DyanmicClient: dynamicClient, DiscoveryClient: discoveryClient, }, nil } func loadKubeconfig(kubeconfigPath string) (clientcmd.ClientConfig, error) { rules := clientcmd.NewDefaultClientConfigLoadingRules() if kubeconfigPath != "" { rules.ExplicitPath = kubeconfigPath } clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( rules, &clientcmd.ConfigOverrides{}, ) return clientConfig, nil } func (c *Client) DefaultNamespace() (string, error) { ns, _, err := c.clientConfig.Namespace() if err != nil { return "", fmt.Errorf("getting namespace from kubeconfig: %w", err) } namespace := ns if namespace == "" { namespace = "default" } return namespace, nil } // ForGVR returns a dynamic client for the specified GroupVersionResource and namespace func (c *Client) ForGVR(gvr schema.GroupVersionResource, namespace string) dynamic.ResourceInterface { var client dynamic.ResourceInterface if namespace != "" { client = c.DyanmicClient.Resource(gvr).Namespace(namespace) } else { client = c.DyanmicClient.Resource(gvr) } return client }