diff --git a/api/v1alpha1/openbaocluster_types.go b/api/v1alpha1/openbaocluster_types.go index 22fa93100..937c77421 100644 --- a/api/v1alpha1/openbaocluster_types.go +++ b/api/v1alpha1/openbaocluster_types.go @@ -703,8 +703,10 @@ type UpgradeConfig struct { // The role must bind to the upgrade ServiceAccount (-upgrade-serviceaccount), // which is automatically created by the operator. // - // If OIDC is enabled in SelfInit and this field is empty, a default role - // named "openbao-operator-upgrade" will be assumed/created. + // If OIDC is enabled during initial SelfInit bootstrap and this field is + // empty, a default role named "openbao-operator-upgrade" will be created. + // For already-initialized clusters, configure this role explicitly or keep + // the default role created during initial bootstrap. // // This is the supported authentication mechanism for built-in upgrade orchestration. // +optional @@ -713,9 +715,9 @@ type UpgradeConfig struct { // token for future non-JWT upgrade authentication flows. // // Built-in rolling and blue/green upgrade orchestration does not support - // token-based authentication. Configure spec.upgrade.jwtAuthRole or enable - // spec.selfInit.oidc.enabled instead. - // +kubebuilder:validation:XValidation:rule="self == null",message="spec.upgrade.tokenSecretRef is not supported; configure spec.upgrade.jwtAuthRole or enable spec.selfInit.oidc.enabled" + // token-based authentication. Configure spec.upgrade.jwtAuthRole, or use the + // default role created during initial spec.selfInit.oidc bootstrap. + // +kubebuilder:validation:XValidation:rule="self == null",message="spec.upgrade.tokenSecretRef is not supported; configure spec.upgrade.jwtAuthRole or use the default role created during initial spec.selfInit.oidc bootstrap" // +optional TokenSecretRef *corev1.LocalObjectReference `json:"tokenSecretRef,omitempty"` @@ -2081,9 +2083,10 @@ type OpenBaoClusterSpec struct { // // Built-in upgrade executor Jobs authenticate with JWT auth using the // upgrade ServiceAccount (-upgrade-serviceaccount). If - // spec.selfInit.oidc.enabled is true and spec.upgrade.jwtAuthRole is empty, - // the operator assumes or bootstraps the default "openbao-operator-upgrade" - // role. + // spec.selfInit.oidc.enabled is true during initial SelfInit bootstrap and + // spec.upgrade.jwtAuthRole is empty, the operator creates the default + // "openbao-operator-upgrade" role. Already-initialized clusters must keep + // that role or configure spec.upgrade.jwtAuthRole explicitly. // // Pre-upgrade snapshots use spec.backup configuration and backup // authentication rather than spec.upgrade credentials. diff --git a/charts/openbao-operator/crds/openbao.org_openbaoclusters.yaml b/charts/openbao-operator/crds/openbao.org_openbaoclusters.yaml index e8e2da383..d3789dd33 100644 --- a/charts/openbao-operator/crds/openbao.org_openbaoclusters.yaml +++ b/charts/openbao-operator/crds/openbao.org_openbaoclusters.yaml @@ -4579,9 +4579,10 @@ spec: Built-in upgrade executor Jobs authenticate with JWT auth using the upgrade ServiceAccount (-upgrade-serviceaccount). If - spec.selfInit.oidc.enabled is true and spec.upgrade.jwtAuthRole is empty, - the operator assumes or bootstraps the default "openbao-operator-upgrade" - role. + spec.selfInit.oidc.enabled is true during initial SelfInit bootstrap and + spec.upgrade.jwtAuthRole is empty, the operator creates the default + "openbao-operator-upgrade" role. Already-initialized clusters must keep + that role or configure spec.upgrade.jwtAuthRole explicitly. Pre-upgrade snapshots use spec.backup configuration and backup authentication rather than spec.upgrade credentials. @@ -4708,8 +4709,10 @@ spec: The role must bind to the upgrade ServiceAccount (-upgrade-serviceaccount), which is automatically created by the operator. - If OIDC is enabled in SelfInit and this field is empty, a default role - named "openbao-operator-upgrade" will be assumed/created. + If OIDC is enabled during initial SelfInit bootstrap and this field is + empty, a default role named "openbao-operator-upgrade" will be created. + For already-initialized clusters, configure this role explicitly or keep + the default role created during initial bootstrap. This is the supported authentication mechanism for built-in upgrade orchestration. type: string @@ -4775,8 +4778,8 @@ spec: token for future non-JWT upgrade authentication flows. Built-in rolling and blue/green upgrade orchestration does not support - token-based authentication. Configure spec.upgrade.jwtAuthRole or enable - spec.selfInit.oidc.enabled instead. + token-based authentication. Configure spec.upgrade.jwtAuthRole, or use the + default role created during initial spec.selfInit.oidc bootstrap. properties: name: default: "" @@ -4791,7 +4794,8 @@ spec: x-kubernetes-map-type: atomic x-kubernetes-validations: - message: spec.upgrade.tokenSecretRef is not supported; configure - spec.upgrade.jwtAuthRole or enable spec.selfInit.oidc.enabled + spec.upgrade.jwtAuthRole or use the default role created during + initial spec.selfInit.oidc bootstrap rule: self == null type: object version: diff --git a/config/crd/bases/openbao.org_openbaoclusters.yaml b/config/crd/bases/openbao.org_openbaoclusters.yaml index bd1bfc60c..8754a74dd 100644 --- a/config/crd/bases/openbao.org_openbaoclusters.yaml +++ b/config/crd/bases/openbao.org_openbaoclusters.yaml @@ -4578,9 +4578,10 @@ spec: Built-in upgrade executor Jobs authenticate with JWT auth using the upgrade ServiceAccount (-upgrade-serviceaccount). If - spec.selfInit.oidc.enabled is true and spec.upgrade.jwtAuthRole is empty, - the operator assumes or bootstraps the default "openbao-operator-upgrade" - role. + spec.selfInit.oidc.enabled is true during initial SelfInit bootstrap and + spec.upgrade.jwtAuthRole is empty, the operator creates the default + "openbao-operator-upgrade" role. Already-initialized clusters must keep + that role or configure spec.upgrade.jwtAuthRole explicitly. Pre-upgrade snapshots use spec.backup configuration and backup authentication rather than spec.upgrade credentials. @@ -4707,8 +4708,10 @@ spec: The role must bind to the upgrade ServiceAccount (-upgrade-serviceaccount), which is automatically created by the operator. - If OIDC is enabled in SelfInit and this field is empty, a default role - named "openbao-operator-upgrade" will be assumed/created. + If OIDC is enabled during initial SelfInit bootstrap and this field is + empty, a default role named "openbao-operator-upgrade" will be created. + For already-initialized clusters, configure this role explicitly or keep + the default role created during initial bootstrap. This is the supported authentication mechanism for built-in upgrade orchestration. type: string @@ -4774,8 +4777,8 @@ spec: token for future non-JWT upgrade authentication flows. Built-in rolling and blue/green upgrade orchestration does not support - token-based authentication. Configure spec.upgrade.jwtAuthRole or enable - spec.selfInit.oidc.enabled instead. + token-based authentication. Configure spec.upgrade.jwtAuthRole, or use the + default role created during initial spec.selfInit.oidc bootstrap. properties: name: default: "" @@ -4790,7 +4793,8 @@ spec: x-kubernetes-map-type: atomic x-kubernetes-validations: - message: spec.upgrade.tokenSecretRef is not supported; configure - spec.upgrade.jwtAuthRole or enable spec.selfInit.oidc.enabled + spec.upgrade.jwtAuthRole or use the default role created during + initial spec.selfInit.oidc bootstrap rule: self == null type: object version: diff --git a/docs/reference/api.md b/docs/reference/api.md index ef8a2949a..8341071e6 100644 --- a/docs/reference/api.md +++ b/docs/reference/api.md @@ -1038,7 +1038,7 @@ _Appears in:_ | `auditFileStorage` _[AuditFileStorageConfig](#auditfilestorageconfig)_ | AuditFileStorage configures a shared filesystem integration point for file audit devices.
When configured, file audit device paths must be under auditFileStorage.mountPath. | | Optional: \{\}
| | `plugins` _[Plugin](#plugin) array_ | Plugins configures declarative plugins for the OpenBao cluster.
See: https://openbao.org/docs/configuration/plugins/ | | Optional: \{\}
| | `telemetry` _[TelemetryConfig](#telemetryconfig)_ | Telemetry configures telemetry reporting for the OpenBao cluster.
See: https://openbao.org/docs/configuration/telemetry/ | | Optional: \{\}
| -| `upgrade` _[UpgradeConfig](#upgradeconfig)_ | Upgrade configures upgrade operations.
Built-in upgrade executor Jobs authenticate with JWT auth using the
upgrade ServiceAccount (<cluster-name>-upgrade-serviceaccount). If
spec.selfInit.oidc.enabled is true and spec.upgrade.jwtAuthRole is empty,
the operator assumes or bootstraps the default "openbao-operator-upgrade"
role.
Pre-upgrade snapshots use spec.backup configuration and backup
authentication rather than spec.upgrade credentials. | | Optional: \{\}
| +| `upgrade` _[UpgradeConfig](#upgradeconfig)_ | Upgrade configures upgrade operations.
Built-in upgrade executor Jobs authenticate with JWT auth using the
upgrade ServiceAccount (<cluster-name>-upgrade-serviceaccount). If
spec.selfInit.oidc.enabled is true during initial SelfInit bootstrap and
spec.upgrade.jwtAuthRole is empty, the operator creates the default
"openbao-operator-upgrade" role. Already-initialized clusters must keep
that role or configure spec.upgrade.jwtAuthRole explicitly.
Pre-upgrade snapshots use spec.backup configuration and backup
authentication rather than spec.upgrade credentials. | | Optional: \{\}
| | `unseal` _[UnsealConfig](#unsealconfig)_ | Unseal defines the auto-unseal configuration.
If omitted, defaults to "static" mode managed by the operator. | | Optional: \{\}
| | `imageVerification` _[ImageVerificationConfig](#imageverificationconfig)_ | ImageVerification configures supply chain security checks. | | Optional: \{\}
| | `operatorImageVerification` _[ImageVerificationConfig](#imageverificationconfig)_ | OperatorImageVerification configures supply chain security checks for operator-managed helper images
(init container, backup/upgrade/restore executors). These images are typically signed
by the operator project (e.g., dc-tec/openbao-operator) rather than the OpenBao upstream project.
If omitted, helper image verification does not fall back to ImageVerification.
In Development, omitted means disabled. In Hardened, omitted means enabled. | | Optional: \{\}
| @@ -2026,8 +2026,8 @@ _Appears in:_ | --- | --- | --- | --- | | `image` _string_ | Image is the container image to use for upgrade operations.
This image is used by Kubernetes Jobs created during upgrades (for example, blue/green
cluster orchestration actions). The executor runs inside the tenant namespace and
authenticates to OpenBao using a projected ServiceAccount token (JWT auth).
If not specified, defaults to "<repo>:X.Y.Z" where <repo> is derived from OPERATOR_UPGRADE_IMAGE_REPOSITORY
(default: "ghcr.io/dc-tec/openbao-upgrade") and the tag matches OPERATOR_VERSION. | | Optional: \{\}
| | `preUpgradeSnapshot` _boolean_ | PreUpgradeSnapshot, when true, triggers a backup before any upgrade.
When enabled, the upgrade manager will create a backup using the backup
configuration (spec.backup.target, spec.backup.image, etc.) and
wait for it to complete before proceeding with the upgrade.
If the backup fails, the upgrade will be blocked and a Degraded condition
will be set with Reason=PreUpgradeBackupFailed.
Requires spec.backup to be configured with target, image, and
authentication (jwtAuthRole or tokenSecretRef). | | Optional: \{\}
| -| `jwtAuthRole` _string_ | JWTAuthRole is the name of the JWT Auth role configured in OpenBao
for upgrade executor Jobs. The executor authenticates with a projected
ServiceAccount token from <cluster-name>-upgrade-serviceaccount.
The role must be configured in OpenBao and must grant the permissions
required by the selected upgrade strategy, including:
- "read" capability on sys/health
- "sudo" and "update" capability on sys/step-down
- "read" capability on sys/storage/raft/autopilot/state
- for Blue/Green, raft join/configuration/remove-peer/promote/demote operations
The role must bind to the upgrade ServiceAccount (<cluster-name>-upgrade-serviceaccount),
which is automatically created by the operator.
If OIDC is enabled in SelfInit and this field is empty, a default role
named "openbao-operator-upgrade" will be assumed/created.
This is the supported authentication mechanism for built-in upgrade orchestration. | | Optional: \{\}
| -| `tokenSecretRef` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#localobjectreference-v1-core)_ | TokenSecretRef optionally references a Secret containing an OpenBao API
token for future non-JWT upgrade authentication flows.
Built-in rolling and blue/green upgrade orchestration does not support
token-based authentication. Configure spec.upgrade.jwtAuthRole or enable
spec.selfInit.oidc.enabled instead. | | Optional: \{\}
| +| `jwtAuthRole` _string_ | JWTAuthRole is the name of the JWT Auth role configured in OpenBao
for upgrade executor Jobs. The executor authenticates with a projected
ServiceAccount token from <cluster-name>-upgrade-serviceaccount.
The role must be configured in OpenBao and must grant the permissions
required by the selected upgrade strategy, including:
- "read" capability on sys/health
- "sudo" and "update" capability on sys/step-down
- "read" capability on sys/storage/raft/autopilot/state
- for Blue/Green, raft join/configuration/remove-peer/promote/demote operations
The role must bind to the upgrade ServiceAccount (<cluster-name>-upgrade-serviceaccount),
which is automatically created by the operator.
If OIDC is enabled during initial SelfInit bootstrap and this field is
empty, a default role named "openbao-operator-upgrade" will be created.
For already-initialized clusters, configure this role explicitly or keep
the default role created during initial bootstrap.
This is the supported authentication mechanism for built-in upgrade orchestration. | | Optional: \{\}
| +| `tokenSecretRef` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#localobjectreference-v1-core)_ | TokenSecretRef optionally references a Secret containing an OpenBao API
token for future non-JWT upgrade authentication flows.
Built-in rolling and blue/green upgrade orchestration does not support
token-based authentication. Configure spec.upgrade.jwtAuthRole, or use the
default role created during initial spec.selfInit.oidc bootstrap. | | Optional: \{\}
| | `strategy` _[UpdateStrategyType](#updatestrategytype)_ | Strategy defines the update strategy to use. | RollingUpdate | Enum: [RollingUpdate BlueGreen]
| | `requests` _[UpgradeRequestConfig](#upgraderequestconfig)_ | Requests defines explicit one-shot operator requests for the current
upgrade workflow. The operator acts only when a request value changes. | | Optional: \{\}
| | `blueGreen` _[BlueGreenConfig](#bluegreenconfig)_ | BlueGreen configures the behavior when Strategy is BlueGreen. | | Optional: \{\}
| diff --git a/docs/reference/compatibility.md b/docs/reference/compatibility.md index 76d31c621..b0df2e811 100644 --- a/docs/reference/compatibility.md +++ b/docs/reference/compatibility.md @@ -41,7 +41,7 @@ The current stable release line is intended for real deployments, but it remains emphasis: 'caution', }, { - cells: ['v1.33', 'Not validated for the current release line', 'May work but is not release-gated for 0.2.0', 'Validate in staging before carrying this version into the current pre-GA line'], + cells: ['v1.33', 'Not validated for the current release line', 'May work but is not release-gated for the current line', 'Validate in staging before carrying this version into the current pre-GA line'], emphasis: 'caution', }, { diff --git a/docs/reference/known-limitations.md b/docs/reference/known-limitations.md index 3136ff0d1..40c91e4f8 100644 --- a/docs/reference/known-limitations.md +++ b/docs/reference/known-limitations.md @@ -35,7 +35,7 @@ journey: reference cells: ['Helm CRD lifecycle', 'Helm does not automatically upgrade or delete CRDs.', 'Use release `crds.yaml` assets for CRD lifecycle operations.'], }, { - cells: ['Built-in upgrade authentication', 'Built-in rolling and blue/green upgrade orchestration do not support `spec.upgrade.tokenSecretRef`; upgrade Jobs use JWT authentication only.', 'Configure `spec.upgrade.jwtAuthRole` or enable `spec.selfInit.oidc.enabled` so the operator can bootstrap the upgrade auth path.'], + cells: ['Built-in upgrade authentication', 'Built-in rolling and blue/green upgrade orchestration do not support `spec.upgrade.tokenSecretRef`; upgrade Jobs use JWT authentication only.', 'Configure `spec.upgrade.jwtAuthRole`, or use the default role created during initial `selfInit.oidc` bootstrap.'], }, { cells: ['Audit file storage archival', '`spec.auditFileStorage` provides a PVC-backed collector handoff and replay buffer; it does not provide rotation, pruning, tamper-proof retention, or a collector.', 'Mount the audit PVC read-only into a collector and ship records to external retention-controlled storage.'], diff --git a/release-notes/0.3.0.md b/release-notes/0.3.0.md new file mode 100644 index 000000000..ae4a71eea --- /dev/null +++ b/release-notes/0.3.0.md @@ -0,0 +1,130 @@ +0.3.0 is the next stable pre-GA release line for OpenBao Operator. This +release focuses on production operations hardening across operator +authentication, observability, audit logging, Gateway and Ingress integration, +runtime configuration, and backup and restore safety. + +### Highlights + +* Defaulted supported operator JWT flows to inline authentication, reducing + repeated login overhead while keeping controller, backup, restore, and upgrade + roles scoped separately. +* Added workload metrics scraping support, including declarative metrics + configuration, managed `ServiceMonitor` reconciliation, active-node and + all-node scrape profiles, and optional metrics-only listener support. +* Added audit file storage support for `OpenBaoCluster`, including managed PVC + wiring, pod-specific audit file paths, status reporting, and OpenBao-aligned + audit device options. +* Improved Gateway and Ingress integration readiness with Gateway API v1 + `TLSRoute` emission, explicit Gateway/Ingress readiness conditions, and + tolerance for GatewayClass implementations that omit the `SupportedVersion` + condition. +* Improved PKCS#11 runtime ergonomics for HSM-backed deployments, including + runtime environment and file-based configuration wiring for vendor libraries. +* Hardened backup, restore, storage endpoint, transit unseal, JWT role, and + helper input handling so unsafe or ambiguous configuration fails earlier and + more consistently. + +### Breaking and Migration Notes + +* Apply the `0.3.0` CRDs before upgrading the controller or Helm chart. This + release adds and tightens several `openbao.org/v1alpha1` fields and admission + checks. +* Inline authentication is now the default supported JWT flow. Environments with + proxies or intermediaries between the operator and OpenBao must preserve the + `X-Vault-Inline-Auth-*` headers. Use the login compatibility strategy only + when inline auth headers cannot be passed reliably. +* Audit file storage changes the OpenBao workload pod template. Enabling it on + an existing cluster can require StatefulSet recreation because Kubernetes + locks some volume and volume mount fields after creation. Preserve data PVCs + and plan the rollout before enabling audit file storage on production + clusters. +* Static restore token Secrets are now validated more strictly. A restore token + Secret must be in the target namespace and carry the expected identity labels + for the target cluster and restore-token purpose before the operator launches + the restore job. +* Backup, restore, and object storage endpoints are validated more strictly and + guarded at request time. Review custom S3-compatible endpoints, private + endpoints, and restore source configuration before upgrading. +* Metrics-only listener and all-node metrics configurations can expose OpenBao + metrics without normal client authentication. Restrict access with + NetworkPolicy or equivalent cluster controls before enabling unauthenticated + scraping. +* Gateway passthrough exposure requires a Gateway API implementation with the + needed Standard resources and listener behavior. ACME and OpenBao-managed TLS + flows should use passthrough rather than Gateway-side termination. + +### Operational Notes + +* The audit file storage PVC contains sensitive audit material. Treat it as + security-sensitive storage, include it in backup and retention planning, and + do not treat the operator-managed PVC as an immutable compliance archive. +* File audit device paths must stay under the configured audit file storage + mount path. +* Backup, restore, and upgrade jobs now rely on narrower auth roles. Existing + initialized clusters may need OpenBao policy or role updates before using + those workflows because the operator does not mutate OpenBao auth + configuration after initial bootstrap. +* `spec.upgrade.tokenSecretRef` is not supported for upgrade jobs. Upgrade jobs + authenticate through the configured JWT auth role. For already-initialized + clusters, create or update the required OpenBao auth role and policy before + requesting an upgrade; `selfInit` only bootstraps auth during initial cluster + initialization and does not retrofit running clusters. +* PKCS#11 deployments still require an OpenBao image with HSM support and the + vendor PKCS#11 module available at the configured library path. The operator + now wires the runtime more explicitly, but it does not provide vendor HSM + libraries. +* OCI plugin downloads use OpenBao runtime configuration and the mounted plugin + cache directory. Kubernetes image pull secrets do not automatically authorize + OpenBao runtime plugin downloads, so private or disconnected environments + should mirror plugin images and configure registry access deliberately. +* Tenants and platform teams that own Pod Security Standards labels outside the + operator can now keep that ownership model while using the operator + provisioner. +* Users already running `0.2.1` have the duplicate Helm RBAC label and OCI plugin + directory fixes from the patch line; they remain included in `0.3.0`. + +### Upgrade from 0.2.x + +Before upgrading an existing `0.2.x` installation: + +1. Review every existing `OpenBaoCluster`, `OpenBaoRestore`, backup, Gateway, + Ingress, metrics, audit, and unseal configuration against the stricter + validation described above. +2. For clusters using intermediary proxies between the operator and OpenBao, + confirm inline auth headers are preserved or plan to use the login + compatibility strategy. +3. For clusters that will enable audit file storage, plan the StatefulSet + rollout and confirm data PVC retention before applying the change. +4. For restore workflows using static token Secrets, add the required target + namespace and restore-token identity labels before creating new restores. +5. For backup and restore workflows using S3-compatible storage, validate the + endpoint URLs and credentials in staging. +6. Apply the `0.3.0` CRDs first: + + ```sh + kubectl apply -f https://github.com/dc-tec/openbao-operator/releases/download/0.3.0/crds.yaml + ``` + +7. Upgrade the Helm release: + + ```sh + helm upgrade openbao-operator oci://ghcr.io/dc-tec/charts/openbao-operator \ + --version 0.3.0 \ + --namespace openbao-operator-system \ + --reuse-values + ``` + +8. Verify the operator rollout, CRD presence, managed cluster conditions, + Gateway/Ingress readiness conditions, backup/restore events, and recent + controller logs before continuing with OpenBao workload changes. + +Kubernetes `v1.34` and `v1.35` are the 0.3.0 release-gated versions. Kubernetes +`v1.33` may work but is not release-gated for this line. Kubernetes `v1.36` is +tracked as the next candidate once controller-runtime, Kind, and release-gate +coverage are available. + +### Compatibility + +OpenBao Operator requires Kubernetes `v1.33+`. The current release validation +baseline is Kubernetes `v1.34`-`v1.35` and OpenBao `2.5.4`, with config +compatibility coverage for OpenBao `2.4.4`. diff --git a/releases/0.2.0.mdx b/releases/0.2.0.mdx index 10ea40341..142b3ee83 100644 --- a/releases/0.2.0.mdx +++ b/releases/0.2.0.mdx @@ -9,7 +9,7 @@ slug: /0.2.0 Published 2026-05-01. - + Open the docs experience aligned to this release line. diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 4fa19275b..a1676296d 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -13,6 +13,7 @@ const docsPluginDefaultExclude = [ '**/__tests__/**', ]; const releaseLineVersionLabels = { + '0.3.0': '0.3.x', '0.2.0': '0.2.x', '0.1.0': '0.1.x', } as const; diff --git a/website/tests/behavior.spec.ts b/website/tests/behavior.spec.ts index b338105b8..05d428e9f 100644 --- a/website/tests/behavior.spec.ts +++ b/website/tests/behavior.spec.ts @@ -42,7 +42,7 @@ test('version dropdown switches from next docs to the stable release line', asyn await versionDropdown.hover(); const archivedRelease = page.locator('.dropdown__menu').getByRole('link', { - name: '0.2.x', + name: '0.3.x', exact: true, }); await expect(archivedRelease).toBeVisible(); @@ -50,7 +50,7 @@ test('version dropdown switches from next docs to the stable release line', asyn await expect(page).toHaveURL(/\/openbao-operator\/docs\/get-started\/deployment-decision-guide$/); await expect(page.getByText('Published release documentation')).toBeVisible(); - await expect(page.getByText('Version: 0.2.x')).toBeVisible(); + await expect(page.getByText('Version: 0.3.x')).toBeVisible(); }); test.describe('curated legacy redirects stay alive', () => { diff --git a/website/tests/smoke.spec.ts b/website/tests/smoke.spec.ts index 24dc37462..87ab374dd 100644 --- a/website/tests/smoke.spec.ts +++ b/website/tests/smoke.spec.ts @@ -46,7 +46,7 @@ test('stable docs expose the current release banner', async ({page}) => { await expect(page.getByRole('heading', {name: 'OpenBao Operator documentation'})).toBeVisible(); await expect(page.getByText('Published release documentation')).toBeVisible(); - await expect(page.getByText('Version: 0.2.x')).toBeVisible(); + await expect(page.getByText('Version: 0.3.x')).toBeVisible(); }); test('architecture section exposes grouped local navigation', async ({page}) => { diff --git a/website/versioned_docs/version-0.3.0/architecture/backup-manager.md b/website/versioned_docs/version-0.3.0/architecture/backup-manager.md new file mode 100644 index 000000000..82447eb2c --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/backup-manager.md @@ -0,0 +1,200 @@ +--- +title: Backup Manager +hide_title: true +pageType: concept +journey: architecture +description: Schedule snapshot jobs, enforce retention, and update backup status while keeping snapshot data transport out of the controller. +--- + + + + + + + +## Architectural placement + +Backup orchestration belongs to the AdminOps path: + +1. `internal/controller/openbaocluster` receives an adminops reconcile event. +2. The controller delegates into `internal/app/openbaocluster/adminops`. +3. AdminOps orchestration invokes `internal/service/backup` to validate, launch, and observe backup execution. + +That keeps the controller focused on reconcile plumbing while the backup manager owns timing, job launch, and retention decisions. + + + +## Backup flow + + Validate{"Preflight checks"} + Validate --> Retry["Requeue without launch"] + Validate --> Lock["Acquire backup operation lock"] + Lock --> Job["Create backup Job"] + Job --> Auth["Authenticate to OpenBao"] + Auth --> Snapshot["Stream Raft snapshot"] + Snapshot --> Upload["Upload to object storage"] + Upload --> Result{"Job result"} + Result --> Success["Patch lastSuccessfulBackup and next schedule"] + Result --> Failure["Increment consecutiveFailures and record attempt"] + Success --> Retention["Apply retention policy"] + + classDef read fill:transparent,stroke:#79c0ab,stroke-width:2px,color:#e6f4ef; + classDef process fill:transparent,stroke:#fdd0a4,stroke-width:2px,color:#f8fafc; + classDef write fill:transparent,stroke:#87d6be,stroke-width:2px,color:#e6f4ef; + classDef critical fill:transparent,stroke:#dc2626,stroke-width:2px,color:#f8fafc; + + class Trigger read; + class Validate,Lock,Job,Auth,Snapshot,Upload,Retention process; + class Success write; + class Failure critical;`} +/> + + + +## Provider and retention surfaces + + + +Backups are stored under a stable object prefix so restore workflows can locate artifacts without reverse-engineering Job names: + +```text +///-.snap +``` + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/cert-manager.md b/website/versioned_docs/version-0.3.0/architecture/cert-manager.md new file mode 100644 index 000000000..5e874ded4 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/cert-manager.md @@ -0,0 +1,170 @@ +--- +title: Cert Manager +hide_title: true +pageType: concept +journey: architecture +description: Manage TLS certificate sources, rotation windows, and hot-reload signaling for the OpenBao workload path. +--- + + + + + +## Architectural placement + +TLS lifecycle stays on the workload reconcile path: + +1. `internal/controller/openbaocluster` determines that TLS state must reconcile. +2. The controller calls `internal/service/certs`. +3. The cert manager creates, validates, or watches certificate material and signals reload when the active server certificate changes. + +That keeps TLS behavior close to workload rendering while avoiding a second, disconnected certificate controller path. + + + +## Rotation and reload path + + Generate["Generate or reuse cert material"] + Generate --> Secrets["Update tls-ca / tls-server Secrets"] + Secrets --> Hash["Compute server-cert hash"] + Hash --> Change{"Hash changed?"} + Change --> Skip["No reload signal"] + Change --> Annotate["Annotate ready pods with new hash"] + Annotate --> Watcher["In-pod watcher observes change"] + Watcher --> Reload["Send SIGHUP / reload TLS"] + + classDef read fill:transparent,stroke:#79c0ab,stroke-width:2px,color:#e6f4ef; + classDef process fill:transparent,stroke:#fdd0a4,stroke-width:2px,color:#f8fafc; + classDef write fill:transparent,stroke:#87d6be,stroke-width:2px,color:#e6f4ef; + + class Check read; + class Generate,Hash,Watcher process; + class Secrets,Annotate,Reload write; + class Change,Skip read;`} +/> + +>K8s: Update TLS Secret or confirm external change + Certs->>K8s: Patch pod annotation openbao.org/tls-cert-hash + K8s->>Pod: Project new Secret contents and annotation + Pod->>Watcher: File or annotation change observed + Watcher->>Bao: Send reload signal + Bao->>Bao: Reload listener certificate + `} +/> + + + +When `spec.tls.mode=ACME`, the cert manager still participates in rendering the listener contract, but OpenBao owns the live ACME issuance and cache lifecycle. Kubernetes TLS Secrets stop being the source of truth for the workload certificate. + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/components.md b/website/versioned_docs/version-0.3.0/architecture/components.md new file mode 100644 index 000000000..cd8b9994a --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/components.md @@ -0,0 +1,200 @@ +--- +title: Component Design +hide_title: true +pageType: concept +journey: architecture +description: Split-controller architecture for OpenBaoCluster, OpenBaoRestore, and OpenBaoTenant, including controller boundaries, app-layer orchestration, and service-layer coordination. +--- + + + +## Controller split + + WorkloadCtrl["Workload controller"] + Manager --> Admin["AdminOps controller"] + Manager --> Status["Status controller"] + + subgraph Roles["Responsibilities"] + WorkloadCtrl --> Cert["Cert manager"] + WorkloadCtrl --> Bootstrap["Bootstrap manager"] + WorkloadCtrl --> Networking["Networking manager"] + WorkloadCtrl --> Identity["Identity manager"] + WorkloadCtrl --> Init["Init manager"] + WorkloadCtrl --> WorkloadMgr["Workload manager"] + + Admin --> Upgrade["Upgrade manager"] + Admin --> Backup["Backup manager"] + + Status --> Conditions["Status conditions"] + end + + classDef process fill:transparent,stroke:#fdd0a4,stroke-width:2px,color:#f8fafc; + classDef write fill:transparent,stroke:#87d6be,stroke-width:2px,color:#e6f4ef; + classDef read fill:transparent,stroke:#79c0ab,stroke-width:2px,color:#e6f4ef; + + class Manager process; + class WorkloadCtrl,Admin,Status write; + class Cert,Bootstrap,Networking,Identity,Init,WorkloadMgr,Upgrade,Backup,Conditions read;`} +/> + + + + + +Restores are reconciled through the separate `OpenBaoRestore` controller, which orchestrates restore Jobs and acquires the cluster operation lock before destructive work starts. + + + +## App orchestration and managers + + OBCApp["internal/app/openbaocluster"] + OBR["OpenBaoRestore controller"] --> OBRApp["internal/app/openbaorestore"] + Prov["Provisioner controller"] --> ProvApp["internal/app/provisioner"] + + OBCApp --> WorkloadOps["Workload orchestration"] + OBCApp --> AdminOps["AdminOps orchestration"] + OBCApp --> StatusOps["Status and deletion orchestration"] + + WorkloadOps --> Cert["Cert manager"] + WorkloadOps --> Bootstrap["Bootstrap manager"] + WorkloadOps --> Networking["Networking manager"] + WorkloadOps --> Identity["Identity manager"] + WorkloadOps --> Init["Init manager"] + WorkloadOps --> WorkloadMgr["Workload manager"] + AdminOps --> Upgrade["Upgrade manager"] + AdminOps --> Backup["Backup manager"] + + OBRApp --> Restore["Restore manager"] + ProvApp --> Provisioner["Provisioner manager"] + + classDef process fill:transparent,stroke:#fdd0a4,stroke-width:2px,color:#f8fafc; + classDef write fill:transparent,stroke:#87d6be,stroke-width:2px,color:#e6f4ef; + classDef read fill:transparent,stroke:#79c0ab,stroke-width:2px,color:#e6f4ef; + + class OBC,OBR,Prov write; + class OBCApp,OBRApp,ProvApp,WorkloadOps,AdminOps,StatusOps process; + class Cert,Bootstrap,Networking,Identity,Init,WorkloadMgr,Upgrade,Backup,Restore,Provisioner read;`} +/> + + + +## Shared contracts below managers + +The controller and app layers coordinate managers, but some semantics stay below the manager boundary because they must stay uniform across multiple services. + + + + + +Controller, app, service, and selected platform import surfaces are intentionally narrow and enforced by generated architecture-boundary rules from `.ast-grep/policy/architecture-boundaries.yml`. + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/index.mdx b/website/versioned_docs/version-0.3.0/architecture/index.mdx new file mode 100644 index 000000000..38b69f0b8 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/index.mdx @@ -0,0 +1,86 @@ +--- +title: Architecture +slug: /architecture +hide_title: true +pageType: landing +journey: architecture +description: Internal design, controller boundaries, lifecycle flows, invariants, and implementation decisions behind OpenBao Operator. +--- + + + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/init-manager.md b/website/versioned_docs/version-0.3.0/architecture/init-manager.md new file mode 100644 index 000000000..5c25a2ef9 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/init-manager.md @@ -0,0 +1,202 @@ +--- +title: Init Manager +hide_title: true +pageType: concept +journey: architecture +description: Bootstrap a new cluster safely, handle self-init or operator init flows, and configure autopilot before scaling out. +--- + + + + + +## Architectural placement + +Initialization stays on the workload-side controller path while the cluster is not yet ready for normal steady-state reconciliation: + +1. `internal/controller/openbaocluster` keeps the cluster on the uninitialized path. +2. The controller calls `internal/service/init` once the first pod and TLS prerequisites are ready. +3. The init manager marks initialization state, configures autopilot, and only then allows the workload manager to scale to the requested replica count. + +That separation prevents first-boot logic from leaking into every steady-state reconcile. + +## Bootstrap flow + +>Workload: Render StatefulSet at replicas=1 + Workload->>Pod0: Start first pod + Pod0-->>Init: Pod ready + TLS available + Init->>Bao: Detect initialized or call /sys/init + Bao-->>Init: Init response or initialized health + Init->>Status: Set initialized / selfInitialized + Init->>Bao: Configure autopilot defaults + Status-->>Workload: Initialization confirmed + Workload->>Workload: Scale StatefulSet to spec.replicas + `} +/> + +## Initialization phases + + + + + + + + + + + + + + + + + + + +## Autopilot defaults + + 3; other profiles use max(1, replicas).', 'The cleanup policy and quorum safety model must be aligned from the first initialized reconcile.'], + }, + ]} +/> + + + +If the manager detects that a cluster is already initialized, it takes the initialized-cluster path as recovery for an operator-managed cluster. It is not a generic import path for arbitrary unmanaged OpenBao clusters. + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/lifecycle/day0-provisioning.md b/website/versioned_docs/version-0.3.0/architecture/lifecycle/day0-provisioning.md new file mode 100644 index 000000000..006f483d2 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/lifecycle/day0-provisioning.md @@ -0,0 +1,182 @@ +--- +title: Day 0 Provisioning +hide_title: true +pageType: concept +journey: architecture +description: Tenant provisioning flow from OpenBaoTenant creation through namespace-scoped RBAC, policy defaults, and the handoff to cluster creation. +--- + + + + + + + + + +## Architectural placement + +Day 0 provisioning uses the dedicated tenant-controller path: + +1. A cluster admin or namespace owner creates `OpenBaoTenant`. +2. `internal/controller/provisioner` receives the reconcile event and delegates into `internal/app/provisioner`. +3. `internal/service/provisioner` applies namespace-scoped RBAC, policy labels, allowlists, and quota defaults. + +This keeps tenant onboarding separate from steady-state cluster reconciliation and makes the tenant boundary explicit before any workload resources exist. + +Day 0 also defines the handoff into Day 1. In multi-tenant mode, `OpenBaoCluster` controllers wait until the tenant `RoleBinding` exists before they begin finalizer, status, or workload mutation in that namespace. + +>K8s: Create OpenBaoTenant + K8s-->>Ctrl: Watch OpenBaoTenant + Ctrl->>App: Reconcile tenant request + App->>Manager: Apply tenant provisioning contract + Manager->>Namespace: Create tenant Role / RoleBinding + Manager->>Namespace: Apply Pod Security labels when configured to own them + Manager->>Namespace: Apply optional quota defaults + Manager->>Namespace: Sync Secret allowlist roles + Namespace-->>Admin: Namespace ready for OpenBaoCluster + Namespace-->>K8s: Tenant RoleBinding exists + K8s-->>Ctrl: OpenBaoCluster reconcile may proceed + `} +/> + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/lifecycle/day1-creation.md b/website/versioned_docs/version-0.3.0/architecture/lifecycle/day1-creation.md new file mode 100644 index 000000000..ca77d0fea --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/lifecycle/day1-creation.md @@ -0,0 +1,227 @@ +--- +title: Day 1 Creation +hide_title: true +pageType: concept +journey: architecture +description: Cluster creation flow from OpenBaoCluster creation through TLS bootstrap, one-node initialization, autopilot configuration, and scale-out. +--- + + + + + + + +## Architectural placement + +Day 1 creation crosses the workload-side services in sequence: + +1. The cert manager ensures TLS material exists or is ready to be observed. +2. The bootstrap manager renders config and startup prerequisites. +3. The networking and identity managers create the service and RBAC surfaces the workload needs. +4. The workload manager holds the StatefulSet at one replica and applies rollout-safe workload resources. +5. The init manager initializes the cluster, configures autopilot defaults, and only then allows scale-out. + +That split keeps first-boot safety logic separate from routine steady-state reconciliation. + +>K8s: Create OpenBaoCluster + K8s-->>Certs: Reconcile TLS state + Certs->>K8s: Create or validate TLS material + K8s-->>Bootstrap: Render config and bootstrap prerequisites + Bootstrap->>K8s: Apply ConfigMaps, seal prerequisites, and startup config + K8s-->>Networking: Reconcile service and network surfaces + Networking->>K8s: Apply Services, Ingress or Gateway, and NetworkPolicy + K8s-->>Identity: Reconcile workload identity + Identity->>K8s: Apply ServiceAccount and RBAC + K8s-->>Workload: Reconcile workload state + Workload->>K8s: Render StatefulSet at replicas=1 + Workload->>Pod0: Start first pod + Pod0-->>Init: Pod ready and API reachable + Init->>Pod0: Detect initialized or perform init + Init->>K8s: Set initialized status + Init->>Pod0: Configure autopilot defaults + K8s-->>Workload: Initialization confirmed + Workload->>K8s: Scale StatefulSet to spec.replicas + `} +/> + + + + + + + + + + +Self-init requires an auto-unseal mechanism. In exchange, it avoids creating a root-token Secret and keeps bootstrap closer to OpenBao’s native startup path. + + + + + + +-root-token`, and initialization status is patched back to the cluster.', + 'After initialization and autopilot configuration complete, the workload manager scales the StatefulSet to the requested replica count.', + ]} +/> + + + +Static auto-unseal requires OpenBao v2.4.0 or later. Older versions need a supported external KMS seal instead of the built-in static seal path. + + + + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/lifecycle/day2-operations.md b/website/versioned_docs/version-0.3.0/architecture/lifecycle/day2-operations.md new file mode 100644 index 000000000..0cffe3951 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/lifecycle/day2-operations.md @@ -0,0 +1,200 @@ +--- +title: Day 2 Operations +hide_title: true +pageType: concept +journey: architecture +description: Operational lifecycle for upgrades, maintenance controls, and long-running admin operations after the cluster is live. +--- + + + + + + + + + +## Architectural placement + +Day 2 work is intentionally separated from the high-churn workload loop: + +1. Workload reconciliation continues to own the steady-state pod, Service, and config contract. +2. Admin operations orchestration takes over when a change requires long-running coordination such as upgrade or backup. +3. `internal/service/opslifecycle` keeps disruptive operations consistent around lock ownership, retry timing, and audit fields. + +That separation prevents upgrades, backups, and other long-running workflows from blocking normal workload repair. + + AdminOps["AdminOps orchestration"] + AdminOps --> Upgrade["Upgrade manager"] + AdminOps --> Backup["Backup manager"] + Upgrade --> Lifecycle["Operation lifecycle"] + Backup --> Lifecycle + Lifecycle --> Lock["status.operationLock"] + Upgrade --> Status["Upgrade and blue-green status"] + Backup --> BackupStatus["status.backup"] + Workload["Workload reconcile loop"] --> Ready["Steady-state pod repair"] + + classDef read fill:transparent,stroke:#79c0ab,stroke-width:2px,color:#e6f4ef; + classDef process fill:transparent,stroke:#fdd0a4,stroke-width:2px,color:#f8fafc; + classDef write fill:transparent,stroke:#87d6be,stroke-width:2px,color:#e6f4ef; + + class Drift,Workload read; + class AdminOps,Upgrade,Backup,Lifecycle process; + class Lock,Status,BackupStatus,Ready write;`} +/> + + + + + + + + + + + + + + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/lifecycle/dayN-backups.md b/website/versioned_docs/version-0.3.0/architecture/lifecycle/dayN-backups.md new file mode 100644 index 000000000..d28091fe3 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/lifecycle/dayN-backups.md @@ -0,0 +1,176 @@ +--- +title: Day N Backups And Restore +hide_title: true +pageType: concept +journey: architecture +description: Backup and restore lifecycle for live clusters, including snapshot scheduling, status surfaces, retention, and explicit restore requests. +--- + + + + + + + + + +## Architectural placement + +Durability work is shared across two explicit operation surfaces: + +1. The backup manager lives on the adminops path and handles scheduled, manual, and pre-upgrade snapshot jobs. +2. The restore manager runs through the dedicated `OpenBaoRestore` controller path so destructive recovery stays explicit and auditable. +3. `internal/service/opslifecycle` supplies shared lock and retry behavior so backups, restores, and upgrades coordinate instead of colliding. + +That model keeps backup routine and restore exceptional, even though both exist in the same durability phase of the lifecycle. + + Backup["Backup manager"] + Backup --> Job["Snapshot executor Job"] + Job --> Storage["Object storage"] + Job --> BackupStatus["status.backup"] + Storage --> RestoreReq["OpenBaoRestore request"] + RestoreReq --> Restore["Restore manager"] + Restore --> Lock["status.operationLock"] + Restore --> RestoreJob["Restore Job"] + RestoreJob --> Cluster["Cluster restored or follow-up required"] + + classDef read fill:transparent,stroke:#79c0ab,stroke-width:2px,color:#e6f4ef; + classDef process fill:transparent,stroke:#fdd0a4,stroke-width:2px,color:#f8fafc; + classDef write fill:transparent,stroke:#87d6be,stroke-width:2px,color:#e6f4ef; + classDef critical fill:transparent,stroke:#dc2626,stroke-width:2px,color:#f8fafc; + + class Schedule,RestoreReq read; + class Backup,Job,Restore,RestoreJob process; + class Storage,BackupStatus,Lock write; + class Cluster critical;`} +/> + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/lifecycle/index.md b/website/versioned_docs/version-0.3.0/architecture/lifecycle/index.md new file mode 100644 index 000000000..9af5698e2 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/lifecycle/index.md @@ -0,0 +1,79 @@ +--- +title: Lifecycle Architecture +hide_title: true +pageType: landing +journey: architecture +description: Lifecycle overview for OpenBao Operator from Day 0 provisioning through Day 1 creation, Day 2 operations, and backup-and-restore flows. +--- + + + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/operation-lifecycle.md b/website/versioned_docs/version-0.3.0/architecture/operation-lifecycle.md new file mode 100644 index 000000000..4505ff4f3 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/operation-lifecycle.md @@ -0,0 +1,196 @@ +--- +title: Operation Lifecycle Coordination +hide_title: true +pageType: concept +journey: architecture +description: Shared lock, retry, and phase-audit primitives used by backup, restore, and upgrade managers. +--- + + + + + + + +## Architectural placement + +Operation lifecycle coordination sits below the concrete managers and owns the shared lock write path: + +1. A manager such as backup, restore, or upgrade decides it needs to start or resume work. +2. It uses `internal/service/opslifecycle` to acquire or release the expected lock identity, classify retry intent, and log phase changes. +3. `opslifecycle` applies `status.operationLock` directly through the shared SSA lock plane. + +That keeps the shared safety model in one place instead of scattering lock and retry semantics across several managers. + + + + Ops["Operation lifecycle"] + Restore["Restore manager"] --> Ops + Upgrade["Upgrade manager"] --> Ops + Ops --> Lock["Operation lock status writer"] + Ops --> Retry["Retry classes"] + Ops --> Audit["Phase audit logging"] + Lock --> Status["OpenBaoCluster.status.operationLock"] + + classDef read fill:transparent,stroke:#79c0ab,stroke-width:2px,color:#e6f4ef; + classDef process fill:transparent,stroke:#fdd0a4,stroke-width:2px,color:#f8fafc; + classDef write fill:transparent,stroke:#87d6be,stroke-width:2px,color:#e6f4ef; + + class Backup,Restore,Upgrade read; + class Ops,Retry,Audit process; + class Lock process; + class Status write;`} +/> + + + +## Retry and lock model + + + + + + + +`opslifecycle` does not decide whether an upgrade should roll or blue-green, whether a restore request is valid, or whether a backup target is reachable. It only standardizes the lock, retry, and audit mechanics around those domain decisions. + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/operator-invariants.md b/website/versioned_docs/version-0.3.0/architecture/operator-invariants.md new file mode 100644 index 000000000..b66439400 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/operator-invariants.md @@ -0,0 +1,247 @@ +--- +title: Operator Invariants +description: Cross-cutting invariants preserved by OpenBao Operator across identity boundaries, production posture, configuration ownership, and lifecycle safety. +hide_title: true +pageType: concept +journey: architecture +--- + + + + + + + +`OpenBaoCluster` is an operator-owned lifecycle contract. It is not a generic import API for arbitrary unmanaged OpenBao clusters. + + + + + +## Identity boundary invariants + + + +Related reading: RBAC Architecture, Admission Policies, and Operator Identity and Access. + +## Production posture invariants + + + +Related reading: Security Profiles, TLS and Identity, and Self-Initialization. + +## Integration invariants + + + +Related reading: Status and Events, Observability, and Configure Backups. + +## Lifecycle safety invariants + + + +Related reading: Operation Lifecycle, Restore from Backup, and Recovery and Restore. + + + +If a change weakens one of these invariants, update the related architecture, security, and user-guide pages in the same change set. It changes the product operating contract. + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/provisioner-manager.md b/website/versioned_docs/version-0.3.0/architecture/provisioner-manager.md new file mode 100644 index 000000000..612b34650 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/provisioner-manager.md @@ -0,0 +1,174 @@ +--- +title: Provisioner Manager +hide_title: true +pageType: concept +journey: architecture +description: Provision tenant namespaces with scoped RBAC, Secret allowlists, Pod Security label ownership, and quota defaults for OpenBaoTenant. +--- + + + + + + + +## Architectural placement + +Provisioning follows a dedicated tenant-controller path: + +1. `internal/controller/provisioner` receives the reconcile event for `OpenBaoTenant`. +2. The controller delegates orchestration to `internal/app/provisioner`. +3. The app layer invokes `internal/service/provisioner` to apply RBAC, labels, allowlists, and cleanup behavior. + +That keeps tenant onboarding separate from `OpenBaoCluster` steady-state reconciliation while still using the same design system and policy language. + +The tenant `RoleBinding` is also the explicit handoff marker into the cluster controllers. Until that object exists, `OpenBaoCluster` workload, admin-operations, and status reconciliation pause and requeue instead of trying to mutate resources in a namespace that is not yet provisioned. + + + +## Provisioning flow + + Ctrl["Provisioner controller"] + Ctrl --> App["internal/app/provisioner"] + App --> Manager["Provisioner manager"] + Manager --> RBAC["Tenant Role / RoleBinding"] + Manager --> Secrets["Reader / writer Secret allowlists"] + Manager -. enforce mode .-> Labels["Pod Security labels"] + Manager --> Quotas["ResourceQuota / LimitRange"] + Quotas --> Ready["Tenant namespace ready for OpenBaoCluster"] + + classDef read fill:transparent,stroke:#79c0ab,stroke-width:2px,color:#e6f4ef; + classDef process fill:transparent,stroke:#fdd0a4,stroke-width:2px,color:#f8fafc; + classDef write fill:transparent,stroke:#87d6be,stroke-width:2px,color:#e6f4ef; + + class Tenant read; + class Ctrl,App,Manager process; + class RBAC,Secrets,Labels,Quotas,Ready write;`} +/> + + + + + + diff --git a/website/versioned_docs/version-0.3.0/architecture/restore-manager.md b/website/versioned_docs/version-0.3.0/architecture/restore-manager.md new file mode 100644 index 000000000..590892f02 --- /dev/null +++ b/website/versioned_docs/version-0.3.0/architecture/restore-manager.md @@ -0,0 +1,176 @@ +--- +title: Restore Manager +hide_title: true +pageType: concept +journey: architecture +description: Reconcile OpenBaoRestore requests, acquire operation locks, and orchestrate restore jobs as explicit destructive workflows. +--- + + + + + + + +## Request model + +