Documentation
¶
Overview ¶
Package kubernetes contains interfaces and implementations for clients that talk directly to Kubernetes
Index ¶
- Constants
- Variables
- func GetComposedFieldOwner(obj *un.Unstructured) string
- type AccessChecker
- type ApplyClient
- type Clients
- type DefaultAccessClient
- type DefaultApplyClient
- type DefaultResourceClient
- func (c *DefaultResourceClient) GetGVKsForGroupKind(_ context.Context, group, kind string) ([]schema.GroupVersionKind, error)
- func (c *DefaultResourceClient) GetResource(ctx context.Context, gvk schema.GroupVersionKind, namespace, name string) (*un.Unstructured, error)
- func (c *DefaultResourceClient) GetResourcesByLabel(ctx context.Context, gvk schema.GroupVersionKind, namespace string, ...) ([]*un.Unstructured, error)
- func (c *DefaultResourceClient) IsNamespacedResource(_ context.Context, gvk schema.GroupVersionKind) (bool, error)
- func (c *DefaultResourceClient) ListResources(ctx context.Context, gvk schema.GroupVersionKind, namespace string) ([]*un.Unstructured, error)
- type DefaultSchemaClient
- func (c *DefaultSchemaClient) GetAllCRDs() []*extv1.CustomResourceDefinition
- func (c *DefaultSchemaClient) GetCRD(ctx context.Context, gvk schema.GroupVersionKind) (*extv1.CustomResourceDefinition, error)
- func (c *DefaultSchemaClient) GetCRDByName(name string) (*extv1.CustomResourceDefinition, error)
- func (c *DefaultSchemaClient) IsCRDRequired(ctx context.Context, gvk schema.GroupVersionKind) bool
- func (c *DefaultSchemaClient) LoadCRDsFromXRDs(ctx context.Context, xrds []*un.Unstructured) error
- type DefaultTypeConverter
- type ResourceClient
- type SchemaClient
- type TypeConverter
Constants ¶
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 ¶
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
func (c *DefaultAccessClient) Can(ctx context.Context, gvk schema.GroupVersionKind, namespace string, verb dtypes.Verb) (bool, string, error)
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
func (c *DefaultSchemaClient) GetAllCRDs() []*extv1.CustomResourceDefinition
GetAllCRDs returns all cached CRDs.
func (*DefaultSchemaClient) GetCRD ¶
func (c *DefaultSchemaClient) GetCRD(ctx context.Context, gvk schema.GroupVersionKind) (*extv1.CustomResourceDefinition, error)
GetCRD gets the CustomResourceDefinition for a given GVK.
func (*DefaultSchemaClient) GetCRDByName ¶ added in v0.2.0
func (c *DefaultSchemaClient) GetCRDByName(name string) (*extv1.CustomResourceDefinition, error)
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 ¶
func (c *DefaultTypeConverter) GVKToGVR(ctx context.Context, gvk schema.GroupVersionKind) (schema.GroupVersionResource, error)
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.