client

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README

pkg/k8s/client

Initialises the Kubernetes client pair (typed clientset + dynamic client) the rest of pkg/k8s and pkg/controller depend on.

Overview

Watchers and resource loaders need both a typed kubernetes.Interface (for built-in resources) and a dynamic.Interface (for CRDs that aren't in the typed scheme). *Client wraps both behind one struct and handles in-cluster vs. kubeconfig discovery, plus best-effort detection of the controller's own namespace from the service-account token mount.

Quick Start

import "github.com/haproxy-haptic/HAPTIC/pkg/k8s/client"

// In-cluster (the production path)
c, err := client.New(client.Config{})

// Out-of-cluster (development)
c, err = client.New(client.Config{
    Kubeconfig: "/path/to/kubeconfig",
    Namespace:  "default", // empty = auto-detect from /var/run/secrets/.../namespace
})
if err != nil { /* ... */ }

// Typed clientset
pods, _ := c.Clientset().CoreV1().Pods("default").List(ctx, metav1.ListOptions{})

// Dynamic client for CRDs not in the typed scheme
gvr := schema.GroupVersionResource{Group: "haproxy-haptic.org", Version: "v1alpha1", Resource: "haproxytemplateconfigs"}
list, _ := c.DynamicClient().Resource(gvr).Namespace(c.Namespace()).List(ctx, metav1.ListOptions{})

The Config struct has four fields (Kubeconfig, Namespace, QPS, Burst). QPS <= 0 (the default) disables client-side throttling — New sets rest.Config.QPS = -1 — so the controller relies on the apiserver's Priority & Fairness (APF). Unlike the client-side token bucket, which blocks a throttled request until the caller's context expires, APF returns 429 + Retry-After, which client-go retries. A positive QPS reinstates a client-side cap installed as one shared flowcontrol RateLimiter on the rest.Config, so every clientset derived from it — the core clientset, the dynamic client, and any versioned/apiext client built via NewForConfig(RestConfig()) — draws from a single controller-wide budget rather than a private bucket each (Burst defaults to 2*QPS when zero). The controller wires this from --kube-client-qps/--kube-client-burst (env KUBE_CLIENT_QPS/KUBE_CLIENT_BURST, chart value controller.kubeClient.qps/.burst). NewFromClientset builds a *Client from existing fakes — used by tests only.

Other Exported Surfaces

Symbol Purpose
(*Client).RestConfig() *rest.Config Underlying *rest.Config for callers that need to build their own client variants (e.g. metrics/v1 clients in tests).
(*Client).GetResource(ctx, gvr, name) (*unstructured.Unstructured, error) Convenience wrapper around DynamicClient().Resource(gvr).Namespace(c.Namespace()).Get(...) — saves a line in CRD lookups.
DiscoverNamespace() (string, error) Reads the namespace from DefaultNamespaceFile (the standard /var/run/secrets/.../namespace path). Used by New when Config.Namespace is empty.
DiscoverNamespaceFromFile(path) (string, error) Same, but lets tests point at a fixture path.
DefaultNamespaceFile The constant /var/run/secrets/kubernetes.io/serviceaccount/namespace — exported so callers can compare or override in tests.
*ClientError / *NamespaceDiscoveryError Typed errors. Both implement Unwrap() so errors.Is/errors.As walks through to the underlying cause; use these to distinguish "couldn't reach the cluster" from "couldn't discover the namespace from the SA token mount".

See Also

  • pkg/k8s/watcher — wraps *Client to deliver typed change callbacks
  • pkg/k8s/store — backing storage for watcher results
  • client.go — Config field semantics and the in-cluster vs kubeconfig discovery rules

License

Apache-2.0 — see root LICENSE.

Documentation

Overview

Package client provides a wrapper around the Kubernetes client-go library.

This package simplifies Kubernetes client creation and provides utilities for common operations like namespace discovery.

Index

Constants

View Source
const (
	// DefaultNamespaceFile is the standard location for the service account namespace.
	DefaultNamespaceFile = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
)

Variables

This section is empty.

Functions

func DiscoverNamespace

func DiscoverNamespace() (string, error)

DiscoverNamespace reads the current namespace from the service account token.

Returns:

  • The namespace string
  • An error if the namespace cannot be discovered

The namespace is read from /var/run/secrets/kubernetes.io/serviceaccount/namespace which is automatically mounted in pods by Kubernetes.

func DiscoverNamespaceFromFile

func DiscoverNamespaceFromFile(path string) (string, error)

DiscoverNamespaceFromFile reads the namespace from the specified file. This is primarily useful for testing.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client wraps a Kubernetes clientset with additional utilities.

func New

func New(cfg Config) (*Client, error)

New creates a new Kubernetes client with the provided configuration.

If Config.Kubeconfig is empty, uses in-cluster configuration. If Config.Namespace is empty, discovers namespace from service account token.

Example:

// k8sClient avoids shadowing the imported `client` package; this is
// the convention used throughout pkg/controller (see iteration.go).

// In-cluster client
k8sClient, err := client.New(client.Config{})

// Out-of-cluster client
k8sClient, err = client.New(client.Config{
    Kubeconfig: "/path/to/kubeconfig",
    Namespace:  "default",
})

func NewFromClientset

func NewFromClientset(clientset kubernetes.Interface, dynamicClient dynamic.Interface, namespace string) *Client

NewFromClientset creates a Client from an existing Kubernetes clientset. This is useful for testing with fake clients.

func (*Client) Clientset

func (c *Client) Clientset() kubernetes.Interface

Clientset returns the underlying Kubernetes clientset.

func (*Client) DynamicClient

func (c *Client) DynamicClient() dynamic.Interface

DynamicClient returns the underlying dynamic client.

func (*Client) GetResource

GetResource fetches a specific Kubernetes resource by name in the client's namespace.

The resource is fetched from the client's default namespace (auto-detected from service account or specified during client creation).

Parameters:

  • ctx: Context for cancellation and timeout
  • gvr: GroupVersionResource identifying the resource type
  • name: Name of the specific resource to fetch

Returns:

  • The resource as an unstructured.Unstructured object
  • An error if the resource cannot be fetched

Example:

// Fetch a ConfigMap; k8sClient is a *Client from client.New(...).
gvr := schema.GroupVersionResource{
    Group:    "",
    Version:  "v1",
    Resource: "configmaps",
}
cm, err := k8sClient.GetResource(ctx, gvr, "my-config")

func (*Client) ListResources

func (c *Client) ListResources(ctx context.Context, gvr schema.GroupVersionResource, labelSelector string) (*unstructured.UnstructuredList, error)

ListResources returns every object of gvr in the client's namespace matching labelSelector (empty selects all).

An error is returned rather than an empty list for any failure, including a 403: callers that treat "found nothing" as a legitimate state cannot otherwise distinguish it from "was not allowed to look".

func (*Client) Namespace

func (c *Client) Namespace() string

Namespace returns the default namespace for this client.

func (*Client) RestConfig

func (c *Client) RestConfig() *rest.Config

RestConfig returns the underlying REST configuration.

type ClientError

type ClientError struct {
	Operation string
	Cause     error
}

ClientError represents errors that occur during Kubernetes client operations.

func (*ClientError) Error

func (e *ClientError) Error() string

func (*ClientError) Unwrap

func (e *ClientError) Unwrap() error

type Config

type Config struct {
	// Kubeconfig path for out-of-cluster configuration.
	// If empty, uses in-cluster configuration.
	Kubeconfig string

	// Namespace is the default namespace for operations.
	// If empty, will be discovered from service account.
	Namespace string

	// QPS is the client-side apiserver rate limit. Zero or negative disables
	// client-side throttling so the controller relies on the apiserver's
	// Priority & Fairness (the default; see New). A positive value reinstates a
	// client-side cap shared across every derived clientset.
	QPS float32

	// Burst is the token-bucket burst; used only when QPS is positive. Zero
	// falls back to 2*QPS.
	Burst int
}

Config contains configuration options for creating a Kubernetes client.

type NamespaceDiscoveryError

type NamespaceDiscoveryError struct {
	Path  string
	Cause error
}

NamespaceDiscoveryError represents errors that occur during namespace discovery.

func (*NamespaceDiscoveryError) Error

func (e *NamespaceDiscoveryError) Error() string

func (*NamespaceDiscoveryError) Unwrap

func (e *NamespaceDiscoveryError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL