Documentation
¶
Overview ¶
Package object turns the kernel's compiled output into Kubernetes objects and holds the Kubernetes facts about them that every frontend shares. It is part of the Kubernetes tier beside the kernel: the kernel never imports it, a depguard rule in .golangci.yml keeps it that way, and a frontend that applies to Kubernetes uses it instead of a copy of its own.
Resource wraps one kernel.Compiled: the rendered CUE value with its instance, component and transformer provenance, and best-effort accessors for the fields Kubernetes addresses an object by. NewResource and Resources build it from the kernel's output.
A Resource holds its CUE value, and a CUE value pins the whole build it came from (holder-bounded: it lives as long as the caller holds it). A long-lived caller exports its Resources once and drops them; the library never drops them for it. Export is that one export: it exports each Resource from CUE exactly once and hands back, index-aligned, the JSON bytes, the object decoded from those same bytes and the provenance, so a digest, the apply objects and the inventory entries all read one result and nothing exports twice.
Weight is the kind-class order every Kubernetes frontend applies by: definitions before their users on apply, the reverse on delete (0012:D5). It agrees with the staged apply order of Flux's ssa package wherever Flux orders two kinds, so an engine that applies through Flux only refines it. Sort orders by it, and Stages cuts an apply set into stages: the cluster definitions, then one stage per weight.
Duplicates finds rendered objects that share one Kubernetes apply identity, so a runtime can refuse the render instead of letting the last write silently overwrite the first. Two objects with the same API group, kind, namespace and name reach apply as two writes to one object, whatever version of the group each names. Nothing in the kernel notices: kernel.Compiled deliberately carries no platform vocabulary, and Render never reads kind or metadata. Duplicates takes the render's compiled objects and returns every identity two or more of them share, each row naming the identity and every producing component and transformer in render order. It reads exactly four fields off each value (apiVersion, kind, metadata.namespace, metadata.name) and validates nothing else. A value with no kind or no metadata.name is not a Kubernetes object: it is skipped, never refused, because a frontend that requires manifests already fails at conversion with a better message. DuplicateIdentitiesError turns the rows into the refusal itself, worded once so every runtime says the same thing. A runtime calls it between render and apply, on the []*kernel.Compiled the kernel returned: the cli in its render workflow, so build refuses what apply would, and the operator before it builds inventory entries. The deprecated opm/helper/objectset holds an identical copy until both frontends have moved here.
Index ¶
- Constants
- func Sort[T any](items []T, gvkOf func(T) schema.GroupVersionKind, dir Direction)
- func Weight(gvk schema.GroupVersionKind) int
- type Direction
- type Duplicate
- type DuplicateIdentitiesError
- type ExportError
- type ExportStep
- type Exported
- type Identity
- type Producer
- type Resource
- func (r *Resource) APIVersion() string
- func (r *Resource) Annotations() map[string]string
- func (r *Resource) GVK() schema.GroupVersionKind
- func (r *Resource) Kind() string
- func (r *Resource) Labels() map[string]string
- func (r *Resource) MarshalJSON() ([]byte, error)
- func (r *Resource) Name() string
- func (r *Resource) Namespace() string
- func (r *Resource) String() string
- func (r *Resource) ToUnstructured() (*unstructured.Unstructured, error)
- type Stage
Constants ¶
const ( WeightCRD = -100 WeightNamespace = 0 WeightClusterRole = 5 WeightClass = 6 WeightStorageClass = WeightClass WeightClusterRoleBinding = 7 WeightResourceQuota = 8 WeightServiceAccount = 10 WeightRole = 10 WeightRoleBinding = 10 WeightSecret = 15 WeightConfigMap = 15 WeightService = 50 WeightLimitRange = 60 WeightDeployment = 100 WeightStatefulSet = 100 WeightCronJob = 105 WeightPDB = 108 WeightDefault = 1000 WeightWebhook = 2000 // The kinds below are not in Flux's ReconcileOrder, so they weigh // WeightDefault. The names stay for the callers that use them. WeightPersistentVolume = WeightDefault WeightPVC = WeightDefault WeightDaemonSet = WeightDefault WeightJob = WeightDefault WeightIngress = WeightDefault WeightNetworkPolicy = WeightDefault WeightHPA = WeightDefault WeightVPA = WeightDefault )
Kind-class ordering weights for Kubernetes apply and delete. Lower weights are applied first and deleted last (0012:D5). They follow Flux's staged apply order: the cluster definitions, then the class kinds, then Flux's ReconcileOrder. Every kind Flux does not list weighs WeightDefault, so Flux's alphabetical fallback among those kinds only refines the order.
Variables ¶
This section is empty.
Functions ¶
func Sort ¶
func Sort[T any](items []T, gvkOf func(T) schema.GroupVersionKind, dir Direction)
Sort orders items in place by Weight of each item's GVK, read through gvkOf. The sort is stable: items of equal weight keep their relative order.
func Weight ¶
func Weight(gvk schema.GroupVersionKind) int
Weight returns the ordering weight for a GVK. Lower weights are applied first. The lookup follows Flux's staged apply: the entry for the exact group, version and kind; else a cluster definition (a CustomResourceDefinition of apiextensions.k8s.io, a core Namespace or a ClusterRole of rbac.authorization.k8s.io) by group and kind in any version; else the entry for the kind alone, where a definition's kind name in another group weighs WeightClass; else WeightClass for any kind whose name ends in "Class" (case-sensitive, as Flux's class stage is); else WeightDefault.
Types ¶
type Direction ¶
type Direction int
Direction selects ascending (apply) or descending (delete) weight order.
type Duplicate ¶
Duplicate is one apply identity that two or more rendered objects share, with every producer of it in render order. Identity is the first-rendered object's, its APIVersion verbatim.
func Duplicates ¶
Duplicates scans a render's compiled objects and returns every apply identity two or more of them share, in the order each identity was first rendered. Two objects share an apply identity when their API group (the part of apiVersion before the first "/", empty for the core group and for an object with no apiVersion), kind, namespace and name match; the version does not distinguish them, because the API server serves one object under every version of its group. A value carrying no kind or no metadata.name is not a Kubernetes object and is skipped; nothing else about the objects is validated. A render whose objects all have distinct identities returns no rows.
type DuplicateIdentitiesError ¶
type DuplicateIdentitiesError struct {
Duplicates []Duplicate
}
DuplicateIdentitiesError is the refusal a runtime raises from the rows Duplicates returned, before apply. The kernel never returns it: it is raised by the frontend that calls the check.
func (*DuplicateIdentitiesError) Error ¶
func (e *DuplicateIdentitiesError) Error() string
Error names each shared identity once, on its own line, with every component and transformer that produced it, so one wording serves every runtime that applies to Kubernetes. When a row's producers rendered the object under different apiVersions, each producer is followed by its own version, so the reader sees the mismatch that made them one object.
type ExportError ¶
type ExportError struct {
// Index is the failing Resource's position in the input.
Index int
// Resource is the failing Resource's String().
Resource string
// Step is the step that failed.
Step ExportStep
// Err is the cause.
Err error
}
ExportError is the failure of Export for one Resource: its position in the input, its summary, the step that failed and the cause.
func (*ExportError) Error ¶
func (e *ExportError) Error() string
Error names the resource, its position and the step.
type ExportStep ¶
type ExportStep int
ExportStep names the step of Export that failed.
const ( // ExportMarshal is the CUE export: the value would not export to JSON. ExportMarshal ExportStep = iota // ExportDecode is the decode: the JSON would not decode to an object. ExportDecode )
func (ExportStep) String ¶
func (s ExportStep) String() string
String returns "cue export" or "json decode".
type Exported ¶
type Exported struct {
// JSON is the CUE export of the value, field order as CUE emits it.
JSON []byte
// Object is decoded from JSON, not exported again. Object.Object is
// never nil.
Object *unstructured.Unstructured
// Instance, Component and Transformer are the Resource's provenance.
Instance string
Component string
Transformer string
}
Exported is one Resource after its single export: the JSON bytes CUE emitted, the object decoded from those same bytes, and the provenance. It holds no CUE value, so it does not pin the build.
func Export ¶
Export exports each resource from CUE exactly once, in input order, and returns one Exported per input, index-aligned. Each object is decoded from the bytes of that one export. A value whose JSON is not an object (a list, a string or null) fails at ExportDecode. Export stops at the first failure and returns an *ExportError.
Export never changes or drops its input. The caller drops its Resources after the export to release the CUE build they pin. A nil Resource in the input, or one with no CUE value, fails at ExportMarshal.
type Identity ¶
Identity names a rendered object by its apiVersion, kind, namespace and name. Namespace is empty for a cluster-scoped object, or for one that names no namespace. A Kubernetes apply addresses an object by group, kind, namespace and name, so two identities that differ only in the version part of APIVersion address one object; Duplicates matches them on the group.
type Producer ¶
Producer is the (component, transformer) pair the kernel recorded on a rendered object, with that object's own apiVersion. Within one row the producers' APIVersion values differ when one object was rendered under two versions of its group.
type Resource ¶
type Resource struct {
// Value is the CUE value of the rendered object (e.g. a Kubernetes
// manifest). Concrete and fully evaluated: safe to encode to JSON.
Value cue.Value
// Instance is the name of the ModuleInstance that produced this object.
Instance string
// Component is the source component name within the instance.
Component string
// Transformer is the FQN of the transformer that produced this object.
Transformer string
}
Resource is a single rendered object with its provenance. It is the Kubernetes wrapper of a kernel.Compiled, field for field.
Value holds the raw CUE output from a transformer, avoiding premature conversion to Go-native formats. Callers convert to the format they need (JSON, *unstructured.Unstructured) only when needed, through Export or the conversion methods.
A Resource keeps its whole CUE build alive for as long as it is held. A long-lived caller exports and then drops its Resources.
func NewResource ¶
NewResource wraps one compiled object, copying its value and provenance. A nil input yields a nil result.
func (*Resource) APIVersion ¶
APIVersion returns the object's apiVersion (e.g. "apps/v1"), or "" when absent.
func (*Resource) Annotations ¶
Annotations returns the object's metadata.annotations, or nil when absent or not a map of strings.
func (*Resource) GVK ¶
func (r *Resource) GVK() schema.GroupVersionKind
GVK returns the GroupVersionKind parsed from apiVersion and kind.
func (*Resource) Labels ¶
Labels returns the object's metadata.labels, or nil when absent or not a map of strings.
func (*Resource) MarshalJSON ¶
MarshalJSON returns the JSON form of the resource's CUE value. Each call exports the value from CUE again; a caller that needs the bytes and the object uses Export, which exports once.
func (*Resource) Namespace ¶
Namespace returns the object's metadata.namespace. Empty for a cluster-scoped object or one that names no namespace.
func (*Resource) String ¶
String returns a human-readable summary: "Kind/namespace/name", or "Kind/name" when there is no namespace.
func (*Resource) ToUnstructured ¶
func (r *Resource) ToUnstructured() (*unstructured.Unstructured, error)
ToUnstructured converts the resource to a *unstructured.Unstructured, with JSON as the intermediate format. It exports from CUE on every call.
type Stage ¶
type Stage[T any] struct { // ClusterDefinitions marks the stage that holds the CustomResourceDefinitions // and core Namespaces. A frontend waits for them (a CRD to be Established) // before it applies the next stage, whose objects may need them. ClusterDefinitions bool // Items are the stage's objects in stable [Sort] order. Items []T }
Stage is one apply stage: the objects a frontend submits in one call to its apply engine before it moves on to the next stage.
func Stages ¶
func Stages[T any](items []T, gvkOf func(T) schema.GroupVersionKind) []Stage[T]
Stages returns a sorted copy of items cut into apply stages. The cluster definitions (every CustomResourceDefinition of apiextensions.k8s.io and every Namespace of the core group) come first as one stage, omitted when there are none. Then comes one stage per distinct Weight of the remaining items, in ascending weight. Order within a stage is the stable sort order. The input slice is not reordered, and no stage is empty.
The definition stage spans two weights, -100 and 0, and Flux's order also puts a CustomResourceDefinition before a Namespace. The Weight table agrees with the staged apply order of Flux's ssa package wherever that orders two kinds, so an engine that re-sorts with Flux's order can take the whole set or any one stage in a call and only refine the library's order, never contradict it (0012:D5:R1).