Documentation
¶
Overview ¶
pkg/kubeclient/context.go
pkg/kubeclient/dynamic.go
pkg/kubeclient/genericclient.go
pkg/kubeclient/kubeclient.go
pkg/kubeclient/patch_status.go
pkg/kubeclient/provider.go
Index ¶
- Constants
- func NewFakeClientset() kubernetes.Interface
- func WithKubeclient(ctx context.Context, kube KubeClient) context.Context
- type CRDInfo
- type Client
- func (c *Client) List(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error)
- func (c *Client) ListInNamespace(ctx context.Context, namespace string, opts metav1.ListOptions) (runtime.Object, error)
- func (c *Client) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
- func (c *Client) WatchInNamespace(ctx context.Context, namespace string, opts metav1.ListOptions) (watch.Interface, error)
- type ClientFactory
- type ClientProvider
- type DynamicListerWatcher
- type KubeClient
- type Kubeclient
- func (k *Kubeclient) ApiextensionsClient() apiextclientset.Interface
- func (k *Kubeclient) Clientset() kubernetes.Interface
- func (k *Kubeclient) Create(ctx context.Context, obj sigs.Object) error
- func (k *Kubeclient) DynamicClient() dynamic.Interface
- func (k *Kubeclient) DynamicClientFor(apiPath, group, version string) (dynamic.Interface, error)
- func (k *Kubeclient) Get(ctx context.Context, namespace, name string, into sigs.Object) error
- func (k *Kubeclient) Mapper() meta.RESTMapper
- func (k *Kubeclient) Name() string
- func (k *Kubeclient) NewClient(objList runtime.Object, info CRDInfo) (*Client, error)
- func (k *Kubeclient) NewClientProvider() *ClientProvider
- func (k *Kubeclient) NewDynamicListerWatcher(info CRDInfo, opts ListOptions) cache.ListerWatcher
- func (k *Kubeclient) Patch(ctx context.Context, obj sigs.Object, patch Patch) error
- func (k *Kubeclient) PatchAnnotations(ctx context.Context, obj runtime.Object, annotations map[string]string) error
- func (k *Kubeclient) PatchFinalizers(ctx context.Context, obj runtime.Object, finalizers []string) error
- func (k *Kubeclient) PatchLabels(ctx context.Context, obj runtime.Object, base, desired map[string]string) error
- func (k *Kubeclient) PatchSpec(ctx context.Context, obj domain.Object, specFields map[string]interface{}) error
- func (k *Kubeclient) PatchStatus(ctx context.Context, obj domain.Object, statusFields map[string]interface{}) error
- func (k *Kubeclient) RefreshMapper()
- func (k *Kubeclient) RestClientFor(apiPath, group, version string) (*rest.RESTClient, error)
- func (k *Kubeclient) RestConfig() *rest.Config
- func (k *Kubeclient) RuntimeParameterCodec() runtime.ParameterCodec
- func (k *Kubeclient) Scheme() *runtime.Scheme
- func (k *Kubeclient) SharedClientFactory(apiPath, group, version string) (*rest.RESTClient, error)
- func (k *Kubeclient) Shutdown(ctx context.Context)
- func (k *Kubeclient) Start(ctx context.Context) error
- func (k *Kubeclient) Started() bool
- type ListOptions
- type Patch
Constants ¶
const ContextKey contextKey = "orkestra-kubeclient"
ContextKey is the key used to store and retrieve a KubeClient from a context.
Usage — inject before calling hooks:
ctx = kubeclient.WithKubeclient(ctx, kube)
Usage — retrieve in hook/registry functions:
kube, ok := kubeclient.FromContext(ctx)
Variables ¶
This section is empty.
Functions ¶
func WithKubeclient ¶
func WithKubeclient(ctx context.Context, kube KubeClient) context.Context
WithKubeclient returns a new context with the KubeClient stored under ContextKey. Called in GenericReconciler.Reconcile before invoking hook and registry functions.
Types ¶
type CRDInfo ¶
type CRDInfo struct {
Kind string // Required by Registry
Group string // Required if GroupVersion is not specified
Version string // Required if GroupVersion is not specified
GroupVersion *schema.GroupVersion // Optional (can be used if Group and Version are not specified)
GroupVersionKind schema.GroupVersionKind // Useful for some manipulations
GroupVersionResource schema.GroupResource
Plural string
Namespaced bool // Required for cluster-scoped resources
APIPath string
Namespace string
}
CRDInfo defines what a CRD is
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client definition
func (*Client) List ¶
A generic client should know how to List and Watch just as the dynamic client List returns runtime.Object - exactly what GenericClient needs!
func (*Client) ListInNamespace ¶ added in v0.2.5
func (c *Client) ListInNamespace(ctx context.Context, namespace string, opts metav1.ListOptions) (runtime.Object, error)
ListInNamespace lists resources scoped to the given namespace. Used by the Tier 1 namespace filter when allowedNamespaces has exactly one entry.
func (*Client) WatchInNamespace ¶ added in v0.2.5
func (c *Client) WatchInNamespace(ctx context.Context, namespace string, opts metav1.ListOptions) (watch.Interface, error)
WatchInNamespace watches resources scoped to the given namespace. Used by the Tier 1 namespace filter when allowedNamespaces has exactly one entry.
type ClientFactory ¶
type ClientFactory func(*Kubeclient) (informer.GenericClient, error)
ClientFactory accepts kubeclient and returns a generic client The generic client is the hallmark of the whole design konstructRuntime() performs per CRD registration and hands over to ghe informer factory
type ClientProvider ¶
type ClientProvider struct {
// contains filtered or unexported fields
}
ClientProvider definition for registering new clients
func (*ClientProvider) For ¶
func (p *ClientProvider) For(obj runtime.Object) (informer.GenericClient, error)
For returns a generic client for a registered object
func (*ClientProvider) Register ¶
func (p *ClientProvider) Register(obj runtime.Object, factory ClientFactory)
Register adds a new object to clients
type DynamicListerWatcher ¶
type DynamicListerWatcher struct {
// contains filtered or unexported fields
}
DynamicListerWatcher implements cache.ListerWatcher using the dynamic client. Safe to construct before kube.Start() — k.dynamic is resolved at call time.
func (*DynamicListerWatcher) List ¶
func (d *DynamicListerWatcher) List(options metav1.ListOptions) (runtime.Object, error)
List implements cache.ListerWatcher. *unstructured.UnstructuredList satisfies runtime.Object — explicit cast needed because dynamic.ResourceInterface.List returns the concrete type, not the interface.
func (*DynamicListerWatcher) Watch ¶
func (d *DynamicListerWatcher) Watch(options metav1.ListOptions) (watch.Interface, error)
Watch implements cache.ListerWatcher.
type KubeClient ¶ added in v0.4.8
type KubeClient interface {
Clientset() kubernetes.Interface
DynamicClient() dynamic.Interface
Mapper() meta.RESTMapper
// CRUD — typed object operations for constructor reconcilers.
// Accepts sigs.k8s.io/controller-runtime/pkg/client.Object so reconcilers
// migrated from controller-runtime compile without changes to their call sites.
// GVR is derived from the Go type via the scheme and mapper; callers do not
// need to specify it explicitly.
Get(ctx context.Context, namespace, name string, into sigs.Object) error
Create(ctx context.Context, obj sigs.Object) error
Patch(ctx context.Context, obj sigs.Object, patch Patch) error
// Patch helpers — used by the generic reconciler for finalizer, label,
// annotation, and status updates. Implementations must be idempotent.
PatchFinalizers(ctx context.Context, obj runtime.Object, finalizers []string) error
PatchLabels(ctx context.Context, obj runtime.Object, base, desired map[string]string) error
PatchAnnotations(ctx context.Context, obj runtime.Object, annotations map[string]string) error
PatchStatus(ctx context.Context, obj domain.Object, statusFields map[string]interface{}) error
}
KubeClient is the interface every registry function depends on. *Kubeclient satisfies this with real clients. *simulate.FakeKubeclient satisfies this with k8s.io/client-go/kubernetes/fake.
func FromContext ¶
func FromContext(ctx context.Context) (KubeClient, bool)
FromContext retrieves the KubeClient from a context. Returns (nil, false) if not present.
type Kubeclient ¶
type Kubeclient struct {
Info *CRDInfo
// Testing
FakeClientset kubernetes.Interface
// contains filtered or unexported fields
}
Kubeclient defines what a kube client is
func NewForTesting ¶ added in v0.3.7
NewForTesting builds a Kubeclient wired to the given REST config without going through Start(). Used exclusively by integration tests that provide their own envtest config.
func NewKubeclient ¶
func NewKubeclient(kfg *konfig.Konfig, scheme *runtime.Scheme) *Kubeclient
----------------------------------------------------------------------------- Entry point ----------------------------------------------------------------------------- NewKubeclient returns a new Kubeclient with the correct scheme
func (*Kubeclient) ApiextensionsClient ¶
func (k *Kubeclient) ApiextensionsClient() apiextclientset.Interface
ApiextensionsClient returns the apiextensions clientset for CRD operations.
func (*Kubeclient) Clientset ¶
func (k *Kubeclient) Clientset() kubernetes.Interface
Clientset returns the kubernetes interface
func (*Kubeclient) Create ¶ added in v0.7.7
Create creates obj in the cluster. Derives the API group and resource from the Go type via the scheme and mapper.
func (*Kubeclient) DynamicClient ¶
func (k *Kubeclient) DynamicClient() dynamic.Interface
Dynamic returns yhe dynamic interface. Useful in 'dynamic' reconciler mode
func (*Kubeclient) DynamicClientFor ¶
func (k *Kubeclient) DynamicClientFor(apiPath, group, version string) (dynamic.Interface, error)
On-demand dynamic client
func (*Kubeclient) Get ¶ added in v0.7.7
Get fetches the object identified by namespace/name into into. Derives the API group and resource from the Go type via the scheme and mapper.
func (*Kubeclient) Mapper ¶ added in v0.4.6
func (k *Kubeclient) Mapper() meta.RESTMapper
func (*Kubeclient) Name ¶
func (k *Kubeclient) Name() string
Name returns the name of the kubeclient
func (*Kubeclient) NewClientProvider ¶
func (k *Kubeclient) NewClientProvider() *ClientProvider
NewClientProvider creates a new provider with the passed in kubeclient At this stage, it only accepts the kubeclient and created the clients map This is because kube is not live yet
func (*Kubeclient) NewDynamicListerWatcher ¶
func (k *Kubeclient) NewDynamicListerWatcher(info CRDInfo, opts ListOptions) cache.ListerWatcher
NewDynamicListerWatcher builds a cache.ListerWatcher for an unstructured CRD. Safe to call before kube.Start() — dynamic client is resolved lazily.
func (*Kubeclient) Patch ¶ added in v0.7.7
Patch applies patch to obj in the cluster. The patch body and type are computed by calling patch.Data(obj). Use kubeclient.MergeFrom or kubeclient.StrategicMergeFrom to build the patch, or pass sigs.MergeFrom / sigs.StrategicMergeFrom directly — they satisfy Patch.
func (*Kubeclient) PatchAnnotations ¶
func (k *Kubeclient) PatchAnnotations( ctx context.Context, obj runtime.Object, annotations map[string]string, ) error
PatchAnnotations merges annotations onto the object by sending a JSON Merge Patch containing only the desired annotation keys. Keys present in annotations are added or updated on the server; keys absent from the patch are left unchanged (not deleted).
This is intentionally a one-way merge: Orkestra's annotation management only ever adds keys (managed-by and managed-since are write-once and never removed). If key deletion is ever needed, mirror the base/desired pattern used by [PatchLabels].
func (*Kubeclient) PatchFinalizers ¶
func (k *Kubeclient) PatchFinalizers( ctx context.Context, obj runtime.Object, finalizers []string, ) error
PatchFinalizers replaces the object's finalizer list with finalizers by sending a minimal JSON Merge Patch that touches only metadata.finalizers. Sending only the changed field avoids resourceVersion conflicts that would arise from patching the full object.
func (*Kubeclient) PatchLabels ¶
func (k *Kubeclient) PatchLabels( ctx context.Context, obj runtime.Object, base, desired map[string]string, ) error
PatchLabels transitions the object's labels from base to desired by sending a JSON Merge Patch. Keys present in base but absent in desired are set to null so the server deletes them. Keys in desired that differ from base are added or updated. Unchanged keys are omitted from the patch body.
base must be a snapshot of the labels as they exist on the server immediately before any in-memory mutations are applied (the controller-runtime MergeFrom pattern). Pass nil for base when the object is brand-new and has no labels.
func (*Kubeclient) PatchSpec ¶
func (k *Kubeclient) PatchSpec( ctx context.Context, obj domain.Object, specFields map[string]interface{}, ) error
pkg/kubeclient/patch_spec.go
func (*Kubeclient) PatchStatus ¶
func (k *Kubeclient) PatchStatus( ctx context.Context, obj domain.Object, statusFields map[string]interface{}, ) error
PatchStatus applies a merge patch to the /status subresource of a CR.
statusFields is the map of status fields to set — it is merged into the existing status, not replaced entirely. Fields not present in statusFields are left untouched.
The patch is applied to the /status subresource, which requires the CRD to declare:
spec:
versions:
- name: v1
subresources:
status: {} # ← this enables the status subresource
If the CRD does not declare a status subresource, the API server returns a 404 "the server could not find the requested resource". Callers should treat this as a non-fatal condition — the CRD simply does not support status updates.
PatchStatus uses merge patch (application/merge-patch+json) rather than strategic merge patch. Merge patch is simpler and sufficient for status updates — we are setting top-level status fields, not merging lists.
Example statusFields:
{
"conditions": [{"type": "Ready", "status": "True", ...}],
"observedGeneration": 3,
"phase": "Running",
"endpoint": "my-site.default.svc.cluster.local"
}
The API server wraps this in {"status": <statusFields>} before applying. Callers pass only the status contents — not the "status" wrapper key.
func (*Kubeclient) RefreshMapper ¶ added in v0.4.6
func (k *Kubeclient) RefreshMapper()
RefreshMapper forces the deferred mapper to refresh its discovery cache. Call this after creating or updating CRDs so RESTMapping will pick them up.
func (*Kubeclient) RestClientFor ¶
func (k *Kubeclient) RestClientFor(apiPath, group, version string) (*rest.RESTClient, error)
On-demand rest client
func (*Kubeclient) RestConfig ¶
func (k *Kubeclient) RestConfig() *rest.Config
RestConfig returns the rest confif for the kube client
func (*Kubeclient) RuntimeParameterCodec ¶
func (k *Kubeclient) RuntimeParameterCodec() runtime.ParameterCodec
func (*Kubeclient) Scheme ¶
func (k *Kubeclient) Scheme() *runtime.Scheme
Scheme returns the runtime scheme for yhe kubeclient
func (*Kubeclient) SharedClientFactory ¶
func (k *Kubeclient) SharedClientFactory(apiPath, group, version string) (*rest.RESTClient, error)
SharedClientFactory provides a simple way to build clients from config
func (*Kubeclient) Shutdown ¶
func (k *Kubeclient) Shutdown(ctx context.Context)
Shutdown is called by orkestra fir graceful shutdown
func (*Kubeclient) Start ¶
func (k *Kubeclient) Start(ctx context.Context) error
Start is called by orkestra.Start() to start kube client
func (*Kubeclient) Started ¶
func (k *Kubeclient) Started() bool
Started is called by orkestra for healthcheck
type ListOptions ¶
type Patch ¶ added in v0.7.7
Patch is sigs.k8s.io/controller-runtime/pkg/client.Patch, re-exported so constructor reconcilers only need to import this package. Values produced by sigs.MergeFrom, sigs.StrategicMergeFrom, and sigs.Apply satisfy this type directly — no adapter or wrapper needed when migrating from controller-runtime.
func MergeFrom ¶ added in v0.7.7
MergeFrom returns a JSON Merge Patch (RFC 7396) from base to the modified object passed to kube.Patch. Call before mutating the object:
patch := kubeclient.MergeFrom(existing.DeepCopy()) existing.Spec = desired.Spec return kube.Patch(ctx, existing, patch)
Use for CRDs and any object where replace semantics are correct. For core Kubernetes types with list merge keys, prefer StrategicMergeFrom.
Delegates to sigs.k8s.io/controller-runtime/pkg/client.MergeFrom — the sigs version works here directly if you already import controller-runtime.
func StrategicMergeFrom ¶ added in v0.7.7
StrategicMergeFrom returns a Strategic Merge Patch for core Kubernetes types (Deployment, DaemonSet, StatefulSet, etc.) that carry patchMergeKey annotations. The API server merges list entries by key (e.g. containers by name) rather than replacing the entire list. For CRDs, use MergeFrom — the API server has no schema knowledge for custom types.
Delegates to sigs.k8s.io/controller-runtime/pkg/client.StrategicMergeFrom — the sigs version works here directly if you already import controller-runtime.