Help us shape the future of Go! Take the 2026 Go Developer Survey

kubernetes

package
v0.11.0 Latest Latest
Warning

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

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

Documentation

Overview

Package kubernetes contains interfaces and implementations for clients that talk directly to Kubernetes

Index

Constants

View Source
const (
	// FieldOwnerComposedPrefix is the prefix for field owners of composed resources.
	// This matches Crossplane's FieldOwnerComposedPrefix in composition_functions.go.
	FieldOwnerComposedPrefix = "apiextensions.crossplane.io/composed"

	// FieldOwnerDefault is the default field owner when no specific owner is provided.
	FieldOwnerDefault = "crossplane-diff"
)

Variables

View Source
var ErrUnresolvableGVK = errors.New("cannot resolve resource type")

ErrUnresolvableGVK reports that a dry run never reached the apiserver because the object's group/version/kind could not be resolved to a resource at all.

It exists because the two failures are indistinguishable by error shape and must not be. Both dry-run methods resolve the GVK through discovery first, and a discovery 404 for an unserved group/version is apierrors-NotFound — exactly like NamespaceLifecycle refusing a resource whose type is perfectly fine. A caller inferring the cause from the apierrors shape alone would blame a missing namespace for a type that does not exist, sending the user after entirely the wrong root cause. Callers MUST test for this sentinel before classifying an error by its apierrors shape.

The gap is narrow but real: scope determination falls back to a CRD lookup when discovery fails, whereas GVKToGVR is discovery-only, so a CRD whose version is not `served` (or one created moments earlier, before discovery caught up) passes the earlier guards and fails here.

Functions

func GetComposedFieldOwner added in v0.5.0

func GetComposedFieldOwner(obj *un.Unstructured) string

GetComposedFieldOwner extracts the Crossplane composed resource field owner from an existing object's managedFields. Returns empty string if not found. This is used to ensure dry-run apply uses the same field owner as Crossplane, which correctly handles field removal detection.

Types

type AccessChecker added in v0.11.0

type AccessChecker interface {
	// Can reports whether the current credentials may perform verb on objects
	// of the given GVK in the given namespace (empty namespace for
	// cluster-scoped resources). When allowed is false, reason carries a
	// human-readable explanation suitable for display. A non-nil error means the
	// question could not be answered at all, which callers must treat as a tool
	// error rather than as a denial.
	Can(ctx context.Context, gvk schema.GroupVersionKind, namespace string, verb dtypes.Verb) (allowed bool, reason string, err error)
}

AccessChecker answers authorization questions about the current credentials.

func NewAccessClient added in v0.11.0

func NewAccessClient(clients *core.Clients, converter TypeConverter, logger logging.Logger) AccessChecker

NewAccessClient creates a new DefaultAccessClient.

type ApplyClient

type ApplyClient interface {
	// DryRunApply performs a dry-run server-side apply.
	// If fieldOwner is empty, uses the default field owner.
	DryRunApply(ctx context.Context, obj *un.Unstructured, fieldOwner string) (*un.Unstructured, error)

	// DryRunCreate performs a dry-run create, for resources that do not yet exist.
	DryRunCreate(ctx context.Context, obj *un.Unstructured) (*un.Unstructured, error)
}

ApplyClient handles server-side apply operations.

func NewApplyClient

func NewApplyClient(clients *core.Clients, converter TypeConverter, logger logging.Logger) ApplyClient

NewApplyClient creates a new DefaultApplyClient.

type Clients

type Clients struct {
	Access   AccessChecker
	Apply    ApplyClient
	Resource ResourceClient
	Schema   SchemaClient
	Type     TypeConverter
}

Clients is an aggregation of all of our Kubernetes clients, used to pass them as a bundle, typically for initialization where the consumer can select which ones they need.

type DefaultAccessClient added in v0.11.0

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

DefaultAccessClient implements AccessChecker via SelfSubjectAccessReview, memoizing each answer for the lifetime of the client.

func (*DefaultAccessClient) Can added in v0.11.0

Can reports whether the current credentials may perform verb on objects of the given GVK in the given namespace.

type DefaultApplyClient

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

DefaultApplyClient implements ApplyClient.

func (*DefaultApplyClient) DryRunApply

func (c *DefaultApplyClient) DryRunApply(ctx context.Context, obj *un.Unstructured, fieldOwner string) (*un.Unstructured, error)

DryRunApply performs a dry-run server-side apply. If fieldOwner is empty, uses the default field owner.

func (*DefaultApplyClient) DryRunCreate added in v0.11.0

func (c *DefaultApplyClient) DryRunCreate(ctx context.Context, obj *un.Unstructured) (*un.Unstructured, error)

DryRunCreate performs a dry-run create, so that a resource which does not yet exist in the cluster still picks up apiserver defaulting and admission before it is diffed.

Server-side apply cannot serve this path: DryRunApply issues a PUT-shaped request to a named path, and an addition that relies on metadata.generateName has no name yet - SSA has no generateName equivalent. Create is also the narrower permission ask (create alone, versus create+patch for a creating SSA apply) and the semantically correct primitive for "plan before apply".

There is deliberately no fieldOwner parameter. A brand-new object has no managedFields, so GetComposedFieldOwner has nothing to read; creates therefore always use FieldOwnerDefault. Do not reintroduce the parameter.

Errors are wrapped with errors.Wrapf, which is implemented as fmt.Errorf("...: %w", err) and therefore implements Unwrap. That is load bearing: callers discriminate outcomes with apierrors.IsInvalid, IsForbidden, IsAlreadyExists, IsInternalError, IsServiceUnavailable and IsTimeout, all of which reach the apiserver's APIStatus through errors.As and so need an unwrappable chain. Any replacement wrapper MUST also implement Unwrap.

type DefaultResourceClient

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

DefaultResourceClient implements the ResourceClient interface.

func (*DefaultResourceClient) GetGVKsForGroupKind

func (c *DefaultResourceClient) GetGVKsForGroupKind(_ context.Context, group, kind string) ([]schema.GroupVersionKind, error)

GetGVKsForGroupKind returns all available GroupVersionKinds for a given group and kind. It queries only the specified API group rather than all server APIs, avoiding issues with stale discovery data in unrelated API groups.

func (*DefaultResourceClient) GetResource

func (c *DefaultResourceClient) GetResource(ctx context.Context, gvk schema.GroupVersionKind, namespace, name string) (*un.Unstructured, error)

GetResource retrieves a resource from the cluster based on its GVK, namespace, and name.

func (*DefaultResourceClient) GetResourcesByLabel

func (c *DefaultResourceClient) GetResourcesByLabel(ctx context.Context, gvk schema.GroupVersionKind, namespace string, sel metav1.LabelSelector) ([]*un.Unstructured, error)

GetResourcesByLabel returns resources matching labels in the given namespace.

func (*DefaultResourceClient) IsNamespacedResource

func (c *DefaultResourceClient) IsNamespacedResource(_ context.Context, gvk schema.GroupVersionKind) (bool, error)

IsNamespacedResource determines if a given GVK represents a namespaced resource by querying the cluster's discovery API.

func (*DefaultResourceClient) ListResources

func (c *DefaultResourceClient) ListResources(ctx context.Context, gvk schema.GroupVersionKind, namespace string) ([]*un.Unstructured, error)

ListResources lists resources matching the given GVK and namespace.

type DefaultSchemaClient

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

DefaultSchemaClient implements SchemaClient.

func (*DefaultSchemaClient) GetAllCRDs added in v0.2.0

GetAllCRDs returns all cached CRDs.

func (*DefaultSchemaClient) GetCRD

GetCRD gets the CustomResourceDefinition for a given GVK.

func (*DefaultSchemaClient) GetCRDByName added in v0.2.0

GetCRDByName gets a CRD by its name from the cache. If the name is not found directly, it will also check if it's an XRD name that maps to a different CRD name (e.g., claim XRDs).

func (*DefaultSchemaClient) IsCRDRequired

func (c *DefaultSchemaClient) IsCRDRequired(ctx context.Context, gvk schema.GroupVersionKind) bool

IsCRDRequired checks if a GVK requires a CRD.

func (*DefaultSchemaClient) LoadCRDsFromXRDs added in v0.2.0

func (c *DefaultSchemaClient) LoadCRDsFromXRDs(ctx context.Context, xrds []*un.Unstructured) error

LoadCRDsFromXRDs fetches corresponding CRDs from the cluster for the given XRDs and caches them. Instead of converting XRDs to CRDs, this method fetches the actual CRDs that should already exist in the cluster since the Crossplane control plane manages both XRDs and their corresponding CRDs.

type DefaultTypeConverter

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

DefaultTypeConverter implements TypeConverter.

func (*DefaultTypeConverter) GVKToGVR

GVKToGVR converts a GroupVersionKind to a GroupVersionResource.

func (*DefaultTypeConverter) GetResourceNameForGVK

func (c *DefaultTypeConverter) GetResourceNameForGVK(_ context.Context, gvk schema.GroupVersionKind) (string, error)

GetResourceNameForGVK returns the resource name for a given GVK.

type ResourceClient

type ResourceClient interface {
	// GetResource retrieves a resource by its GVK, namespace, and name
	GetResource(ctx context.Context, gvk schema.GroupVersionKind, namespace, name string) (*un.Unstructured, error)

	// ListResources lists resources matching the given GVK and namespace
	ListResources(ctx context.Context, gvk schema.GroupVersionKind, namespace string) ([]*un.Unstructured, error)

	// GetResourcesByLabel returns resources matching labels in the given namespace
	GetResourcesByLabel(ctx context.Context, gvk schema.GroupVersionKind, namespace string, sel metav1.LabelSelector) ([]*un.Unstructured, error)

	// GetGVKsForGroupKind retrieves all GroupVersionKinds for a given group and kind
	GetGVKsForGroupKind(ctx context.Context, group, kind string) ([]schema.GroupVersionKind, error)

	// IsNamespacedResource determines if a given GVK represents a namespaced resource
	IsNamespacedResource(ctx context.Context, gvk schema.GroupVersionKind) (bool, error)
}

ResourceClient handles basic CRUD operations for Kubernetes resources.

func NewResourceClient

func NewResourceClient(clients *core.Clients, converter TypeConverter, logger logging.Logger) ResourceClient

NewResourceClient creates a new DefaultResourceClient instance.

type SchemaClient

type SchemaClient interface {
	// GetCRD gets the CustomResourceDefinition for a given GVK
	GetCRD(ctx context.Context, gvk schema.GroupVersionKind) (*extv1.CustomResourceDefinition, error)

	// GetCRDByName gets the CustomResourceDefinition by its name
	GetCRDByName(name string) (*extv1.CustomResourceDefinition, error)

	// IsCRDRequired checks if a GVK requires a CRD
	IsCRDRequired(ctx context.Context, gvk schema.GroupVersionKind) bool

	// LoadCRDsFromXRDs converts XRDs to CRDs and caches them
	LoadCRDsFromXRDs(ctx context.Context, xrds []*un.Unstructured) error

	// GetAllCRDs returns all cached CRDs (needed for external validation library)
	GetAllCRDs() []*extv1.CustomResourceDefinition
}

SchemaClient handles operations related to Kubernetes schemas and CRDs.

func NewSchemaClient

func NewSchemaClient(clients *core.Clients, typeConverter TypeConverter, logger logging.Logger) SchemaClient

NewSchemaClient creates a new DefaultSchemaClient.

type TypeConverter

type TypeConverter interface {
	// GVKToGVR converts a GroupVersionKind to a GroupVersionResource
	GVKToGVR(ctx context.Context, gvk schema.GroupVersionKind) (schema.GroupVersionResource, error)

	// GetResourceNameForGVK returns the resource name for a given GVK
	GetResourceNameForGVK(ctx context.Context, gvk schema.GroupVersionKind) (string, error)
}

TypeConverter provides conversion between Kubernetes types.

func NewTypeConverter

func NewTypeConverter(clients *core.Clients, logger logging.Logger) TypeConverter

NewTypeConverter creates a new DefaultTypeConverter.

Jump to

Keyboard shortcuts

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