Documentation
¶
Overview ¶
Package v1alpha1 holds the CRD types for ferrflow.io/v1alpha1 — the FerrFlow-Operator's first API version. The `v1alpha1` suffix advertises that field names and semantics may still change before we promote to v1.
Index ¶
- Constants
- Variables
- type FerrFlowConnection
- type FerrFlowConnectionList
- type FerrFlowConnectionSpec
- type FerrFlowConnectionStatus
- type FerrFlowSecret
- type FerrFlowSecretList
- type FerrFlowSecretSpec
- type FerrFlowSecretStatus
- type LocalObjectReference
- type OIDCAuth
- type SecretKeyRef
- type SecretSelector
- type SecretTarget
- type SecretTransform
- type WorkloadRef
Constants ¶
const DefaultAudience = "https://ferrflow.com"
DefaultAudience matches the FerrFlow API's `EXPECTED_AUDIENCE` constant. Changing this is a coordinated breaking change across both repos.
const DefaultTokenPath = "/var/run/secrets/ferrflow/token"
DefaultTokenPath is where kubelet mounts the projected SA token in our sample Deployment. Exposed so both the controllers and the chart share a single source of truth.
Variables ¶
var AddToScheme = SchemeBuilder.AddToScheme
AddToScheme is the canonical entry point used by cmd/main.go.
var GroupVersion = schema.GroupVersion{Group: "ferrflow.io", Version: "v1alpha1"}
GroupVersion is the API group/version pair the controller watches.
var SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
SchemeBuilder registers the package's types with the runtime scheme so that the manager can encode/decode them and the informers can list/watch them.
Functions ¶
This section is empty.
Types ¶
type FerrFlowConnection ¶
type FerrFlowConnection struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FerrFlowConnectionSpec `json:"spec,omitempty"`
Status FerrFlowConnectionStatus `json:"status,omitempty"`
}
FerrFlowConnection is the Schema for the ferrflowconnections API.
func (*FerrFlowConnection) DeepCopy ¶
func (in *FerrFlowConnection) DeepCopy() *FerrFlowConnection
DeepCopy returns a deep copy of the receiver.
func (*FerrFlowConnection) DeepCopyInto ¶
func (in *FerrFlowConnection) DeepCopyInto(out *FerrFlowConnection)
DeepCopyInto copies the receiver into out.
func (*FerrFlowConnection) DeepCopyObject ¶
func (in *FerrFlowConnection) DeepCopyObject() runtime.Object
DeepCopyObject implements runtime.Object.
type FerrFlowConnectionList ¶
type FerrFlowConnectionList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FerrFlowConnection `json:"items"`
}
FerrFlowConnectionList contains a list of FerrFlowConnection.
func (*FerrFlowConnectionList) DeepCopy ¶
func (in *FerrFlowConnectionList) DeepCopy() *FerrFlowConnectionList
DeepCopy returns a deep copy of the receiver.
func (*FerrFlowConnectionList) DeepCopyInto ¶
func (in *FerrFlowConnectionList) DeepCopyInto(out *FerrFlowConnectionList)
DeepCopyInto copies the receiver into out.
func (*FerrFlowConnectionList) DeepCopyObject ¶
func (in *FerrFlowConnectionList) DeepCopyObject() runtime.Object
DeepCopyObject implements runtime.Object.
type FerrFlowConnectionSpec ¶
type FerrFlowConnectionSpec struct {
// URL is the base of the FerrFlow API — e.g. `https://ferrflow.example.com`.
// The operator appends `/api/v1/…` paths itself.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:Pattern=`^https?://`
URL string `json:"url"`
// Organization is the FerrFlow org slug this connection targets. Every
// `FerrFlowSecret` referencing this connection resolves `project` and
// `vault` inside this org.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Organization string `json:"organization"`
// TokenSecretRef points at a Kubernetes Secret holding a FerrFlow
// authentication token — `ffclust_...` (cluster identity) or `fft_...`
// (user API token, org-scoped, discouraged).
//
// Kept for **air-gapped clusters** where FerrFlow cannot reach the
// cluster's OIDC JWKS endpoint, and for **non-Kubernetes callers**.
// When FerrFlow can reach the cluster, prefer `oidc` — no secret at
// rest, short-lived tokens, automatic rotation.
//
// +optional
TokenSecretRef *SecretKeyRef `json:"tokenSecretRef,omitempty"`
// OIDC enables workload-identity authentication: the operator presents
// its projected ServiceAccount token to FerrFlow, which validates it
// against the cluster's registered OIDC config and mints a short-lived
// bearer. No long-lived secret on the cluster side, revocation is
// instant on the FerrFlow side.
//
// Requires the FerrFlow cluster resource to be pre-configured with
// OIDC (`PUT /orgs/:org/clusters/:id/oidc` on the FerrFlow API), and
// the operator pod to have a projected SA token volume mounted at
// `oidc.tokenPath` with audience matching `oidc.audience`.
//
// +optional
OIDC *OIDCAuth `json:"oidc,omitempty"`
}
FerrFlowConnectionSpec declares how to reach a FerrFlow API instance and which organization the operator should scope its reads to. A single `FerrFlowConnection` object is typically shared by multiple `FerrFlowSecret` objects in the same namespace — users create one per (cluster, org) pair.
Exactly one authentication source must be set: either `tokenSecretRef` (long-lived token stored in a k8s Secret) or `oidc` (workload-identity exchange — recommended, no long-lived secret at rest).
func (*FerrFlowConnectionSpec) DeepCopyInto ¶
func (in *FerrFlowConnectionSpec) DeepCopyInto(out *FerrFlowConnectionSpec)
DeepCopyInto for the spec — pointer fields (TokenSecretRef, OIDC) are the reason we need a real deep copy here instead of the shallow `= *in`. Shallow would share the inner struct between receivers of the deep copy, which breaks the "caller can mutate without affecting the source" invariant that the Kubernetes controller-runtime relies on.
type FerrFlowConnectionStatus ¶
type FerrFlowConnectionStatus struct {
// Conditions follows the upstream `metav1.Condition` convention. The
// primary condition is `Ready` — `True` when the token authenticates and
// the `secrets:read` scope is present.
//
// +optional
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions,omitempty"`
// LastCheckedAt is the timestamp of the most recent auth probe.
//
// +optional
LastCheckedAt *metav1.Time `json:"lastCheckedAt,omitempty"`
}
FerrFlowConnectionStatus reports the outcome of the most recent probe against the configured FerrFlow instance. The controller refreshes this on every reconciliation of any `FerrFlowSecret` that references the connection.
func (*FerrFlowConnectionStatus) DeepCopyInto ¶
func (in *FerrFlowConnectionStatus) DeepCopyInto(out *FerrFlowConnectionStatus)
DeepCopyInto for the status block — manually written so we can drop the codegen step for now.
type FerrFlowSecret ¶
type FerrFlowSecret struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FerrFlowSecretSpec `json:"spec,omitempty"`
Status FerrFlowSecretStatus `json:"status,omitempty"`
}
FerrFlowSecret is the Schema for the ferrflowsecrets API.
func (*FerrFlowSecret) DeepCopy ¶
func (in *FerrFlowSecret) DeepCopy() *FerrFlowSecret
DeepCopy returns a deep copy of the receiver.
func (*FerrFlowSecret) DeepCopyInto ¶
func (in *FerrFlowSecret) DeepCopyInto(out *FerrFlowSecret)
DeepCopyInto copies the receiver into out.
func (*FerrFlowSecret) DeepCopyObject ¶
func (in *FerrFlowSecret) DeepCopyObject() runtime.Object
DeepCopyObject implements runtime.Object.
type FerrFlowSecretList ¶
type FerrFlowSecretList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FerrFlowSecret `json:"items"`
}
FerrFlowSecretList contains a list of FerrFlowSecret.
func (*FerrFlowSecretList) DeepCopy ¶
func (in *FerrFlowSecretList) DeepCopy() *FerrFlowSecretList
DeepCopy returns a deep copy of the receiver.
func (*FerrFlowSecretList) DeepCopyInto ¶
func (in *FerrFlowSecretList) DeepCopyInto(out *FerrFlowSecretList)
DeepCopyInto copies the receiver into out.
func (*FerrFlowSecretList) DeepCopyObject ¶
func (in *FerrFlowSecretList) DeepCopyObject() runtime.Object
DeepCopyObject implements runtime.Object.
type FerrFlowSecretSpec ¶
type FerrFlowSecretSpec struct {
// ConnectionRef points at a FerrFlowConnection in the same namespace.
//
// +kubebuilder:validation:Required
ConnectionRef LocalObjectReference `json:"connectionRef"`
// Project is the FerrFlow project slug.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Project string `json:"project"`
// Vault is the FerrFlow vault name inside the project (often used as the
// environment identifier: `production`, `staging`, …).
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Vault string `json:"vault"`
// Selector chooses which secrets to sync.
//
// +optional
Selector SecretSelector `json:"selector,omitempty"`
// Target controls the generated Secret.
//
// +optional
Target SecretTarget `json:"target,omitempty"`
// RefreshInterval is the cadence at which the operator polls FerrFlow for
// value changes, expressed in Go's `time.Duration` syntax (`30m`, `1h`).
// Defaults to `1h`. Set to `0s` to disable scheduled refreshes (the
// operator still reacts to spec changes).
//
// +optional
// +kubebuilder:default="1h"
RefreshInterval string `json:"refreshInterval,omitempty"`
// RolloutRestart lists workloads whose pods should be rolled when secret
// values change. Pattern: the operator patches the pod template's
// `ferrflow.io/restartedAt` annotation to force a rolling update.
//
// +optional
RolloutRestart []WorkloadRef `json:"rolloutRestart,omitempty"`
// Transforms rewrite the revealed key/value map before it's written to
// the target Secret. Applied in order. See SecretTransform for the
// supported operations.
//
// +optional
Transforms []SecretTransform `json:"transforms,omitempty"`
}
FerrFlowSecretSpec declares a sync from a FerrFlow vault into a native Kubernetes Secret. The operator reconciles this CR on the configured `refreshInterval`, or immediately when the spec changes.
func (*FerrFlowSecretSpec) DeepCopyInto ¶
func (in *FerrFlowSecretSpec) DeepCopyInto(out *FerrFlowSecretSpec)
DeepCopyInto for Spec — slice fields need deep copies.
type FerrFlowSecretStatus ¶
type FerrFlowSecretStatus struct {
// Conditions conveys the health of this sync. The primary condition is
// `Ready` — `True` when the target Secret mirrors the desired keys.
//
// +optional
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions,omitempty"`
// LastSyncedAt is the timestamp of the most recent successful reveal.
//
// +optional
LastSyncedAt *metav1.Time `json:"lastSyncedAt,omitempty"`
// SyncedKeys is the list of keys present in the target Secret after the
// most recent reconciliation. Handy for `kubectl get` columns and for
// diffing which keys disappeared upstream.
//
// +optional
SyncedKeys []string `json:"syncedKeys,omitempty"`
// MissingKeys lists keys that were requested in `spec.selector.names` but
// were not present in the FerrFlow vault at last reveal. When non-empty,
// `Ready` is set to `False`.
//
// +optional
MissingKeys []string `json:"missingKeys,omitempty"`
// ObservedGeneration is the generation of the CR the controller has
// successfully applied.
//
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}
FerrFlowSecretStatus reports the last reconciliation outcome.
func (*FerrFlowSecretStatus) DeepCopyInto ¶
func (in *FerrFlowSecretStatus) DeepCopyInto(out *FerrFlowSecretStatus)
DeepCopyInto for Status — includes Time pointer + slices.
type LocalObjectReference ¶
type LocalObjectReference struct {
// +kubebuilder:validation:Required
Name string `json:"name"`
}
LocalObjectReference is a namespaced reference with just a name, used to point at another CR living in the same namespace.
type OIDCAuth ¶
type OIDCAuth struct {
// ClusterID is the UUID of the cluster resource registered in FerrFlow.
// Admins retrieve it from the FerrFlow UI after creating the cluster.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:Pattern=`^[0-9a-fA-F-]{36}$`
ClusterID string `json:"clusterID"`
// TokenPath is the filesystem location where kubelet mounts the
// projected ServiceAccount token. Defaults to
// `/var/run/secrets/ferrflow/token` — match this in the operator pod's
// `volumeMounts` + `serviceAccountToken` projection.
//
// +optional
TokenPath string `json:"tokenPath,omitempty"`
// Audience the projected ServiceAccount token declares in its `aud`
// claim. Must match `EXPECTED_AUDIENCE` on the FerrFlow side
// (`https://ferrflow.com`). Defaults to that value when omitted.
//
// +optional
Audience string `json:"audience,omitempty"`
}
OIDCAuth configures the workload-identity exchange. The operator posts the JWT at `oidc.tokenPath` to FerrFlow's `POST /clusters/oidc-exchange` and caches the returned bearer for its lifetime (currently ~15 min).
type SecretKeyRef ¶
type SecretKeyRef struct {
// Name of the Secret. Must live in the same namespace as the
// FerrFlowConnection object.
//
// +kubebuilder:validation:Required
Name string `json:"name"`
// Key within the Secret's `data` map.
//
// +kubebuilder:validation:Required
Key string `json:"key"`
}
SecretKeyRef selects a single key inside a Kubernetes Secret.
type SecretSelector ¶
type SecretSelector struct {
// Names is an explicit list of secret keys to sync. When empty, every
// secret in the vault is synced.
//
// +optional
Names []string `json:"names,omitempty"`
}
SecretSelector picks which keys to pull from the referenced FerrFlow vault.
type SecretTarget ¶
type SecretTarget struct {
// Name of the `Secret` to create or update in the same namespace as the
// CR. Defaults to `metadata.name` of the `FerrFlowSecret` itself when
// omitted.
//
// +optional
Name string `json:"name,omitempty"`
// Type of the generated Secret (e.g. `Opaque`, `kubernetes.io/tls`).
// Defaults to `Opaque`.
//
// +optional
Type string `json:"type,omitempty"`
}
SecretTarget controls the Kubernetes Secret the operator writes to.
type SecretTransform ¶
type SecretTransform struct {
// Type identifies the transform kind.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=prefix;suffix;rename;base64Decode;jsonExpand
Type string `json:"type"`
// Value is the payload for `prefix` and `suffix`.
//
// +optional
Value string `json:"value,omitempty"`
// From is the source key for `rename`.
//
// +optional
From string `json:"from,omitempty"`
// To is the destination key for `rename`.
//
// +optional
To string `json:"to,omitempty"`
// Keys restricts `base64Decode` to a subset of keys. Empty = all keys.
//
// +optional
Keys []string `json:"keys,omitempty"`
// Key is the source key for `jsonExpand`.
//
// +optional
Key string `json:"key,omitempty"`
}
SecretTransform rewrites the `{key: value}` map returned by the FerrFlow API before it lands in the target Secret. Transforms are applied in the order declared. Exactly one of the payload fields relevant to `type` must be set — the CRD enforces this via OpenAPI validation at admission time.
Supported types:
- prefix: Stamp `value` in front of every key.
- suffix: Append `value` to every key.
- rename: Project `from` to `to`. No-op when `from` is missing.
- base64Decode: Decode the listed `keys` (or all when empty) from base64.
- jsonExpand: Flatten a JSON object under `key` into `<KEY>_<SUB>` entries. Nested objects compose with `_`. The source key is dropped.
func (*SecretTransform) DeepCopyInto ¶
func (in *SecretTransform) DeepCopyInto(out *SecretTransform)
DeepCopyInto copies the receiver into out. Keys slice is copied element-wise; all other fields are scalars.
type WorkloadRef ¶
type WorkloadRef struct {
// Kind of the workload. One of: Deployment, StatefulSet, DaemonSet.
//
// +kubebuilder:validation:Enum=Deployment;StatefulSet;DaemonSet
Kind string `json:"kind"`
// Name of the workload within the same namespace as the CR.
//
// +kubebuilder:validation:Required
Name string `json:"name"`
}
WorkloadRef identifies a workload whose pods should be rolled when secret values change. The operator adds an annotation (`ferrflow.io/restartedAt`) to the pod template to trigger a rolling restart.