Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/primitives/configmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,26 @@ func ChecksumAnnotationMutation(version, configHash string) deployment.Mutation
When the ConfigMap mutations change (version upgrade, feature toggle), `DesiredHash` returns a different value on the
same reconcile cycle, the pod template annotation changes, and Kubernetes triggers a rolling restart.

## Data Extraction

`configmap.ExtractInto` declares that this ConfigMap produces the value of a data cell, which is how a rendered
configuration value reaches the resources that consume it. The function receives a value copy of the reconciled
ConfigMap after each sync cycle:

```go
bootstrapServers := concepts.NewData[string]("bootstrap-servers")

builder := configmap.NewBuilder(base)
configmap.ExtractInto(builder, bootstrapServers, func(cm corev1.ConfigMap) (string, error) {
return cm.Data["bootstrap-servers"], nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(bootstrapServers)` or read it
opportunistically with `WithOptionalData(bootstrapServers)`. See [Declared Data](../component.md#declared-data).

## Full Example

```go
Expand Down
23 changes: 23 additions & 0 deletions docs/primitives/cronjob.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,29 @@ a plain function accepting `*cronjob.Mutator` and call it directly.

See [workload-kind-agnostic mutations](../primitives.md#workload-kind-agnostic-mutations) for the cross-kind pattern.

## Data Extraction

`cronjob.ExtractInto` declares that this CronJob produces the value of a data cell, which is how scheduling state
observed on the object reaches the resources that consume it. The function receives a value copy of the reconciled
CronJob after each sync cycle:

```go
lastSchedule := concepts.NewData[metav1.Time]("cleanup-last-schedule")

builder := cronjob.NewBuilder(base)
cronjob.ExtractInto(builder, lastSchedule, func(cj batchv1.CronJob) (metav1.Time, error) {
if cj.Status.LastScheduleTime == nil {
return metav1.Time{}, nil
}
return *cj.Status.LastScheduleTime, nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(lastSchedule)` or read it
opportunistically with `WithOptionalData(lastSchedule)`. See [Declared Data](../component.md#declared-data).

## Operational Status

`DefaultOperationalStatusHandler` always reports `Operational`. A CronJob is a passive scheduler: once it exists in the
Expand Down
19 changes: 19 additions & 0 deletions docs/primitives/daemonset.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,25 @@ agent.WithMutation(daemonset.LiftMutation(sharedAuthMutation()))

See [workload-kind-agnostic mutations](../primitives.md#workload-kind-agnostic-mutations) for the full pattern.

## Data Extraction

`daemonset.ExtractInto` declares that this DaemonSet produces the value of a data cell, such as how many nodes are
running a ready pod. The function receives a value copy of the reconciled DaemonSet after each sync cycle:

```go
readyNodes := concepts.NewData[int32]("collector-ready-nodes")

builder := daemonset.NewBuilder(base)
daemonset.ExtractInto(builder, readyNodes, func(ds appsv1.DaemonSet) (int32, error) {
return ds.Status.NumberReady, nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(readyNodes)` or read it
opportunistically with `WithOptionalData(readyNodes)`. See [Declared Data](../component.md#declared-data).

## Suspension

DaemonSets have no replicas field, so there is no clean in-place pause mechanism. By default, the DaemonSet is
Expand Down
19 changes: 19 additions & 0 deletions docs/primitives/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,25 @@ frontend.WithMutation(deployment.LiftMutation(sharedAuthMutation()))

See [workload-kind-agnostic mutations](../primitives.md#workload-kind-agnostic-mutations) for the full pattern.

## Data Extraction

`deployment.ExtractInto` declares that this Deployment produces the value of a data cell, such as the revision the
rollout landed on. The function receives a value copy of the reconciled Deployment after each sync cycle:

```go
revision := concepts.NewData[string]("web-server-revision")

builder := deployment.NewBuilder(base)
deployment.ExtractInto(builder, revision, func(d appsv1.Deployment) (string, error) {
return d.Annotations["deployment.kubernetes.io/revision"], nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(revision)` or read it
opportunistically with `WithOptionalData(revision)`. See [Declared Data](../component.md#declared-data).

## Suspension

When the component is suspended, the Deployment is scaled to zero replicas. The resource is not deleted.
Expand Down
20 changes: 20 additions & 0 deletions docs/primitives/hpa.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,26 @@ m.EditObjectMetadata(func(e *editors.ObjectMetaEditor) error {
})
```

## Data Extraction

`hpa.ExtractInto` declares that this HPA produces the value of a data cell, which is how the replica count the
autoscaler settled on reaches the resources that consume it. The function receives a value copy of the reconciled HPA
after each sync cycle:

```go
currentReplicas := concepts.NewData[int32]("backend-current-replicas")

builder := hpa.NewBuilder(base)
hpa.ExtractInto(builder, currentReplicas, func(h autoscalingv2.HorizontalPodAutoscaler) (int32, error) {
return h.Status.CurrentReplicas, nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(currentReplicas)` or read it
opportunistically with `WithOptionalData(currentReplicas)`. See [Declared Data](../component.md#declared-data).

## Operational Status

The default handler inspects `Status.Conditions`:
Expand Down
22 changes: 22 additions & 0 deletions docs/primitives/job.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,28 @@ function accepting `*job.Mutator` and call it directly.

See [workload-kind-agnostic mutations](../primitives.md#workload-kind-agnostic-mutations) for the cross-kind pattern.

## Data Extraction

`job.ExtractInto` declares that this Job produces the value of a data cell, such as how many pods have run to
completion. The function receives a value copy of the reconciled Job after each sync cycle:

```go
succeeded := concepts.NewData[int32]("migration-succeeded-pods")

builder := job.NewBuilder(base)
job.ExtractInto(builder, succeeded, func(j batchv1.Job) (int32, error) {
return j.Status.Succeeded, nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(succeeded)` or read it
opportunistically with `WithOptionalData(succeeded)`. See [Declared Data](../component.md#declared-data).

Guard on the Job's `Completable` status when a later resource must wait for the Job to finish. Data cells carry values
between resources; they are not a substitute for the completion condition.
Comment on lines +199 to +200

## Suspension

Jobs use the `Completable` lifecycle rather than `Alive`. The suspension behavior differs from Workload primitives:
Expand Down
19 changes: 19 additions & 0 deletions docs/primitives/pod.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,25 @@ m.EditObjectMetadata(func(e *editors.ObjectMetaEditor) error {
| `EnsureContainerArg(arg)` | `EditContainers(AllContainers(), ...)` → `EnsureArg(arg)` |
| `RemoveContainerArg(arg)` | `EditContainers(AllContainers(), ...)` → `RemoveArg(arg)` |

## Data Extraction

`pod.ExtractInto` declares that this Pod produces the value of a data cell, such as the address assigned to it by the
cluster. The function receives a value copy of the reconciled Pod after each sync cycle:

```go
agentIP := concepts.NewData[string]("agent-pod-ip")

builder := pod.NewBuilder(base)
pod.ExtractInto(builder, agentIP, func(p corev1.Pod) (string, error) {
return p.Status.PodIP, nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(agentIP)` or read it
opportunistically with `WithOptionalData(agentIP)`. See [Declared Data](../component.md#declared-data).

## Suspension

Pods cannot be paused. The default behavior deletes the pod when the component is suspended.
Expand Down
22 changes: 22 additions & 0 deletions docs/primitives/pv.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,28 @@ The `Mutator` exposes convenience wrappers for the most common PV spec operation
Use these for simple, single-operation mutations. Use `EditPVSpec` when you need multiple operations or raw access in a
single edit block.

## Data Extraction

`pv.ExtractInto` declares that this PersistentVolume produces the value of a data cell, such as the claim the volume was
bound to. The function receives a value copy of the reconciled PersistentVolume after each sync cycle:

```go
boundClaim := concepts.NewData[string]("data-volume-claim")

builder := pv.NewBuilder(base)
pv.ExtractInto(builder, boundClaim, func(v corev1.PersistentVolume) (string, error) {
if v.Spec.ClaimRef == nil {
return "", nil
}
return v.Spec.ClaimRef.Name, nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(boundClaim)` or read it
opportunistically with `WithOptionalData(boundClaim)`. See [Declared Data](../component.md#declared-data).

## Operational Status

The PV primitive implements `concepts.Operational`. The default handler maps PV phase to operational status:
Expand Down
19 changes: 19 additions & 0 deletions docs/primitives/replicaset.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,25 @@ that accepts `*replicaset.Mutator` and call it directly from a `replicaset.Mutat

See [workload-kind-agnostic mutations](../primitives.md#workload-kind-agnostic-mutations) for the cross-kind pattern.

## Data Extraction

`replicaset.ExtractInto` declares that this ReplicaSet produces the value of a data cell, such as the number of pods
reporting ready. The function receives a value copy of the reconciled ReplicaSet after each sync cycle:

```go
readyReplicas := concepts.NewData[int32]("worker-ready-replicas")

builder := replicaset.NewBuilder(base)
replicaset.ExtractInto(builder, readyReplicas, func(rs appsv1.ReplicaSet) (int32, error) {
return rs.Status.ReadyReplicas, nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(readyReplicas)` or read it
opportunistically with `WithOptionalData(readyReplicas)`. See [Declared Data](../component.md#declared-data).

## Suspension

When the component is suspended, the ReplicaSet is scaled to zero replicas. The resource is not deleted.
Expand Down
22 changes: 22 additions & 0 deletions docs/primitives/secret.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,28 @@ func ChecksumAnnotationMutation(version, secretHash string) deployment.Mutation
When the Secret mutations change (version upgrade, feature toggle), `DesiredHash` returns a different value on the same
reconcile cycle, the pod template annotation changes, and Kubernetes triggers a rolling restart.

## Data Extraction

`secret.ExtractInto` declares that this Secret produces the value of a data cell, which is how a generated credential
reaches the resources that need it. The function receives a value copy of the reconciled Secret after each sync cycle:

```go
password := concepts.NewData[string]("app-password")

builder := secret.NewBuilder(base)
secret.ExtractInto(builder, password, func(s corev1.Secret) (string, error) {
return string(s.Data["password"]), nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(password)` or read it
opportunistically with `WithOptionalData(password)`. See [Declared Data](../component.md#declared-data).

A cell extracted from a Secret holds the decoded plaintext for the rest of the reconcile. Use it to build the object you
are applying, and keep it out of conditions, events, and log lines.

## Full Example

```go
Expand Down
20 changes: 20 additions & 0 deletions docs/primitives/statefulset.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,26 @@ m.EnsureVolumeClaimTemplate(corev1.PersistentVolumeClaim{
such updates. The mutator silently skips these operations on existing StatefulSets (identified by a non-empty
`ResourceVersion`). Plan your storage layout before the first creation.

## Data Extraction

`statefulset.ExtractInto` declares that this StatefulSet produces the value of a data cell, such as the controller
revision the pods are currently running. The function receives a value copy of the reconciled StatefulSet after each
sync cycle:

```go
currentRevision := concepts.NewData[string]("db-current-revision")

builder := statefulset.NewBuilder(base)
statefulset.ExtractInto(builder, currentRevision, func(sts appsv1.StatefulSet) (string, error) {
return sts.Status.CurrentRevision, nil
})

resource, err := builder.Build()
```

Resources registered later in the same component block on the cell with `WithDataGuard(currentRevision)` or read it
opportunistically with `WithOptionalData(currentRevision)`. See [Declared Data](../component.md#declared-data).

## Suspension

When the component is suspended, the StatefulSet is scaled to zero replicas. The resource is not deleted.
Expand Down
20 changes: 20 additions & 0 deletions plugin/skills/using-primitives/references/primitives/configmap.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions plugin/skills/using-primitives/references/primitives/cronjob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions plugin/skills/using-primitives/references/primitives/daemonset.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading