v1alpha1

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 21, 2026 License: MPL-2.0 Imports: 4 Imported by: 0

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

View Source
const DefaultAudience = "https://ferrflow.com"

DefaultAudience matches the FerrFlow API's `EXPECTED_AUDIENCE` constant. Changing this is a coordinated breaking change across both repos.

View Source
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

View Source
var AddToScheme = SchemeBuilder.AddToScheme

AddToScheme is the canonical entry point used by cmd/main.go.

View Source
var GroupVersion = schema.GroupVersion{Group: "ferrflow.io", Version: "v1alpha1"}

GroupVersion is the API group/version pair the controller watches.

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

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL