Skip to content

[apps] [foundationdb] Initial support for FoundationDB operator - #1397

Merged
Timofei Larkin (lllamnyp) merged 13 commits into
cozystack:mainfrom
insignia96:feat/add-foundationdb-operator
Oct 10, 2025
Merged

[apps] [foundationdb] Initial support for FoundationDB operator#1397
Timofei Larkin (lllamnyp) merged 13 commits into
cozystack:mainfrom
insignia96:feat/add-foundationdb-operator

Conversation

@insignia96

@insignia96 Isaiah Olson (insignia96) commented Sep 7, 2025

Copy link
Copy Markdown
Contributor

What this PR does

This PR adds initial support to begin testing managed FoundationDB instances in Cozystack. Addresses #824

Release note

[apps] Add FoundationDB as a managed app for tenants
[foundationdb] Add fdb-kubernetes-operator with v2.13.0

Summary by CodeRabbit

  • New Features
    • Introduced a managed FoundationDB app with configurable sizing, redundancy, and storage.
    • Optional S3 backups and automated replacements.
    • Built-in monitoring with WorkloadMonitor and dashboard resource map.
    • Secure defaults (non-root user/group) and unified image support.
  • Platform
    • Added FoundationDB Operator to platform bundles for automated cluster management.
    • Exposed FoundationDB in the catalog with UI/API schema integration.
  • Documentation
    • New README with setup, configuration, and best practices.
  • Tests
    • Added end-to-end test covering full FoundationDB lifecycle.

@coderabbitai

coderabbitai Bot commented Sep 7, 2025

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Introduces a new managed FoundationDB app and its Helm chart, values, schema, and templates; registers it in Cozystack API and versions map; adds platform bundle entries. Vendors an upstream FoundationDB operator chart with templates/CRDs and config. Adds an end-to-end BATs test validating deployment, monitoring, RBAC, PVCs, and cleanup.

Changes

Cohort / File(s) Summary
E2E Test
hack/e2e-apps/foundationdb.bats
New BATs test that creates a FoundationDB CR in tenant-test, waits for HelmRelease/cluster readiness, validates status, pods, WorkloadMonitor, ConfigMap, PVCs, security context, then deletes the resource.
App Chart: FoundationDB (Helm metadata/docs/build)
packages/apps/foundationdb/Chart.yaml, packages/apps/foundationdb/.helmignore, packages/apps/foundationdb/Makefile, packages/apps/foundationdb/README.md, packages/apps/foundationdb/charts/cozy-lib
Adds Helm chart metadata, ignores Makefile, build helper Makefile, README, and cozy-lib chart link.
App Chart: Values and Schema
packages/apps/foundationdb/values.yaml, packages/apps/foundationdb/values.schema.json
Adds default values and JSON Schema covering cluster config, storage, resources, backups, monitoring, securityContext, and imageType.
App Chart: Core Templates
packages/apps/foundationdb/templates/cluster.yaml, packages/apps/foundationdb/templates/_resources.tpl
Adds FoundationDBCluster template and helper templates for labels, resources, chart id, and minReplicas logic.
App Chart: Monitoring and Dashboard
packages/apps/foundationdb/templates/workloadmonitor.yaml, packages/apps/foundationdb/templates/dashboard-resourcemap.yaml
Conditionally renders WorkloadMonitor and a dashboard resourcemap ConfigMap, tied to monitoring.enabled and backups.
App Chart: RBAC + SA
packages/apps/foundationdb/templates/serviceaccount.yaml, packages/apps/foundationdb/templates/role.yaml, packages/apps/foundationdb/templates/rolebinding.yaml
Adds ServiceAccount, Role, and RoleBinding for the app release.
API Registration + Version Map
packages/apps/versions_map, packages/system/cozystack-api/openapi-schemas/foundationdb.json, packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml
Registers foundationdb in versions_map, links OpenAPI schema to values.schema.json, and adds CozystackResourceDefinition for foundationdb and kafka.
Platform Bundles
packages/core/platform/bundles/distro-full.yaml, .../distro-hosted.yaml, .../paas-full.yaml, .../paas-hosted.yaml
Adds foundationdb-operator release entries with namespace, chart, optional flag, and dependencies.
Operator Chart: Top-level
packages/system/foundationdb-operator/Chart.yaml, packages/system/foundationdb-operator/.helmignore, packages/system/foundationdb-operator/Makefile, packages/system/foundationdb-operator/values.yaml
Adds operator chart scaffolding, ignore, update workflow to vendor upstream v2.13.0, and aggregation values.
Operator Chart: Vendored fdb-operator
packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml, .../templates/_helpers.tpl, .../templates/manager/deployment.yaml, .../templates/rbac/*, .../templates/NOTES.txt, .../crds/apps.foundationdb.org_foundationdbrestores.yaml, .../values.yaml
Vendors fdb-operator chart v0.2.0 (appVersion v2.13.0) with Deployment, RBAC, SA, helper templates, NOTES, CRD for FoundationDBRestore, and defaults including initContainers for FDB binaries.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant CSA as Cozystack API
  participant HR as HelmRelease/Controller
  participant CH as Chart (foundationdb)
  participant OP as FDB Operator
  participant K8s as Kubernetes

  U->>CSA: Apply CozystackResource (FoundationDB)
  CSA->>HR: Reconcile to HelmRelease
  HR->>CH: Render templates (Cluster, RBAC, WM, Backup)
  CH->>K8s: Create ServiceAccount/Role/RoleBinding
  CH->>K8s: Create FoundationDBCluster
  opt monitoring.enabled
    CH->>K8s: Create WorkloadMonitor
    CH->>K8s: Create dashboard resourcemap ConfigMap
  end
  opt backup.enabled
    CH->>K8s: Create Secret (S3 creds)
    CH->>K8s: Create FoundationDBBackup
  end
  OP->>K8s: Reconcile FDBCluster to Pods/PVCs
  K8s-->>OP: Pod/PVC statuses
  OP-->>K8s: Update FDBCluster status
  K8s-->>HR: Resources Ready
  HR-->>CSA: HelmRelease Ready
  CSA-->>U: Resource Ready
Loading
sequenceDiagram
  autonumber
  actor T as E2E Test
  participant API as Kubernetes API
  participant HR as HelmRelease
  participant FDBC as FoundationDBCluster
  participant Pods as FDB Pods/PVCs

  T->>API: Apply FoundationDB (CR) via here-doc
  T-->>API: Wait(HelmRelease ready)
  API-->>T: HR ready
  T-->>API: Poll(FDBCluster exists)
  API-->>T: FDBCluster present
  T-->>API: Poll(status fields healthy/available)
  API-->>T: Healthy status
  T-->>API: Verify Pods (counts, states), PVC sizes, SA securityContext
  T-->>API: Verify WorkloadMonitor and ConfigMap
  T->>API: Delete FoundationDB
  T-->>API: Confirm FDBCluster removed
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Possibly related PRs

Suggested reviewers

  • kvaps
  • klinch0

Poem

A rabbit taps its helm with glee,
Charts unfurl for F‑D‑B.
Operators hop to tend the rows,
Pods sprout up in tidy rows.
Monitors blink, backups stand by—
“All green!” the bunny squeaks, “oh my!” 🐇📦

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately describes the primary change—adding initial support for the FoundationDB operator—and follows the repository’s tagging convention ([apps] [foundationdb]). It is concise, specific, and informative for reviewers scanning the commit history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between edc12e3 and 857416d.

📒 Files selected for processing (2)
  • packages/core/platform/bundles/paas-full.yaml (1 hunks)
  • packages/core/platform/bundles/paas-hosted.yaml (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@lllamnyp

Copy link
Copy Markdown
Member

Hi Isaiah Olson (@insignia96) !

Thanks for taking the time to contribute to Cozystack. This looks really cool! Ping us up once you're ready to mark this PR as ready for review and we'll be happy to test your addition.

@lllamnyp

Copy link
Copy Markdown
Member

By the way, could you please run make generate for the Makefile in ./packages/system/cozystack-api and update ./packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml with a config for the new app? The format there should be pretty self-explanatory.

@insignia96

Isaiah Olson (insignia96) commented Sep 9, 2025

Copy link
Copy Markdown
Contributor Author

Thanks Timofei Larkin (@lllamnyp) ! I appreciate the feedback. This is still a WIP as I am working on getting an environment for testing. I was wondering about generating the API parts so that is very helpful. I am still working on figuring out how to use my bare-metal nodes to run the tests. Can you run the actual E2E tests on the buildkit or do you use some other method to run the tests on a bare-metal node in the cluster?

@lllamnyp

Copy link
Copy Markdown
Member

If you were to mark this as ready for review, we would be able to run tests on our runners. We do in fact run tests with buildkit, essentially, we have a powerful metal server that fires up three qemu-kvm nodes for cozystack and runs everything inside of them. If you already have a Cozystack cluster running, you could install your new build on top of that, by running make apply from a number of directories in your local environment. Can't give exact steps off the top of my head, I'll see if I can get you some more detailed instructions.

@insignia96

Copy link
Copy Markdown
Contributor Author

Timofei Larkin (@lllamnyp) I have marked this as ready for review after making the changes you mentioned. I do have one bare metal node in my cluster that could work to run the test setup in the repo. I am working on getting that set up to test on my end as well.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/system/cozystack-api/openapi-schemas/foundationdb.json (1)

1-203: File mixes a path shim with full JSON; invalid format.

Keep only the relative path line (repo convention) or keep only valid JSON, not both. The current file won’t parse.

Apply:

-../../../apps/foundationdb/values.schema.json
-  "$schema": "http://json-schema.org/draft-07/schema#",
-  "type": "object",
-  "properties": {
-    ...
-  }
-}
+../../../apps/foundationdb/values.schema.json

Also run make generate in ./packages/system/cozystack-api to refresh templates/cozystack-resource-definitions.yaml as requested in review.

🧹 Nitpick comments (36)
packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (4)

66-70: Tighten destinationClusterName validation to DNS-1123 label.

This field references a Kubernetes object name; add basic constraints.

               destinationClusterName:
-                type: string
+                type: string
+                minLength: 1
+                maxLength: 63
+                pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$'

39-59: Clarify required fields for blobStoreConfiguration; add CEL guard.

As written, only accountName is required. Usually a location (e.g., bucket or backupName) must also be provided. Align with upstream contract and enforce via CEL.

               blobStoreConfiguration:
                 properties:
                   accountName:
                     maxLength: 100
                     type: string
                   backupName:
                     maxLength: 1024
                     type: string
                   bucket:
                     maxLength: 63
                     minLength: 3
                     type: string
                   urlParameters:
                     items:
                       maxLength: 1024
                       type: string
                     maxItems: 100
                     type: array
                 required:
                   - accountName
                 type: object
+                x-kubernetes-validations:
+                  - rule: "has(self.bucket) || has(self.backupName)"
+                    message: "Provide at least one of bucket or backupName."

If upstream requires different fields, mirror that instead.


20-27: Expose destination in printer columns for quick UX.

Adds a useful column without changing behavior.

   - additionalPrinterColumns:
     - jsonPath: .metadata.creationTimestamp
       name: Age
       type: date
     - jsonPath: .status.state
       name: State
       type: string
+    - jsonPath: .spec.destinationClusterName
+      name: Destination
+      type: string
     name: v1beta2

1-3: CRD upgrade caveat with Helm: document/plan CRD lifecycle.

CRDs under charts/*/crds aren't upgraded by helm upgrade. Plan for manual CRD updates or separate chart, and note it in release notes/migration docs.

packages/system/foundationdb-operator/.helmignore (1)

1-1: Keep Makefile out of the chart — LGTM; consider anchoring and wildcard.

Works as-is. Minor nit: anchor to chart root and ignore possible variants.

-Makefile
+/Makefile
+/Makefile.*
packages/apps/foundationdb/.helmignore (1)

1-1: LGTM; same nit about anchoring/wildcard.

Keeps build helper out of package. Optional improvement below.

-Makefile
+/Makefile
+/Makefile.*
packages/system/foundationdb-operator/values.yaml (2)

1-4: Cluster-scoped RBAC enabled — confirm intent and PoLP.

fdb-operator.globalMode.enabled: true creates ClusterRole/ClusterRoleBinding; nodeReadClusterRole: true adds node read permissions. Confirm this is required for your multi-namespace deployment; otherwise prefer namespace-scoped Roles (set globalMode.enabled: false) to reduce blast radius. Also verify the subchart is named fdb-operator so these values are correctly scoped.


4-4: Add trailing newline.

Fix YAML linter warning.

-  nodeReadClusterRole: true
+  nodeReadClusterRole: true
+
packages/system/foundationdb-operator/Chart.yaml (1)

3-3: Add trailing newline.

Fix YAML lint error.

-version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
+version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
+
packages/apps/foundationdb/values.yaml (1)

73-73: Add trailing newline.

Fix YAML lint error.

-  automaticReplacements: true
+  automaticReplacements: true
+
packages/apps/foundationdb/values.schema.json (2)

112-161: Conditionally require backup fields when enabled.

Guardrails to prevent half‑configured backups.

Example:

 }
-  }
+  },
+  "allOf": [
+    {
+      "if": { "properties": { "backup": { "properties": { "enabled": { "const": true } } } } },
+      "then": {
+        "properties": {
+          "backup": {
+            "properties": {
+              "s3": {
+                "required": ["bucket", "region"]
+              }
+            }
+          }
+        }
+      }
+    }
+  ]

66-81: Optionally restrict storage.size format.

Add a pattern to catch typos (e.g., “16Gii”).

         "size": {
           "type": "string",
           "default": "16Gi",
           "title": "Storage size",
-          "description": "Size of persistent volumes for each instance"
+          "description": "Size of persistent volumes for each instance",
+          "pattern": "^[0-9]+(Ki|Mi|Gi|Ti)$"
         },
packages/system/foundationdb-operator/Makefile (2)

6-19: Parametrize upstream, add safety flags, and .PHONY.

Improve maintainability and robustness; address checkmake hints.

+SHELL := /bin/bash
+FDB_OPERATOR_TAG ?= v2.13.0
+.PHONY: update clean all test
+
 update:
-	rm -rf charts
-	git clone --depth 1 --branch v2.13.0 https://github.com/FoundationDB/fdb-kubernetes-operator.git tmp-repo
+	set -euo pipefail
+	rm -rf charts tmp-repo
+	git clone --depth 1 --branch $(FDB_OPERATOR_TAG) https://github.com/FoundationDB/fdb-kubernetes-operator.git tmp-repo
 	mkdir -p charts
 	cp -r tmp-repo/charts/fdb-operator charts/
 	# Remove symlinked CRDs and replace with actual files
 	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbbackups.yaml
 	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbclusters.yaml
 	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
 	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbbackups.yaml charts/fdb-operator/crds/
 	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml charts/fdb-operator/crds/
 	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbrestores.yaml charts/fdb-operator/crds/
-	rm -rf tmp-repo
+	rm -rf tmp-repo
 	rm -rf charts/fdb-operator/charts

Also keep Chart.yaml dependency version in sync with $(FDB_OPERATOR_TAG).


6-6: Target length warning.

Consider factoring CRD copy into a helper target if your lint enforces max body length.

packages/system/foundationdb-operator/charts/fdb-operator/templates/NOTES.txt (1)

3-6: Polish NOTES phrasing and kubectl example.

Minor grammar and use the common “deploy” shorthand.

-To see the logs of the operator you can use below command
-kubectl logs deployment/{{ include "fdb-operator.fullname" . }} -n {{ .Release.Namespace }} -f
+To see operator logs, run:
+kubectl logs deploy/{{ include "fdb-operator.fullname" . }} -n {{ .Release.Namespace }} -f
packages/apps/foundationdb/Makefile (1)

3-4: Declare .PHONY and add a no‑op test/clean to satisfy linters.

Keeps local tooling quiet and consistent with other packages.

 include ../../../scripts/package.mk
 
+.PHONY: generate test clean all
 generate:
 	cozyvalues-gen -v values.yaml -s values.schema.json -r README.md
+
+test:
+	@true
+clean:
+	@true
+all: generate
packages/apps/foundationdb/Chart.yaml (1)

25-25: Add trailing newline.

Fix YAML lint error.

-appVersion: "7.4.1"
+appVersion: "7.4.1"
+
packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml (1)

3-3: Nit: fix capitalization and tighten metadata

Use “FoundationDB” capitalization in the description; consider adding kubeVersion and icon for polish.

-description: A Helm chart for foundationDB operator
+description: A Helm chart for the FoundationDB Operator
packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml (1)

9-16: Ensure imagePullSecrets shape matches SA schema

Kubernetes expects imagePullSecrets as [{name: ...}]. If values can be strings, this will render invalid YAML. Enforce object shape in values.schema or normalize here.

-{{- with .Values.serviceAccount.imagePullSecrets }}
-imagePullSecrets:
-  {{- toYaml . | nindent 2 }}
-{{- end }}
+{{- with .Values.serviceAccount.imagePullSecrets }}
+imagePullSecrets:
+  {{- range . }}
+  - {{- if kindIs "string" . -}}
+    name: {{ . }}
+    {{- else -}}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
+  {{- end }}
+{{- end }}
packages/apps/foundationdb/README.md (1)

61-72: Don’t encourage inline cloud credentials

Recommend Secret/secretRef over embedding keys in values. Replace the example with secretRef to avoid copy-paste leaks.

-  s3:
-    bucket: "my-fdb-backups"
-    endpoint: "https://s3.amazonaws.com"
-    region: "us-east-1"
-    credentials:
-      accessKeyId: "AKIA..."
-      secretAccessKey: "..."
+  s3:
+    bucket: "my-fdb-backups"
+    endpoint: "https://s3.amazonaws.com"
+    region: "us-east-1"
+    secretRef:
+      name: "fdb-backup-s3"
packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml (1)

21-25: Always set ServiceAccount namespace in subjects

Be explicit for both RoleBinding and ClusterRoleBinding to avoid ambiguity and future refactors moving the binding across namespaces.

 subjects:
 - kind: ServiceAccount
   name: {{ include "fdb-operator.serviceAccountName" . }}
-  {{- if .Values.globalMode.enabled }}
-  namespace: {{ .Release.Namespace }}
-  {{- end }}
+  namespace: {{ .Release.Namespace }}
hack/e2e-apps/foundationdb.bats (1)

47-49: Use fully qualified resource for Flux HelmRelease to reduce alias issues

Some clusters won’t have the hr shortname. Use the full GVK.

-  kubectl -n tenant-test wait hr foundationdb-\$name --timeout=180s --for=condition=ready
+  kubectl -n tenant-test wait helmrelease.helm.toolkit.fluxcd.io foundationdb-\$name --timeout=180s --for=condition=ready
packages/apps/foundationdb/templates/backup.yaml (4)

11-14: Prefer stringData over pre‑base64 encoding for Secrets.

Avoids accidental double-encoding and improves ergonomics.

Apply this diff:

 type: Opaque
-data:
-  AWS_ACCESS_KEY_ID: {{ .Values.backup.s3.credentials.accessKeyId | b64enc }}
-  AWS_SECRET_ACCESS_KEY: {{ .Values.backup.s3.credentials.secretAccessKey | b64enc }}
+stringData:
+  AWS_ACCESS_KEY_ID: {{ .Values.backup.s3.credentials.accessKeyId | quote }}
+  AWS_SECRET_ACCESS_KEY: {{ .Values.backup.s3.credentials.secretAccessKey | quote }}

42-44: Run as non‑root unless strictly required.

Root in backup pods is unnecessary in most setups; align with operator’s non-root posture.

Apply this diff:

-            securityContext:
-              runAsUser: 0
+            securityContext:
+              runAsNonRoot: true
+              runAsUser: 4059
+              runAsGroup: 4059
+              allowPrivilegeEscalation: false
+              readOnlyRootFilesystem: true
+              capabilities:
+                drop: ["ALL"]

If the backup image truly needs root, please justify and scope privileges minimally.


7-11: Unify labels via chart helper for consistency.

Reuse the shared labels helper to prevent drift across templates.

Apply this diff:

   labels:
-    app.kubernetes.io/name: foundationdb
-    app.kubernetes.io/instance: {{ .Release.Name }}
-    app.kubernetes.io/managed-by: {{ .Release.Service }}
+    {{- include "foundationdb.labels" . | nindent 4 }}

(Repeat the same replacement for the FoundationDBBackup metadata.labels.)

Also applies to: 22-24


56-64: Optional: allow using an existing Secret instead of creating one.

Common pattern: gate Secret creation and reference an externally‑managed secret.

I can send a follow-up patch adding:

  • Values: backup.s3.existingSecretName, backup.s3.createSecret (default true)
  • Conditional Secret rendering and reference.
    Want me to draft it?
packages/system/foundationdb-operator/charts/fdb-operator/values.yaml (3)

49-55: Consider lowering manager CPU requests or documenting rationale.

500m request/limit is high for idle operators; 100–200m is typical unless load-tested.

Apply this diff if appropriate:

 resources:
   limits:
-    cpu: 500m
+    cpu: 200m
     memory: 256Mi
   requests:
-    cpu: 500m
+    cpu: 100m
     memory: 256Mi

2-5: Supply‑chain hardening: support digest pinning.

Expose optional image.digest fields to allow tag+digest pinning.

I can open a small PR to add:

  • values: image.digest, initContainers.*.image.digest
  • template: use “repository@digest” when set, else fall back to tag.

70-70: Double‑check need for node‑read ClusterRole by default.

If not strictly required, default to false and document when to enable.

packages/apps/foundationdb/templates/_resources.tpl (1)

11-18: Labels helper looks good; ensure templates consume it consistently.

Several templates handcraft labels; prefer this helper everywhere.

packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl (1)

37-41: Version label source is reasonable; minor tweak.

If image.tag carries a “v” prefix inconsistently, consider falling back to Chart.AppVersion when tag is unset.

packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml (3)

43-67: Deterministic init container ordering.

Map iteration order is non-deterministic; sort versions for stable manifests.

Apply this diff:

-      {{- range $version, $params := .Values.initContainers }}
+      {{- $keys := keys .Values.initContainers | sortAlpha -}}
+      {{- range $idx, $version := $keys -}}
+      {{- $params := index $.Values.initContainers $version -}}
       - name: foundationdb-kubernetes-init-{{ $version | replace "." "-" }}
         image: {{ $params.image.repository }}:{{ $params.image.tag }}
         imagePullPolicy: {{ $params.image.pullPolicy }}
         args:

93-99: Add readinessProbe alongside liveness.

Avoids serving metrics-only readiness as a proxy; but minimally mirror liveness to readiness.

Apply this diff:

         livenessProbe:
           httpGet:
             path: /metrics
             port: metrics
+        readinessProbe:
+          httpGet:
+            path: /metrics
+            port: metrics

35-41: Harden security context with seccomp profile.

Set RuntimeDefault at pod/container level.

Apply this diff:

       securityContext:
         {{- toYaml .Values.securityContext | nindent 8 }}
+        seccompProfile:
+          type: RuntimeDefault
@@
         securityContext:
           {{- toYaml .Values.containerSecurityContext | nindent 10 }}
+          seccompProfile:
+            type: RuntimeDefault

Also applies to: 91-99

packages/apps/foundationdb/templates/cluster.yaml (2)

6-9: Use shared labels helper for consistency.

Prefer the chart helper to avoid label drift.

Apply this diff:

   labels:
-    app.kubernetes.io/name: foundationdb
-    app.kubernetes.io/instance: {{ .Release.Name }}
-    app.kubernetes.io/managed-by: {{ .Release.Service }}
+    {{- include "foundationdb.labels" . | nindent 4 }}

46-49: Reuse the resources helper consistently.

You already defined foundationdb.resources; use it instead of calling cozy‑lib directly.

Apply this diff:

-              resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resources.preset .Values.resources $) | nindent 16 }}
+              resources: {{- include "foundationdb.resources" . | nindent 16 }}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 356fea6 and 838457d.

⛔ Files ignored due to path filters (1)
  • packages/apps/foundationdb/logos/foundationdb.svg is excluded by !**/*.svg
📒 Files selected for processing (29)
  • hack/e2e-apps/foundationdb.bats (1 hunks)
  • packages/apps/foundationdb/.helmignore (1 hunks)
  • packages/apps/foundationdb/Chart.yaml (1 hunks)
  • packages/apps/foundationdb/Makefile (1 hunks)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/charts/cozy-lib (1 hunks)
  • packages/apps/foundationdb/templates/_resources.tpl (1 hunks)
  • packages/apps/foundationdb/templates/backup.yaml (1 hunks)
  • packages/apps/foundationdb/templates/cluster.yaml (1 hunks)
  • packages/apps/foundationdb/templates/dashboard-resourcemap.yaml (1 hunks)
  • packages/apps/foundationdb/templates/workloadmonitor.yaml (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
  • packages/apps/versions_map (1 hunks)
  • packages/system/cozystack-api/openapi-schemas/foundationdb.json (1 hunks)
  • packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml (1 hunks)
  • packages/system/foundationdb-operator/.helmignore (1 hunks)
  • packages/system/foundationdb-operator/Chart.yaml (1 hunks)
  • packages/system/foundationdb-operator/Makefile (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/NOTES.txt (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/values.yaml (1 hunks)
  • packages/system/foundationdb-operator/values.yaml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/values.yaml

[error] 73-73: no new line character at the end of file

(new-line-at-end-of-file)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml

[error] 2-2: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/Chart.yaml

[error] 25-25: no new line character at the end of file

(new-line-at-end-of-file)

packages/system/foundationdb-operator/values.yaml

[error] 4-4: no new line character at the end of file

(new-line-at-end-of-file)

packages/system/foundationdb-operator/Chart.yaml

[error] 3-3: no new line character at the end of file

(new-line-at-end-of-file)

packages/apps/foundationdb/templates/backup.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/templates/dashboard-resourcemap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml

[error] 7-7: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/templates/workloadmonitor.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml

[error] 4-4: syntax error: could not find expected ':'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml

[error] 4-4: syntax error: could not find expected ':'

(syntax)

packages/apps/foundationdb/templates/cluster.yaml

[error] 14-14: syntax error: expected the node content, but found '-'

(syntax)

🪛 checkmake (0.2.2)
packages/apps/foundationdb/Makefile

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

packages/system/foundationdb-operator/Makefile

[warning] 6-6: Target body for "update" exceeds allowed length of 5 (13).

(maxbodylength)


[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

🪛 Gitleaks (8.27.2)
hack/e2e-apps/foundationdb.bats

[high] 35-35: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (23)
packages/apps/versions_map (1)

36-36: Approve: foundationdb 0.1.0 — chart & API wiring verified

Chart.yaml shows name: foundationdb and version: 0.1.0; packages/apps/foundationdb/values.schema.json exists; packages/system/cozystack-api/openapi-schemas/foundationdb.json is present and injected into templates/cozystack-resource-definitions.yaml (lines ~312–320); versions_map entry (packages/apps/versions_map line 36) is "foundationdb 0.1.0 HEAD".

packages/apps/foundationdb/charts/cozy-lib (1)

1-1: Confirm pointer-file convention or switch to Helm file:// dependency.

Verification script produced no output — couldn't locate packages/apps/foundationdb/charts/cozy-lib or any Chart.yaml declaring cozy-lib. Manually verify whether pointer files are materialized by CI for this chart; if not, declare the library as a file:// dependency and vendor it into charts/.

  • Recommended Chart.yaml dependency:
dependencies:
  - name: cozy-lib
    version: 0.x.x
    repository: "file://../../../library/cozy-lib"
  • Ensure make deps / helm dependency build vendors cozy-lib into charts/ so helm lint/helm package work locally and during release.
packages/system/foundationdb-operator/Chart.yaml (1)

1-3: Confirm version auto‑bump path.

If CI sets chart version, ensure this file is included in that pipeline step.

packages/apps/foundationdb/values.yaml (1)

21-23: Clarify faultDomain value substitution.

The "$FDB_ZONE_ID" literal won’t be expanded by Helm; ensure templates replace it or document how users set it. Consider making this a template expression or a direct value field.

packages/apps/foundationdb/Chart.yaml (1)

21-25: Ensure icon path exists and is packaged.

Verify /logos/foundationdb.svg is present in chart or top‑level assets and included in packaging.

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml (1)

1-17: FYI: YAMLlint complains due to Helm directives at top of file

The reported YAMLlint error is a false positive on templating; rendering is fine.

packages/apps/foundationdb/README.md (1)

28-35: Version alignment note

Confirm the example cluster.version "7.4.1" is supported by the bundled operator (appVersion v2.13.0).

packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml (1)

311-330: ResourceDefinition looks consistent (prefix, schema, repo)

Matches existing patterns; release prefix aligns with E2E (foundationdb-).

Please run make generate in packages/system/cozystack-api and commit regenerated artifacts to keep CRDs/UI in sync.

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml (2)

1-7: YAMLlint error is due to templating (safe to ignore)

Helm conditionals before apiVersion trigger false positives.


26-44: Companion ClusterRole exists — no action required.

rbac_role.yaml renders {{ include "fdb-operator.fullname" . }}-clusterrole for both .Values.globalMode.enabled and .Values.nodeReadClusterRole (packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml).

hack/e2e-apps/foundationdb.bats (1)

19-21: Questionable faultDomain config

valueFrom: "$FDB_ZONE_ID" is unlikely to be a valid FoundationDBCluster field; consider removing or mapping to the operator’s supported fault domain settings.

-    faultDomain:
-      key: "foundationdb.org/none"
-      valueFrom: "\$FDB_ZONE_ID"
+    faultDomain:
+      key: "foundationdb.org/none"
packages/apps/foundationdb/templates/dashboard-resourcemap.yaml (2)

13-21: Indentation within block scalar is correct; ensure CRD version matches

Data maps to v1beta2 CRDs—confirm the operator chart ships v1beta2 CRDs.


1-3: YAMLlint false positive

Template gates cause the linter error; rendering is fine.

packages/apps/foundationdb/templates/workloadmonitor.yaml (2)

12-19: Double-check selector and version semantics

  • Ensure FDB pods carry app.kubernetes.io/name=foundationdb and instance={{ .Release.Name }}; otherwise WorkloadMonitor won’t pick them up.
  • Confirm WorkloadMonitor.spec.version expects the chart version, not FoundationDB cluster version.

1-3: YAMLlint false positive

Template guards trigger the reported linter error; safe to ignore.

packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml (1)

18-21: Version coherence check — FoundationDB operator v2.13.0

  • Chart: packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml contains appVersion: v2.13.0.
  • CRDs/templates: packages/apps/foundationdb/templates/* use apiVersion apps.foundationdb.org/v1beta2 (e.g. cluster.yaml, backup.yaml, dashboard-resourcemap.yaml).
  • No pinned operator image/tag/digest for fdb-kubernetes-operator was found in the repo (search returned no matches) — verify Helm values.yaml, chart dependencies, CI manifests and tests/schemas reference v2.13.0 or update/document the mismatch.
packages/apps/foundationdb/templates/backup.yaml (1)

1-1: YAMLlint error is a templating false positive.

The reported “expected node content” error stems from Helm templating delimiters; safe to ignore.

packages/apps/foundationdb/templates/_resources.tpl (1)

4-6: LGTM: resources helper delegates to cozy‑lib correctly.

Good reuse and centralization.

packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml (1)

31-31: Confirm serviceAccountName resolves without leading spaces.

Depends on fixing the helper; otherwise this field will be invalid at apply time.

Run: helm template ... | yq '.spec.template.spec.serviceAccountName' and verify no leading whitespace.

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml (2)

113-130: Good separation for node read access.

Optional ClusterRole for nodes is correctly isolated.


12-112: Do you want me to fetch the fdb-kubernetes-operator v2.13.0 RBAC manifests from upstream and compare them, or will you paste this chart’s Role/ClusterRole YAML here?

packages/apps/foundationdb/templates/cluster.yaml (1)

1-86: Resolved — FoundationDB added to Cozystack API templates

Verified packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml contains FoundationDB entries (lines ~312–325); the requested template addition is present.

packages/system/foundationdb-operator/charts/fdb-operator/values.yaml (1)

4-5: Confirm fdb-kubernetes-monitor image tags match FoundationDB server patch versions (operator v2.13.0)

Operator v2.13.0 expects the fdb-kubernetes-monitor image to be tagged to the matching FoundationDB server minor/patch—verify that foundationdb/fdb-kubernetes-monitor:7.1.67, :7.3.63, :7.4.1 are the exact server patches you will run, otherwise update them to the appropriate 7.1., 7.3., 7.4. (use the latest patch for each minor).

File: packages/system/foundationdb-operator/charts/fdb-operator/values.yaml lines 4-5

Comment thread hack/e2e-apps/foundationdb.bats Outdated
Comment on lines +34 to +36
accessKeyId: "oobaiRus9pah8PhohL1ThaeTa4UVa7gu"
secretAccessKey: "ju3eum4dekeich9ahM1te8waeGai0oog"
retentionPolicy: "7d"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove hardcoded secrets; use Secret refs

Even if backups are disabled, static credentials will trigger leak scanners and set bad precedent.

-      credentials:
-        accessKeyId: "oobaiRus9pah8PhohL1ThaeTa4UVa7gu"
-        secretAccessKey: "ju3eum4dekeich9ahM1te8waeGai0oog"
+      # credentials provided via a Secret when enabled
+      # secretRef:
+      #   name: fdb-backup-s3
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
accessKeyId: "oobaiRus9pah8PhohL1ThaeTa4UVa7gu"
secretAccessKey: "ju3eum4dekeich9ahM1te8waeGai0oog"
retentionPolicy: "7d"
# credentials provided via a Secret when enabled
# secretRef:
# name: fdb-backup-s3
retentionPolicy: "7d"
🧰 Tools
🪛 Gitleaks (8.27.2)

[high] 35-35: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In hack/e2e-apps/foundationdb.bats around lines 34 to 36, the file contains
hardcoded accessKeyId and secretAccessKey values which trigger secret scanners;
remove these literal credentials and replace them with references to secrets
(e.g., point to a Secret by name/key, an env var, or a placeholder that is
populated from the CI/k8s Secret) so the manifest no longer contains raw
secrets; ensure retentionPolicy remains unchanged and validate that the code
which reads these config entries can resolve the secret refs at runtime.

Comment thread hack/e2e-apps/foundationdb.bats Outdated
Comment on lines +50 to +55
blobStoreConfiguration:
accountName: {{ .Values.backup.s3.bucket }}
bucket: {{ .Values.backup.s3.bucket }}
{{- if .Values.backup.s3.endpoint }}
endpoint: {{ .Values.backup.s3.endpoint }}
{{- end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

❓ Verification inconclusive

Fix S3 config: drop accountName and wire region (per FDB operator spec).

S3 usually requires bucket, credentials, optional endpoint/region. Mapping bucket into accountName is likely wrong, and region is unused here.

Apply this diff:

   blobStoreConfiguration:
-    accountName: {{ .Values.backup.s3.bucket }}
     bucket: {{ .Values.backup.s3.bucket }}
+    {{- if .Values.backup.s3.region }}
+    region: {{ .Values.backup.s3.region }}
+    {{- end }}
     {{- if .Values.backup.s3.endpoint }}
     endpoint: {{ .Values.backup.s3.endpoint }}
     {{- end }}

If upstream requires accountName for non-S3 stores only, removing it is correct. Otherwise, parameterize it separately. Want me to adjust values.schema.json accordingly?


Fix S3 config: don't map bucket → accountName; pass region via urlParameters.

  • Remove the line accountName: {{ .Values.backup.s3.bucket }} — accountName is for credentials/host, not the bucket; parameterize it separately (e.g. .Values.backup.s3.accountName) or omit it. (pkg.go.dev)
  • The operator has no top-level region field — pass region as a URL parameter (urlParameters: - region=...) and wire .Values.backup.s3.region into urlParameters. (github.com)
  • Change file packages/apps/foundationdb/templates/backup.yaml (around lines 50–55): remove the incorrect mapping, add urlParameters for region, and move any host/port (endpoint) into accountName or urlParameters as appropriate. (pkg.go.dev)

Comment on lines +16 to +33
automationOptions:
replacements:
enabled: {{ .Values.advanced.automaticReplacements }}
faultDomain:
key: {{ .Values.cluster.faultDomain.key }}
{{- if .Values.cluster.faultDomain.valueFrom }}
valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
{{- end }}
imageType: {{ .Values.advanced.imageType }}
labels:
filterOnOwnerReference: false
matchLabels:
foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
processClassLabels:
- foundationdb.org/fdb-process-class
processGroupIDLabels:
- foundationdb.org/fdb-process-group-id
minimumUptimeSecondsForBounce: 60

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Validate spec fields against v1beta2 (faultDomain, routing, sidecarContainer).

These look right, but v2.13.0 occasionally adjusted field names/locations. Please confirm.

Also applies to: 81-86


🌐 Web query:

FoundationDB Kubernetes Operator v2.13.0 CRD: confirm fields for FoundationDBCluster.spec.automationOptions.faultDomain.*, .routing.defineDNSLocalityFields, .sidecarContainer.enable*.

💡 Result:

Confirmed fields (from the Operator docs / CRD examples):

  • spec.faultDomain.* — supported keys:

    • key (string).
    • value (string).
    • valueFrom (string) — e.g. spec.nodeName or a node label source.
    • zoneIndex (integer).
    • zoneCount (integer).
    • (You can also use special keys such as foundationdb.org/none or foundationdb.org/kubernetes-cluster). [1]
  • spec.routing.defineDNSLocalityFields (boolean) — true/false toggle to enable defining locality fields from DNS names. (Related routing flags such as useDNSInClusterFile also appear in examples.) [2]

  • spec.sidecarContainer.enable* — commonly used boolean flags:

    • sidecarContainer.enableTls (boolean).
    • sidecarContainer.enableLivenessProbe (boolean).
    • sidecarContainer.enableReadinessProbe (boolean).
    • (Sidecar image selection and imageConfigs live under spec.sidecarContainer as well.) [3][4]

Sources:

  • Fault-domain options and examples: FoundationDB operator fault_domains documentation. [1]
  • routing.defineDNSLocalityFields and routing examples: Operator sample/issue examples showing routing flags. [2]
  • sidecarContainer enable* flags, imageConfigs and warnings about probes/TLS: operator customization / TLS / warnings docs. [3][4]

If you want, I can fetch the exact CRD schema lines from the v2.13.0 tag and paste the YAML snippets.


Move spec.faultDomain out of automationOptions; routing and sidecar fields must be top-level.

v1beta2 expects spec.faultDomain (key, value, valueFrom, zoneIndex, zoneCount). (github.com)

routing.defineDNSLocalityFields belongs under spec.routing; sidecarContainer.enable* belong under spec.sidecarContainer. (github.com)

Current template nests faultDomain under automationOptions — move it to the spec level (packages/apps/foundationdb/templates/cluster.yaml lines 16–33; also applies to 81–86).

Comment on lines +175 to +201
"advanced": {
"type": "object",
"title": "Advanced Configuration",
"properties": {
"customParameters": {
"type": "array",
"title": "Custom parameters",
"description": "Custom FoundationDB parameters",
"items": {
"type": "string"
}
},
"imageType": {
"type": "string",
"enum": ["unified", "split"],
"default": "split",
"title": "Image type",
"description": "Container image deployment type"
},
"automaticReplacements": {
"type": "boolean",
"default": true,
"title": "Automatic replacements",
"description": "Enable automatic pod replacements"
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Schema missing advanced.securityContext present in values.yaml.

Users can’t validate or set securityContext via API without schema coverage.

Add:

       "automaticReplacements": {
         "type": "boolean",
         "default": true,
         "title": "Automatic replacements",
         "description": "Enable automatic pod replacements"
-        }
+        },
+        "securityContext": {
+          "type": "object",
+          "title": "Security context",
+          "properties": {
+            "runAsNonRoot": { "type": "boolean", "default": true },
+            "runAsUser":    { "type": "integer", "minimum": 0 },
+            "runAsGroup":   { "type": "integer", "minimum": 0 },
+            "allowPrivilegeEscalation": { "type": "boolean", "default": false }
+          }
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"advanced": {
"type": "object",
"title": "Advanced Configuration",
"properties": {
"customParameters": {
"type": "array",
"title": "Custom parameters",
"description": "Custom FoundationDB parameters",
"items": {
"type": "string"
}
},
"imageType": {
"type": "string",
"enum": ["unified", "split"],
"default": "split",
"title": "Image type",
"description": "Container image deployment type"
},
"automaticReplacements": {
"type": "boolean",
"default": true,
"title": "Automatic replacements",
"description": "Enable automatic pod replacements"
}
}
}
"advanced": {
"type": "object",
"title": "Advanced Configuration",
"properties": {
"customParameters": {
"type": "array",
"title": "Custom parameters",
"description": "Custom FoundationDB parameters",
"items": {
"type": "string"
}
},
"imageType": {
"type": "string",
"enum": ["unified", "split"],
"default": "split",
"title": "Image type",
"description": "Container image deployment type"
},
"automaticReplacements": {
"type": "boolean",
"default": true,
"title": "Automatic replacements",
"description": "Enable automatic pod replacements"
},
"securityContext": {
"type": "object",
"title": "Security context",
"properties": {
"runAsNonRoot": { "type": "boolean", "default": true },
"runAsUser": { "type": "integer", "minimum": 0 },
"runAsGroup": { "type": "integer", "minimum": 0 },
"allowPrivilegeEscalation": { "type": "boolean", "default": false }
}
}
}
}
🤖 Prompt for AI Agents
In packages/apps/foundationdb/values.schema.json around lines 175-201, the
schema is missing the advanced.securityContext entry present in values.yaml; add
an "securityContext" property under "advanced" (type: object) whose schema
either mirrors the Kubernetes Pod/Container SecurityContext fields (runAsUser,
runAsGroup, fsGroup, runAsNonRoot, seLinuxOptions, capabilities, etc.) with
appropriate types or references a reusable securityContext definition, and
include a descriptive title and description so clients can validate and set
securityContext via the API.

Comment thread packages/apps/foundationdb/values.yaml Outdated
Comment on lines +67 to +71
# Security context for containers
securityContext:
runAsUser: 0
runAsGroup: 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Defaults run containers as root; tighten security posture.

Running as UID/GID 0 by default is risky for a multi‑tenant platform. Default to non‑root and allow opt‑out.

-  securityContext:
-    runAsUser: 0
-    runAsGroup: 0
+  securityContext:
+    runAsNonRoot: true
+    runAsUser: 1001
+    runAsGroup: 1001
+    allowPrivilegeEscalation: false

Please confirm images support non‑root; if not, gate root under a clear flag (e.g., advanced.allowRoot: true).


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "PWD: $(pwd)"
echo "---- repo root listing ----"
ls -la

echo
echo "---- check for packages/apps/foundationdb/values.yaml ----"
if [ -f packages/apps/foundationdb/values.yaml ]; then
  echo "FOUND: packages/apps/foundationdb/values.yaml"
  echo "---- head of file ----"
  sed -n '1,200p' packages/apps/foundationdb/values.yaml
  echo
  echo "---- lines 60-80 ----"
  sed -n '60,80p' packages/apps/foundationdb/values.yaml || true
else
  echo "NOT FOUND: packages/apps/foundationdb/values.yaml"
fi

echo
echo "---- search for securityContext-related keys under packages/apps/foundationdb ----"
rg -n --hidden -S "securityContext|podSecurityContext|runAsUser|runAsGroup|runAsNonRoot|allowPrivilegeEscalation|fsGroup" packages/apps/foundationdb || true

echo
echo "---- search repo-wide for runAsUser: 0 and related defaults ----"
rg -n --hidden -S "runAsUser:\\s*0\\b|runAsGroup:\\s*0\\b|runAsNonRoot|allowPrivilegeEscalation" || true

echo
echo "---- search for image references under packages/apps/foundationdb ----"
rg -n --hidden -S "image:|repository:|imagePullPolicy|imagePullSecrets" packages/apps/foundationdb || true

Length of output: 83859


Defaults run containers as root — change default to non‑root and add an opt‑out

Confirmed: packages/apps/foundationdb/values.yaml sets advanced.securityContext.runAsUser: 0 / runAsGroup: 0 (values.yaml lines ~68–70) and the templates render it (packages/apps/foundationdb/templates/cluster.yaml lines ~48/58/69; packages/apps/foundationdb/templates/backup.yaml line ~42). Change the default to non‑root and gate root behind a clear flag if needed.

-  securityContext:
-    runAsUser: 0
-    runAsGroup: 0
+  securityContext:
+    runAsNonRoot: true
+    runAsUser: 1001
+    runAsGroup: 1001
+    allowPrivilegeEscalation: false

Confirm images support non‑root; if not, gate root with a flag (e.g., advanced.allowRoot: true).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Security context for containers
securityContext:
runAsUser: 0
runAsGroup: 0
# Security context for containers
securityContext:
runAsNonRoot: true
runAsUser: 1001
runAsGroup: 1001
allowPrivilegeEscalation: false
🤖 Prompt for AI Agents
In packages/apps/foundationdb/values.yaml around lines 67–71, the
securityContext defaults runAsUser/runAsGroup to 0 (root); change the default to
a non‑root uid/gid (e.g., 1000) and add a boolean opt‑out flag (e.g.,
advanced.allowRoot: false) so consumers can explicitly enable root when
required; then update the templates (templates/cluster.yaml and
templates/backup.yaml where securityContext is rendered) to conditionally set
runAsUser/runAsGroup to 0 only when advanced.allowRoot is true, otherwise render
the non‑root values (and ensure podSecurityContext/seccomp/apparmor remain
compatible); also add a note in values.yaml reminding maintainers to confirm
container images support running as non‑root before enabling allowRoot.

Comment on lines +1 to +3
apiVersion: v2
name: cozy-foundationdb-operator
version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing subchart dependency; operator chart won’t install the upstream chart.

Declare fdb-operator as a dependency (local file repo) so Helm includes it at render/install time.

Apply:

 apiVersion: v2
 name: cozy-foundationdb-operator
 version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
+dependencies:
+  - name: fdb-operator
+    version: 2.13.0
+    repository: "file://charts/fdb-operator"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
apiVersion: v2
name: cozy-foundationdb-operator
version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
apiVersion: v2
name: cozy-foundationdb-operator
version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
dependencies:
- name: fdb-operator
version: 2.13.0
repository: "file://charts/fdb-operator"
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 3-3: no new line character at the end of file

(new-line-at-end-of-file)

🤖 Prompt for AI Agents
In packages/system/foundationdb-operator/Chart.yaml lines 1-3, the chart lacks a
dependency entry for the upstream fdb-operator so Helm won't package/install it;
add a dependencies section declaring the fdb-operator as a local file repository
dependency (e.g. add dependencies: - name: fdb-operator, version:
<matching-version-or-*>, repository:
"file://<relative-path-to-fdb-operator-chart>") and save; after that run helm
dependency update (or ensure CI populates chart dependencies) so the upstream
chart is included at render/install time.

Comment on lines +29 to +37
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add top-level required: [spec] to enforce structural schema.

Without requiring spec, empty objects can be created and reconcile oddly.

       openAPIV3Schema:
         properties:
           apiVersion:
             type: string
           kind:
             type: string
           metadata:
             type: object
+        required:
+        - spec
         type: object
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
required:
- spec
type: object
🤖 Prompt for AI Agents
In
packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
around lines 29 to 37, the CRD's openAPIV3Schema is missing a top-level required
field for spec, allowing empty objects to be created; add a top-level required:
["spec"] entry alongside openAPIV3Schema (i.e., at the same level as properties)
so that spec is mandatory for the resource, ensuring the validator rejects
objects that omit spec.

Comment on lines +71 to +84
keyRanges:
items:
properties:
end:
pattern: ^[A-Za-z0-9\/\\-]+$
type: string
start:
pattern: ^[A-Za-z0-9\/\\-]+$
type: string
required:
- end
- start
type: object
type: array

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Key range regex is likely too restrictive; risk of rejecting valid restores.

FDB key ranges may include empty bounds or bytes outside [A-Za-z0-9/\\-]. Suggest dropping the regex and using length guards, or explicitly allowing empty strings for start/end.

                   properties:
                     end:
-                      pattern: ^[A-Za-z0-9\/\\-]+$
-                      type: string
+                      type: string
+                      maxLength: 4096
                     start:
-                      pattern: ^[A-Za-z0-9\/\\-]+$
-                      type: string
+                      type: string
+                      maxLength: 4096
                   required:
                     - end
                     - start
                   type: object

If empty bounds are valid in your operator semantics, also remove required or allow minLength: 0 and keep both required. Please confirm against upstream expectations.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "pwd: $(pwd)"
echo "Listing repo root (top-level):"
ls -la

echo "Searching for the CRD file path given in the review comment..."
if [ -f "packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml" ]; then
  echo "File found: packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml"
  echo "Printing lines 1..220 of that file:"
  sed -n '1,220p' packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
else
  echo "File not found at the exact path, searching repository for 'foundationdbrestores'..."
  rg -n "foundationdbrestores" || true
  echo "Searching for files that mention 'keyRanges'..."
  rg -n "keyRanges" || true
  echo "Searching for the specific regex pattern in the repo..."
  rg -n "pattern: \\^\\[A-Za-z0-9\\\\/\\\\\\\\-\\]\\+\\$" || true
fi

echo "Searching for other CRDs with similar patterns (looking for 'FoundationDBKeyRange' or pattern usage)..."
rg -n "FoundationDBKeyRange|pattern: \\^\\[A-Za-z0-9" || true

echo "Done."

Length of output: 9711


Remove restrictive regex on keyRanges.start/end in FoundationDBRestore CRD

The CRD at packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (lines ~75–78) uses pattern ^[A-Za-z0-9/\-]+$ for start/end, which will reject empty bounds and valid FoundationDB keys containing bytes outside that class — remove the pattern and instead use type: string with a length guard (e.g. maxLength: 4096) or set minLength: 0 if empty bounds are allowed; if empty bounds are valid, also remove the required constraint.

🤖 Prompt for AI Agents
In
packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
around lines 71 to 84, the CRD currently constrains keyRanges.start and
keyRanges.end with the restrictive regex ^[A-Za-z0-9\/\\-]+$ which rejects empty
bounds and many valid FoundationDB keys; remove the pattern entries and replace
them with plain type: string plus a length constraint such as maxLength: 4096
(or minLength: 0 if empty bounds are allowed), and if empty bounds must be
accepted remove the required entries for start/end accordingly so the CRD
permits empty or arbitrary byte-containing keys.

Comment on lines +54 to +59
{{- define "fdb-operator.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "fdb-operator.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Blocker: serviceAccountName helper emits leading spaces, breaking names.

The extra indentation becomes part of the value (e.g., " default"), producing invalid serviceAccount names.

Apply this diff:

 {{- define "fdb-operator.serviceAccountName" -}}
 {{- if .Values.serviceAccount.create -}}
-    {{ default (include "fdb-operator.fullname" .) .Values.serviceAccount.name }}
+{{- default (include "fdb-operator.fullname" .) .Values.serviceAccount.name -}}
 {{- else -}}
-    {{ default "default" .Values.serviceAccount.name }}
+{{- default "default" .Values.serviceAccount.name -}}
 {{- end -}}
 {{- end -}}

Re-render the deployment to ensure the value has no leading whitespace.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl"

if [ ! -f "$file" ]; then
  echo "MISSING_FILE: $file"
  exit 0
fi

echo "=== File excerpt (lines 1-200) ==="
sed -n '1,200p' "$file"
echo

echo "=== Helper block (lines 40-80) ==="
sed -n '40,80p' "$file"
echo

if command -v rg >/dev/null 2>&1; then
  echo "=== rg: lines that start with whitespace then '{{ default' ==="
  rg -n '^\s+\{\{\s*default' "$file" || true
  echo

  echo "=== Lines containing 'default' with visible spaces (spaces->·) ==="
  rg -n 'default' "$file" --line-number | cut -d: -f1 | uniq | while read -r ln; do
    printf "%4s: " "$ln"
    sed -n "${ln}p" "$file" | sed -e 's/ /·/g' -e 's/\t/→/g'
  done
else
  echo "rg not found; falling back to grep/awk"
  grep -nP '^\s+\{\{\s*default' "$file" || true
  awk '/default/ {print NR}' "$file" | sort -n | uniq | while read -r ln; do
    printf "%4s: " "$ln"
    sed -n "${ln}p" "$file" | sed -e 's/ /·/g' -e 's/\t/→/g'
  done
fi

Length of output: 3090


Blocker: serviceAccountName helper emits leading spaces, breaking names

Lines 56 and 58 in packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl have leading indentation before the {{ default ... }} blocks, which becomes part of the rendered serviceAccount name. Apply this diff:

 {{- define "fdb-operator.serviceAccountName" -}}
 {{- if .Values.serviceAccount.create -}}
-    {{ default (include "fdb-operator.fullname" .) .Values.serviceAccount.name }}
+{{- default (include "fdb-operator.fullname" .) .Values.serviceAccount.name -}}
 {{- else -}}
-    {{ default "default" .Values.serviceAccount.name }}
+{{- default "default" .Values.serviceAccount.name -}}
 {{- end -}}
 {{- end -}}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- define "fdb-operator.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "fdb-operator.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- define "fdb-operator.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{- default (include "fdb-operator.fullname" .) .Values.serviceAccount.name -}}
{{- else -}}
{{- default "default" .Values.serviceAccount.name -}}
{{- end -}}
{{- end -}}
🤖 Prompt for AI Agents
In
packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl
around lines 54 to 59 the serviceAccountName helper emits leading spaces because
the template lines contain indentation before the {{ default ... }} calls;
remove the leading spaces (or change to left-trimming tags) so the template
actions start at column 0 (e.g., use no indentation before {{ default ... }} or
use {{- default ... }} / {{ default ... -}} to trim) so the rendered
serviceAccount name has no leading whitespace.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (3)
packages/apps/foundationdb/values.yaml (2)

84-90: Default to non‑root; gate root behind an explicit flag.

Running containers as UID/GID 0 by default is risky. Default to non‑root and disallow privilege escalation; allow opt‑out only if images require root.

Apply:

 securityContext:
-  runAsUser: 0
-  runAsGroup: 0
+  runAsNonRoot: true
+  runAsUser: 1001
+  runAsGroup: 1001
+  allowPrivilegeEscalation: false

If some images need root, add an advanced.allowRoot: true flag and conditionally render 0 in templates.


64-67: Stop inlining S3 credentials; switch to Secret refs.

Plaintext keys in values are unsafe and leak via ConfigMaps and Git history. Use a Secret reference instead and adapt templates to read it.

Apply:

 backup:
   enabled: false
   s3:
     bucket: ""
     endpoint: ""
     region: "us-east-1"
-    credentials:
-      accessKeyId: ""
-      secretAccessKey: ""
+    secretRef:
+      name: ""            # required: Secret name in the release namespace
+      accessKeyKey: accessKeyId
+      secretKeyKey: secretAccessKey

Follow-up: update templates to consume .Values.backup.s3.secretRef via envFrom/secretKeyRef or lookup. Also document required Secret keys.

packages/apps/foundationdb/templates/cluster.yaml (1)

16-23: Move faultDomain to spec.faultDomain (not under automationOptions).

The CRD expects faultDomain at the top level of spec; nesting under automationOptions will be ignored/invalid. (github.com)

Apply:

   automationOptions:
     replacements:
       enabled: {{ .Values.automaticReplacements }}
-    faultDomain:
-      key: {{ .Values.cluster.faultDomain.key }}
-      {{- if .Values.cluster.faultDomain.valueFrom }}
-      valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
-      {{- end }}
-    imageType: {{ .Values.imageType }}
+  faultDomain:
+    key: {{ .Values.cluster.faultDomain.key }}
+    {{- if .Values.cluster.faultDomain.valueFrom }}
+    valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
+    {{- end }}

Place this block right under version/processCounts.

🧹 Nitpick comments (5)
packages/apps/foundationdb/values.yaml (1)

92-92: Add trailing newline.

YAMLlint flags missing newline at EOF.

Apply:

-automaticReplacements: true
+automaticReplacements: true
+
packages/apps/foundationdb/values.schema.json (2)

267-290: Extend securityContext and default to non‑root.

Reflect values.yaml change: add runAsNonRoot and allowPrivilegeEscalation; default uid/gid to 1001. Remove hard “required” to allow partial overrides.

Apply:

 "securityContext": {
   "description": "Security context for containers",
   "type": "object",
-  "default": {
-    "runAsGroup": 0,
-    "runAsUser": 0
-  },
-  "required": [
-    "runAsGroup",
-    "runAsUser"
-  ],
+  "default": {
+    "runAsNonRoot": true,
+    "allowPrivilegeEscalation": false,
+    "runAsGroup": 1001,
+    "runAsUser": 1001
+  },
   "properties": {
+    "runAsNonRoot": {
+      "description": "Require the container to run as a non-root user",
+      "type": "boolean",
+      "default": true
+    },
     "runAsGroup": {
       "description": "Group ID to run the container",
-      "type": "integer",
-      "default": 0
+      "type": "integer",
+      "default": 1001,
+      "minimum": 0
     },
     "runAsUser": {
       "description": "User ID to run the container",
-      "type": "integer",
-      "default": 0
+      "type": "integer",
+      "default": 1001,
+      "minimum": 0
+    },
+    "allowPrivilegeEscalation": {
+      "description": "Whether a process can gain more privileges than its parent process",
+      "type": "boolean",
+      "default": false
     }
   }
 }

298-301: Make storageClass optional.

Requiring storageClass forces users to set an empty string to pass validation. Prefer optional to inherit the cluster default.

Apply:

   "required": [
-    "size",
-    "storageClass"
+    "size"
   ],
packages/apps/foundationdb/templates/cluster.yaml (2)

13-15: Silence yamllint by avoiding left‑trim in templating.

Change “{{- … | nindent 4 }}” to “{{ … | nindent 4 }}” so linters don’t choke on “{{-” after a mapping key.

Apply:

-  processCounts:
-    {{- toYaml .Values.cluster.processCounts | nindent 4 }}
+  processCounts:
+    {{ toYaml .Values.cluster.processCounts | nindent 4 }}

48-49: Propagate full security context and prefer podSecurityContext when possible.

Once values add runAsNonRoot/allowPrivilegeEscalation, render them here. Consider setting pod-level fsGroup if volumes require it.

Apply:

-              securityContext:
-                {{- toYaml .Values.securityContext | nindent 16 }}
+              securityContext:
+                {{ toYaml .Values.securityContext | nindent 16 }}
@@
-              securityContext:
-                {{- toYaml .Values.securityContext | nindent 16 }}
+              securityContext:
+                {{ toYaml .Values.securityContext | nindent 16 }}
@@
-              securityContext:
-                {{- toYaml .Values.securityContext | nindent 16 }}
+              securityContext:
+                {{ toYaml .Values.securityContext | nindent 16 }}

Optional pod template addition (if needed for storage permissions):

podSecurityContext:
  fsGroup: 1001

Also applies to: 58-59, 69-70

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ee3d5f and 8a7cf1d.

📒 Files selected for processing (4)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/templates/cluster.yaml (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/apps/foundationdb/README.md
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/templates/cluster.yaml

[error] 14-14: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/values.yaml

[error] 92-92: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (1)
packages/apps/foundationdb/templates/cluster.yaml (1)

81-86: LGTM: routing and sidecar flags are correctly placed.

Fields match v1beta2 spec and docs. (github.com)

{{- if .Values.cluster.faultDomain.valueFrom }}
valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
{{- end }}
imageType: {{ .Values.imageType }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

imageType is a top‑level field; don’t put it under automationOptions.

Move to spec.imageType. (github.com)

Apply:

-    imageType: {{ .Values.imageType }}
+  imageType: {{ .Values.imageType }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
imageType: {{ .Values.imageType }}
imageType: {{ .Values.imageType }}
🤖 Prompt for AI Agents
In packages/apps/foundationdb/templates/cluster.yaml around line 24, imageType
is currently placed under automationOptions but must be a top‑level spec field;
remove the imageType entry from automationOptions and add it under
spec.imageType (e.g., ensure the template renders .Values.imageType at
spec.imageType) so the generated manifest follows the operator's schema.

Comment on lines +25 to +33
labels:
filterOnOwnerReference: false
matchLabels:
foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
processClassLabels:
- foundationdb.org/fdb-process-class
processGroupIDLabels:
- foundationdb.org/fdb-process-group-id
minimumUptimeSecondsForBounce: 60

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

labels and minimumUptimeSecondsForBounce are top‑level spec fields.

These belong under spec.*, not automationOptions. (github.com)

Apply:

-    labels:
-      filterOnOwnerReference: false
-      matchLabels:
-        foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
-      processClassLabels:
-        - foundationdb.org/fdb-process-class
-      processGroupIDLabels:
-        - foundationdb.org/fdb-process-group-id
-    minimumUptimeSecondsForBounce: 60
+  labels:
+    filterOnOwnerReference: false
+    matchLabels:
+      foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
+    processClassLabels:
+      - foundationdb.org/fdb-process-class
+    processGroupIDLabels:
+      - foundationdb.org/fdb-process-group-id
+  minimumUptimeSecondsForBounce: 60
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
labels:
filterOnOwnerReference: false
matchLabels:
foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
processClassLabels:
- foundationdb.org/fdb-process-class
processGroupIDLabels:
- foundationdb.org/fdb-process-group-id
minimumUptimeSecondsForBounce: 60
labels:
filterOnOwnerReference: false
matchLabels:
foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
processClassLabels:
- foundationdb.org/fdb-process-class
processGroupIDLabels:
- foundationdb.org/fdb-process-group-id
minimumUptimeSecondsForBounce: 60
🤖 Prompt for AI Agents
In packages/apps/foundationdb/templates/cluster.yaml around lines 25 to 33, the
keys "labels", "processClassLabels", "processGroupIDLabels" and
"minimumUptimeSecondsForBounce" are currently placed at the wrong level; move
these entries out of automationOptions and place them under spec (e.g.,
spec.labels: {filterOnOwnerReference, matchLabels, processClassLabels,
processGroupIDLabels} and spec.minimumUptimeSecondsForBounce: 60) with correct
YAML indentation, removing the duplicates from the automationOptions block.

Comment on lines +14 to +25
"enabled": false,
"retentionPolicy": "7d",
"s3": {
"bucket": "",
"credentials": {
"accessKeyId": "",
"secretAccessKey": ""
},
"endpoint": "",
"region": "us-east-1"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Model S3 auth via Secret reference; remove plaintext from defaults.

Schema currently requires inlined accessKeyId/secretAccessKey. Replace with secretRef and make it required; this aligns with the safer values change.

Apply:

-      "default": {
-        "enabled": false,
-        "retentionPolicy": "7d",
-        "s3": {
-          "bucket": "",
-          "credentials": {
-            "accessKeyId": "",
-            "secretAccessKey": ""
-          },
-          "endpoint": "",
-          "region": "us-east-1"
-        }
-      },
+      "default": {
+        "enabled": false,
+        "retentionPolicy": "7d",
+        "s3": {
+          "bucket": "",
+          "secretRef": {
+            "name": "",
+            "accessKeyKey": "accessKeyId",
+            "secretKeyKey": "secretAccessKey"
+          },
+          "endpoint": "",
+          "region": "us-east-1"
+        }
+      },
@@
-          "default": {
-            "bucket": "",
-            "credentials": {
-              "accessKeyId": "",
-              "secretAccessKey": ""
-            },
-            "endpoint": "",
-            "region": "us-east-1"
-          },
+          "default": {
+            "bucket": "",
+            "secretRef": {
+              "name": "",
+              "accessKeyKey": "accessKeyId",
+              "secretKeyKey": "secretAccessKey"
+            },
+            "endpoint": "",
+            "region": "us-east-1"
+          },
           "required": [
             "bucket",
-            "credentials",
+            "secretRef",
             "endpoint",
             "region"
           ],
           "properties": {
             "bucket": {
               "description": "S3 bucket name",
               "type": "string"
             },
-            "credentials": {
-              "description": "S3 credentials",
-              "type": "object",
-              "default": {
-                "accessKeyId": "",
-                "secretAccessKey": ""
-              },
-              "required": [
-                "accessKeyId",
-                "secretAccessKey"
-              ],
-              "properties": {
-                "accessKeyId": {
-                  "description": "S3 access key ID",
-                  "type": "string"
-                },
-                "secretAccessKey": {
-                  "description": "S3 secret access key",
-                  "type": "string"
-                }
-              }
-            },
+            "secretRef": {
+              "description": "Reference to a Secret containing S3 credentials",
+              "type": "object",
+              "required": ["name", "accessKeyKey", "secretKeyKey"],
+              "properties": {
+                "name": { "type": "string", "description": "Secret name" },
+                "accessKeyKey": { "type": "string", "default": "accessKeyId" },
+                "secretKeyKey": { "type": "string", "default": "secretAccessKey" }
+              }
+            },
             "endpoint": {
               "description": "S3 endpoint URL",
               "type": "string"
             },

Optional: keep legacy credentials via a oneOf for smooth migration.

Also applies to: 42-97

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

♻️ Duplicate comments (8)
packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (2)

29-37: Make spec mandatory at the top level.

Add required: [spec] under openAPIV3Schema to enforce structural schema and prevent empty objects.

       openAPIV3Schema:
         properties:
           apiVersion:
             type: string
           kind:
             type: string
           metadata:
             type: object
+        required:
+        - spec
         type: object

71-84: Relax overly restrictive regex for keyRanges bounds.

^[A-Za-z0-9\/\\-]+$ will reject valid FDB keys (including empty bounds and non‑ASCII bytes). Prefer length guards.

                   properties:
                     end:
-                      pattern: ^[A-Za-z0-9\/\\-]+$
-                      type: string
+                      type: string
+                      maxLength: 4096
                     start:
-                      pattern: ^[A-Za-z0-9\/\\-]+$
-                      type: string
+                      type: string
+                      maxLength: 4096
                   required:
                     - end
                     - start

If empty bounds should be allowed, either drop required or add minLength: 0 while keeping both required. Please confirm with operator semantics.

packages/system/foundationdb-operator/Chart.yaml (1)

1-3: Missing subchart dependency; operator chart won’t package/install the upstream chart.

Declare fdb-operator as a local file dependency so Helm renders it.

 apiVersion: v2
 name: cozy-foundationdb-operator
 version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
+dependencies:
+  - name: fdb-operator
+    version: 2.13.0
+    repository: "file://charts/fdb-operator"
packages/apps/foundationdb/values.yaml (2)

58-67: Don’t embed cloud keys in values; switch to Secret ref.

Avoid committing plaintext credentials or passing them via Helm values. Prefer a Secret reference the chart reads.

Apply (values shape):

 backup:
   enabled: false
   s3:
     bucket: ""
     endpoint: ""
     region: "us-east-1"
-    credentials:
-      accessKeyId: ""
-      secretAccessKey: ""
+    secretRef:
+      name: ""            # Secret with AWS creds
+      accessKeyKey: AWS_ACCESS_KEY_ID
+      secretKeyKey: AWS_SECRET_ACCESS_KEY

Then update templates to use secretRef and skip creating a Secret when provided (see backup.yaml comment).


84-90: Default to non‑root; allow opt‑out if images require root.

Running as UID/GID 0 by default is risky in multi‑tenant setups. Default to runAsNonRoot with an override flag if needed.

Apply:

 securityContext:
-  runAsUser: 0
-  runAsGroup: 0
+  runAsNonRoot: true
+  allowPrivilegeEscalation: false
+  runAsUser: 1001
+  runAsGroup: 1001

If root is required, add an explicit .Values.advanced.allowRoot and gate the root context in templates.

packages/apps/foundationdb/templates/cluster.yaml (1)

16-33: Fix CRD field placement: move faultDomain, imageType, labels, minimumUptimeSecondsForBounce to top level.

In v1beta2, these are top‑level under spec, not spec.automationOptions. Keeping them under automationOptions makes the operator ignore them.

Apply:

 spec:
   version: {{ .Values.cluster.version | quote }}
+  faultDomain:
+    key: {{ .Values.cluster.faultDomain.key }}
+    {{- if .Values.cluster.faultDomain.valueFrom }}
+    valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
+    {{- end }}
+  imageType: {{ .Values.imageType }}
+  labels:
+    filterOnOwnerReference: false
+    matchLabels:
+      foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
+    processClassLabels:
+      - foundationdb.org/fdb-process-class
+    processGroupIDLabels:
+      - foundationdb.org/fdb-process-group-id
+  minimumUptimeSecondsForBounce: 60
-  automationOptions:
-    replacements:
-      enabled: {{ .Values.automaticReplacements }}
-    faultDomain:
-      key: {{ .Values.cluster.faultDomain.key }}
-      {{- if .Values.cluster.faultDomain.valueFrom }}
-      valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
-      {{- end }}
-    imageType: {{ .Values.imageType }}
-    labels:
-      filterOnOwnerReference: false
-      matchLabels:
-        foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
-      processClassLabels:
-        - foundationdb.org/fdb-process-class
-      processGroupIDLabels:
-        - foundationdb.org/fdb-process-group-id
-    minimumUptimeSecondsForBounce: 60
+  automationOptions:
+    replacements:
+      enabled: {{ .Values.automaticReplacements }}
  • spec.faultDomain belongs at top level. (github.com)
  • spec.imageType is a top‑level field for unified/split images. (github.com)
  • spec.labels and spec.minimumUptimeSecondsForBounce are top‑level, not under automationOptions. (forums.foundationdb.org)

Also applies to: 81-86

packages/apps/foundationdb/templates/backup.yaml (2)

3-15: Avoid creating a Secret from values; support SecretRef and fallback.

Prefer consuming an existing Secret via values.s3.secretRef; only create a Secret when no ref is provided.

Apply:

-apiVersion: v1
-kind: Secret
+{{- if not .Values.backup.s3.secretRef.name }}
+apiVersion: v1
+kind: Secret
 metadata:
   name: {{ .Release.Name }}-s3-creds
 ...
 data:
   AWS_ACCESS_KEY_ID: {{ .Values.backup.s3.credentials.accessKeyId | b64enc }}
   AWS_SECRET_ACCESS_KEY: {{ .Values.backup.s3.credentials.secretAccessKey | b64enc }}
+{{- end }}

And update credentials below to reference either the provided SecretRef or this fallback Secret (see diff further down).


50-55: Fix S3 mapping: don’t set accountName to the bucket; pass region via urlParameters.

  • accountName is the credential/host part (e.g., user@host[:port]), not the bucket.
  • Region is typically provided via URL parameters for S3 endpoints.

Apply:

   blobStoreConfiguration:
-    accountName: {{ .Values.backup.s3.bucket }}
     bucket: {{ .Values.backup.s3.bucket }}
-    {{- if .Values.backup.s3.endpoint }}
-    endpoint: {{ .Values.backup.s3.endpoint }}
-    {{- end }}
+    {{- if .Values.backup.s3.endpoint }}
+    endpoint: {{ .Values.backup.s3.endpoint }}
+    {{- end }}
+    {{- if or .Values.backup.s3.region .Values.backup.s3.endpoint }}
+    urlParameters:
+    {{- if .Values.backup.s3.region }}
+      - region={{ .Values.backup.s3.region }}
+    {{- end }}
+    {{- end }}

Example usage with urlParameters is shown in operator community examples. (forums.foundationdb.org)

🧹 Nitpick comments (10)
packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (1)

71-84: Optional: add a CEL guard for range ordering.

If lexicographic order is expected, add a per‑item validation to catch swapped bounds.

                 items:
                   properties:
                     end:
                       type: string
                       maxLength: 4096
                     start:
                       type: string
                       maxLength: 4096
                   required:
                     - end
                     - start
+                  x-kubernetes-validations:
+                  - rule: "has(self.start) && has(self.end) ? self.start <= self.end : true"
+                    message: "keyRanges.start must be <= keyRanges.end (lexicographic)"
                   type: object

Confirm that lexicographic comparison matches controller expectations for key encoding.

packages/system/foundationdb-operator/Makefile (2)

6-19: Refactor update flow: parameterize version/repo, add PHONY + smaller targets, future‑proof CRD vendoring, and satisfy checkmake.

  • Add REPO/VERSION vars instead of hardcoding v2.13.0.
  • Split the long recipe into short phony targets (addresses maxbodylength; adds all/clean/test that checkmake expects).
  • Replace explicit CRD filenames with a glob to handle upstream additions.
  • Keep behavior identical otherwise.

Apply this diff:

 export NAME=foundationdb-operator
 export NAMESPACE=cozy-$(NAME)
 
 include ../../../scripts/package.mk
 
-update:
-	rm -rf charts
-	git clone --depth 1 --branch v2.13.0 https://github.com/FoundationDB/fdb-kubernetes-operator.git tmp-repo
-	mkdir -p charts
-	cp -r tmp-repo/charts/fdb-operator charts/
-	# Remove symlinked CRDs and replace with actual files
-	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbbackups.yaml
-	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbclusters.yaml
-	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
-	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbbackups.yaml charts/fdb-operator/crds/
-	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml charts/fdb-operator/crds/
-	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbrestores.yaml charts/fdb-operator/crds/
-	rm -rf tmp-repo
-	rm -rf charts/fdb-operator/charts
+REPO    ?= https://github.com/FoundationDB/fdb-kubernetes-operator.git
+VERSION ?= v2.13.0
+
+.PHONY: all update clean clean-charts fetch-operator vendor-crds prune-subcharts cleanup test
+
+all: update
+
+clean:
+	rm -rf charts tmp-repo
+
+update: clean-charts fetch-operator vendor-crds prune-subcharts cleanup
+
+clean-charts:
+	rm -rf charts
+
+fetch-operator:
+	git clone --depth 1 --branch $(VERSION) $(REPO) tmp-repo
+	mkdir -p charts
+	cp -r tmp-repo/charts/fdb-operator charts/
+
+vendor-crds:
+	# Replace symlinked CRDs with actual files
+	rm -f charts/fdb-operator/crds/*.yaml
+	cp tmp-repo/config/crd/bases/*.yaml charts/fdb-operator/crds/
+
+prune-subcharts:
+	rm -rf charts/fdb-operator/charts
+
+cleanup:
+	rm -rf tmp-repo
+
+test:
+	helm lint charts/fdb-operator || true

Notes:

  • If you prefer strict control over CRD filenames, keep the three rm/cp lines but consider a brief comment explaining the choice.
  • If CI relies on different test tooling than Helm, adjust the test target accordingly.

6-6: Add failure‑resilient cleanup.

If a mid‑recipe command fails, tmp-repo may be left behind. The refactor into separate targets helps, but if you keep a single recipe, use .ONESHELL with trap to ensure cleanup. Otherwise, the split targets + cleanup target as shown are fine.

packages/system/foundationdb-operator/values.yaml (1)

4-4: Add missing newline at EOF.

Minor formatting to satisfy linters.

-  nodeReadClusterRole: true
+  nodeReadClusterRole: true
+
packages/system/foundationdb-operator/Chart.yaml (1)

3-3: Add newline at EOF.

Keep linters quiet.

-version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
+version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
+
packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml (1)

93-99: Add a readinessProbe to avoid routing traffic before the manager is ready.

Small resiliency improvement; the livenessProbe alone may cause flaps during startup.

         livenessProbe:
           httpGet:
             path: /metrics
             port: metrics
+        readinessProbe:
+          httpGet:
+            path: /metrics
+            port: metrics
+          initialDelaySeconds: 3
+          periodSeconds: 10
packages/apps/foundationdb/templates/workloadmonitor.yaml (1)

11-19: Version field likely should reflect FDB version, not chart packaging version.

WorkloadMonitor.spec.version is typically used to track app/runtime version; using .Chart.Version (0.1.0) may be misleading versus FDB 7.4.1. Prefer .Chart.AppVersion or .Values.cluster.version.

Apply this diff:

-  version: {{ .Chart.Version }}
+  version: {{ .Chart.AppVersion | default .Values.cluster.version | quote }}

Please confirm the expected semantics of WorkloadMonitor.version in Cozystack.

packages/apps/foundationdb/Makefile (1)

3-4: Mark phony targets and add a simple default.

Prevents accidental file/target collisions and satisfies checkmake hints.

Apply:

+.PHONY: all generate clean test
+
+all: generate
+
 generate:
 	cozyvalues-gen -v values.yaml -s values.schema.json -r README.md
+
+clean:
+	@true
+
+test:
+	@true
packages/apps/foundationdb/values.yaml (1)

58-68: Unused retentionPolicy value.

retentionPolicy is not wired in templates; either implement or remove to avoid dead config.

I can wire this into backup customParameters or document a retention workflow if you prefer.

packages/apps/foundationdb/templates/backup.yaml (1)

56-65: Make credentials source switchable to SecretRef.

Allow using an existing Secret when provided; otherwise reference the fallback Secret created above.

Apply:

     credentials:
       AWS_ACCESS_KEY_ID:
         secretKeyRef:
-          name: {{ .Release.Name }}-s3-creds
-          key: AWS_ACCESS_KEY_ID
+          name: {{ default (printf "%s-s3-creds" .Release.Name) .Values.backup.s3.secretRef.name }}
+          key: {{ default "AWS_ACCESS_KEY_ID" .Values.backup.s3.secretRef.accessKeyKey }}
       AWS_SECRET_ACCESS_KEY:
         secretKeyRef:
-          name: {{ .Release.Name }}-s3-creds
-          key: AWS_SECRET_ACCESS_KEY
+          name: {{ default (printf "%s-s3-creds" .Release.Name) .Values.backup.s3.secretRef.name }}
+          key: {{ default "AWS_SECRET_ACCESS_KEY" .Values.backup.s3.secretRef.secretKeyKey }}

Please validate against v2.13.0 CRD behavior in your env; some providers require additional urlParameters (e.g., secure_connection). (forums.foundationdb.org)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a7cf1d and 6d2ac46.

⛔ Files ignored due to path filters (1)
  • packages/apps/foundationdb/logos/foundationdb.svg is excluded by !**/*.svg
📒 Files selected for processing (29)
  • hack/e2e-apps/foundationdb.bats (1 hunks)
  • packages/apps/foundationdb/.helmignore (1 hunks)
  • packages/apps/foundationdb/Chart.yaml (1 hunks)
  • packages/apps/foundationdb/Makefile (1 hunks)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/charts/cozy-lib (1 hunks)
  • packages/apps/foundationdb/templates/_resources.tpl (1 hunks)
  • packages/apps/foundationdb/templates/backup.yaml (1 hunks)
  • packages/apps/foundationdb/templates/cluster.yaml (1 hunks)
  • packages/apps/foundationdb/templates/dashboard-resourcemap.yaml (1 hunks)
  • packages/apps/foundationdb/templates/workloadmonitor.yaml (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
  • packages/apps/versions_map (1 hunks)
  • packages/system/cozystack-api/openapi-schemas/foundationdb.json (1 hunks)
  • packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml (1 hunks)
  • packages/system/foundationdb-operator/.helmignore (1 hunks)
  • packages/system/foundationdb-operator/Chart.yaml (1 hunks)
  • packages/system/foundationdb-operator/Makefile (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/NOTES.txt (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/values.yaml (1 hunks)
  • packages/system/foundationdb-operator/values.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • packages/system/foundationdb-operator/.helmignore
  • packages/system/cozystack-api/openapi-schemas/foundationdb.json
  • packages/apps/foundationdb/README.md
🚧 Files skipped from review as they are similar to previous changes (10)
  • packages/apps/foundationdb/.helmignore
  • packages/apps/foundationdb/charts/cozy-lib
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl
  • packages/apps/foundationdb/templates/_resources.tpl
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/NOTES.txt
  • packages/system/foundationdb-operator/charts/fdb-operator/values.yaml
  • packages/apps/foundationdb/values.schema.json
  • packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml
  • packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml
  • hack/e2e-apps/foundationdb.bats
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/system/foundationdb-operator/Chart.yaml

[error] 3-3: no new line character at the end of file

(new-line-at-end-of-file)

packages/apps/foundationdb/templates/dashboard-resourcemap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/Chart.yaml

[error] 25-25: no new line character at the end of file

(new-line-at-end-of-file)

packages/apps/foundationdb/templates/backup.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/templates/cluster.yaml

[error] 14-14: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/templates/workloadmonitor.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/values.yaml

[error] 92-92: no new line character at the end of file

(new-line-at-end-of-file)

packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml

[error] 7-7: syntax error: expected the node content, but found '-'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml

[error] 4-4: syntax error: could not find expected ':'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml

[error] 4-4: syntax error: could not find expected ':'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml

[error] 2-2: syntax error: expected the node content, but found '-'

(syntax)

packages/system/foundationdb-operator/values.yaml

[error] 4-4: no new line character at the end of file

(new-line-at-end-of-file)

🪛 checkmake (0.2.2)
packages/apps/foundationdb/Makefile

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

packages/system/foundationdb-operator/Makefile

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)


[warning] 6-6: Target body for "update" exceeds allowed length of 5 (13).

(maxbodylength)

🔇 Additional comments (11)
packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (1)

1-101: Validate and document CRD drift vs upstream v2.13.0

Upstream: upstream-fdb/config/crd/patches/webhook_in_foundationdbrestores.yaml (webhook patch, apiextensions.k8s.io/v1beta1)
Local: packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (full apiextensions.k8s.io/v1 CRD with OpenAPI schema). Confirm these deltas are intentional; either align the local CRD with upstream or add a short documented justification in the chart/PR.

packages/system/foundationdb-operator/Makefile (3)

1-2: Good: consistent package metadata exports.

NAME and NAMESPACE look consistent with other Cozystack packages.


10-17: Symlink handling: ensure we replace symlinks with regular files.

Couldn't verify — charts/fdb-operator/crds is missing from this checkout (script returned "No such file or directory"). Re-run the provided check after running make update, or update packages/system/foundationdb-operator/Makefile to glob-copy tmp-repo/config/crd/bases/*.yaml into charts/fdb-operator/crds and assert no symlinks remain.


4-4: Include path & targets verified.
packages/system/foundationdb-operator/Makefile includes ../../../scripts/package.mk (line 4); ../../../scripts/package.mk exists and defines apply and related Helm targets (check, diff, delete, suspend, resume). build and test targets are not present — confirm whether build/test are required and add them or adjust the Makefile accordingly.

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml (1)

2-17: ServiceAccount template looks correct; YAMLlint error is a false positive.

Helm directives (‘{{- … }}’) trip YAMLlinters; rendered output is valid. No functional issues spotted.

If you want, I can provide a helm template dry-run script to sanity-check the rendered SA.

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml (1)

1-25: Binding kind toggling is okay; YAMLlint complaint is Helm-template noise.

Current conditional RoleBinding/ClusterRoleBinding for the primary role is fine. No change needed here.

packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml (1)

42-67: Init containers: consistent resource/security contexts look good.

Nice use of shared values for resources and securityContext; volume wiring to fdb-binaries is correct.

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml (1)

113-130: Nodes ClusterRole block is good and complements the binding.

No issues; matches nodeReadClusterRole intent.

packages/apps/foundationdb/values.yaml (1)

92-92: Add trailing newline.

Keeps linters happy.
[raise_nitpick_issue]

packages/apps/foundationdb/templates/dashboard-resourcemap.yaml (1)

13-21: LGTM — conditional inclusion and GVKs look right.

ConfigMap embeds both Cluster and optional Backup entries as expected.

Minor: if the dashboard reads namespaces from the map, consider adding namespace: {{ .Release.Namespace }} to each embedded resource entry.

packages/apps/versions_map (1)

36-36: Approve: FoundationDB entry added and verified.

packages/apps/versions_map — line 36: foundationdb 0.1.0 HEAD. No duplicate (name,version) tuples found; alphabetical order preserved; HEAD usage matches file conventions.

Comment thread packages/apps/foundationdb/Chart.yaml Outdated
Comment on lines +19 to +25
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "7.4.1" No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Add trailing newline and keep appVersion aligned with defaults.

  • Add a newline at EOF to satisfy linters.
  • appVersion "7.4.1" matches values.cluster.version; keep them in sync on bumps.
    [raise_nitpick_issue]

You can auto‑check consistency with:


🏁 Script executed:

#!/bin/bash
yq '.appVersion' packages/apps/foundationdb/Chart.yaml
yq '.cluster.version' packages/apps/foundationdb/values.yaml

Length of output: 81


🏁 Script executed:

#!/bin/bash
CHART=packages/apps/foundationdb/Chart.yaml
VALUES=packages/apps/foundationdb/values.yaml

echo "== Chart.yaml =="
if [ -f "$CHART" ]; then
  echo "-- content --"
  sed -n '1,240p' "$CHART"
  echo
  echo "-- appVersion value --"
  awk -F: '/^[[:space:]]*appVersion[[:space:]]*:/ {
    sub(/^[[:space:]]*appVersion[[:space:]]*:[[:space:]]*/,"")
    gsub(/^[ \t"]+|[ \t"]+$/,"")
    print; found=1; exit
  } END { if (!found) print "<<NOT FOUND>>" }' "$CHART"
  echo
  echo "-- Chart.yaml last byte (hex) --"
  tail -c1 "$CHART" | hexdump -v -e '1/1 "%02x"' || echo "<<unable to read last byte>>"
else
  echo "Chart.yaml: NOT FOUND"
fi

echo
echo "== values.yaml =="
if [ -f "$VALUES" ]; then
  echo "-- content --"
  sed -n '1,400p' "$VALUES"
  echo
  echo "-- cluster.version (approx) --"
  awk '
  /^[[:space:]]*cluster[[:space:]]*:/ { in_cluster=1; next }
  in_cluster {
    if (/^[[:space:]]*version[[:space:]]*:/) {
      sub(/^[[:space:]]*version[[:space:]]*:[[:space:]]*/,"")
      gsub(/^[ \t"]+|[ \t"]+$/,"")
      print; exit
    }
    if (/^[^[:space:]]/ && /:$/) { in_cluster=0 }
  }' "$VALUES" || echo "<<NOT FOUND>>"
  echo
  echo "-- all 'version' lines in values.yaml --"
  grep -n "version" "$VALUES" || true
else
  echo "values.yaml: NOT FOUND"
fi

Length of output: 5329


🏁 Script executed:

#!/bin/bash
CHART=packages/apps/foundationdb/Chart.yaml
VALUES=packages/apps/foundationdb/values.yaml

command -v python3 >/dev/null 2>&1 || command -v python >/dev/null 2>&1 || { echo "python not found"; exit 0; }

PY=python3
command -v python3 >/dev/null 2>&1 || PY=python

if [ ! -f "$CHART" ]; then
  echo "Chart.yaml: NOT FOUND"
else
  echo "== Chart.yaml appVersion & EOF check =="
  $PY - <<'PY'
import re
p='packages/apps/foundationdb/Chart.yaml'
try:
    with open(p,'rb') as f:
        b=f.read()
    m=re.search(rb'^\s*appVersion\s*:\s*(?:(?:"([^"]+)")|(?:\'([^\']+)\')|([^#\n\r]+))', b, re.M)
    if m:
        val=(m.group(1) or m.group(2) or m.group(3)).decode().strip()
        print("appVersion:", val)
    else:
        print("appVersion: <<NOT FOUND>>")
    if len(b)==0:
        print("FILE_EMPTY")
    else:
        lb=b[-1]
        print("LAST_BYTE_ORD=%d" % lb)
        print("ENDS_WITH_NEWLINE=%s" % ("yes" if lb==10 else "no"))
except Exception as e:
    print("ERROR", e)
PY
fi

echo
if [ ! -f "$VALUES" ]; then
  echo "values.yaml: NOT FOUND"
else
  echo "== values.yaml cluster.version =="
  $PY - <<'PY'
import re
p='packages/apps/foundationdb/values.yaml'
try:
    with open(p,'r',encoding='utf-8') as f:
        s=f.read()
    m=re.search(r'^\s*cluster\s*:\s*$', s, re.M)
    if m:
        start=m.end()
        rest=s[start:]
        m2=re.search(r'^\s*version\s*:\s*(?:(?:"([^"]+)")|(?:\'([^\']+)\')|(.+))', rest, re.M)
        if m2:
            val=(m2.group(1) or m2.group(2) or m2.group(3)).strip()
            print("cluster.version:", val)
        else:
            print("cluster.version: <<NOT FOUND_IN_CLUSTER_BLOCK>>")
    else:
        m3=re.search(r'^\s*version\s*:\s*(?:(?:"([^"]+)")|(?:\'([^\']+)\')|(.+))', s, re.M)
        if m3:
            print("version (first):", (m3.group(1) or m3.group(2) or m3.group(3)).strip())
        else:
            print("version: <<NOT FOUND>>")
except Exception as e:
    print("ERROR", e)
PY
fi

Length of output: 153


Add trailing newline to Chart.yaml; appVersion is synced

  • packages/apps/foundationdb/Chart.yaml: add a newline at EOF (file currently does not end with a newline) to satisfy linters.
  • appVersion "7.4.1" matches cluster.version in packages/apps/foundationdb/values.yaml; keep them in sync on future bumps.
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 25-25: no new line character at the end of file

(new-line-at-end-of-file)

🤖 Prompt for AI Agents
In packages/apps/foundationdb/Chart.yaml around lines 19 to 25, the file is
missing a trailing newline at EOF which causes linter failures; add a single
newline character at the end of the file. Also confirm the appVersion "7.4.1"
remains in sync with packages/apps/foundationdb/values.yaml (cluster.version)
when bumping versions in future.

Comment on lines +43 to +44
runAsUser: 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Harden backup pod security context.

Reuse the chart’s securityContext (non‑root by default after values change) instead of forcing root.

Apply:

-            securityContext:
-              runAsUser: 0
+            securityContext:
+              {{- toYaml .Values.securityContext | nindent 14 }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
runAsUser: 0
securityContext:
{{- toYaml .Values.securityContext | nindent 14 }}
🤖 Prompt for AI Agents
In packages/apps/foundationdb/templates/backup.yaml around lines 43-44, the pod
is hardcoding runAsUser: 0 which forces root; remove that hardcoded entry and
instead inherit the chart's securityContext (or reference the chart value) so
the pod runs non-root by default after values change. Update the template to
stop forcing runAsUser: 0 and rely on the chart-level securityContext (or
template with the appropriate .Values.securityContext reference) so the pod
securityContext is reused rather than overridden.

Comment on lines +26 to +44
{{- if .Values.nodeReadClusterRole }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "fdb-operator.fullname" . }}-clusterrolebinding
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "fdb-operator.fullname" . }}-clusterrole
subjects:
- kind: ServiceAccount
name: {{ include "fdb-operator.serviceAccountName" . }}
{{- if .Values.globalMode.enabled }}
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

ClusterRoleBinding subject is missing namespace when globalMode is false.

The second binding is always ClusterRoleBinding; ServiceAccount subjects must specify namespace regardless of global mode. Without it, apply will fail.

 subjects:
 - kind: ServiceAccount
   name: {{ include "fdb-operator.serviceAccountName" . }}
-  {{- if .Values.globalMode.enabled }}
-  namespace: {{ .Release.Namespace }}
-  {{- end }}
+  namespace: {{ .Release.Namespace }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- if .Values.nodeReadClusterRole }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "fdb-operator.fullname" . }}-clusterrolebinding
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "fdb-operator.fullname" . }}-clusterrole
subjects:
- kind: ServiceAccount
name: {{ include "fdb-operator.serviceAccountName" . }}
{{- if .Values.globalMode.enabled }}
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}
{{- if .Values.nodeReadClusterRole }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "fdb-operator.fullname" . }}-clusterrolebinding
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "fdb-operator.fullname" . }}-clusterrole
subjects:
- kind: ServiceAccount
name: {{ include "fdb-operator.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end }}
🤖 Prompt for AI Agents
In
packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml
around lines 26 to 44, the ClusterRoleBinding subject lacks a namespace when
.Values.globalMode.enabled is false which causes kubectl apply to fail; always
include the namespace field for the ServiceAccount subject (e.g., namespace: {{
.Release.Namespace }}) instead of conditionally adding it, and ensure proper
YAML indentation so the namespace is a sibling of name under the subject entry.

Comment on lines +3 to +11
{{- if .Values.globalMode.enabled }}
kind: ClusterRole
{{- else }}
kind: Role
{{- end }}
metadata:
name: {{ include "fdb-operator.fullname" . }}
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Role vs. ClusterRole: cluster-scoped APIs appear under a namespaced Role.

When globalMode.enabled is false, this renders a Role that includes cluster-scoped resources (webhook configurations). Kubernetes rejects cluster-scoped resources in a Role.

Two safe options:

  • Option A (simplest): Always render a ClusterRole.
  • Option B (scoped): Keep Role for namespaced resources, and move cluster-scoped rules to a separate ClusterRole + ClusterRoleBinding.

Minimal patch for Option A:

-{{- if .Values.globalMode.enabled }}
-kind: ClusterRole
-{{- else }}
-kind: Role
-{{- end }}
+kind: ClusterRole

If you take Option A, also ensure the primary binding is a ClusterRoleBinding in rbac_role_binding.yaml.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- if .Values.globalMode.enabled }}
kind: ClusterRole
{{- else }}
kind: Role
{{- end }}
metadata:
name: {{ include "fdb-operator.fullname" . }}
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
kind: ClusterRole
metadata:
name: {{ include "fdb-operator.fullname" . }}
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 4-4: syntax error: could not find expected ':'

(syntax)

🤖 Prompt for AI Agents
In
packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml
around lines 3-11, the template currently renders a namespaced Role when
.Values.globalMode.enabled is false but that Role includes cluster-scoped rules
(e.g. webhook configurations) which Kubernetes rejects; change the template to
always render a ClusterRole (remove the conditional that chooses between Role
and ClusterRole) so cluster-scoped resources are allowed, and update the
corresponding binding in rbac_role_binding.yaml to be a ClusterRoleBinding
(ensure any references to a Role are replaced and that the binding points to the
ClusterRole name produced by include "fdb-operator.fullname").

Comment on lines +53 to +64
- admissionregistration.k8s.io
resources:
- mutatingwebhookconfigurations
- validatingwebhookconfigurations
verbs:
- get
- list
- watch
- create
- update
- patch
- delete

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

If keeping namespaced mode, guard webhook permissions behind globalMode.

Prevents invalid Role manifests while you decide on broader RBAC layout.

-- apiGroups:
-  - admissionregistration.k8s.io
-  resources:
-  - mutatingwebhookconfigurations
-  - validatingwebhookconfigurations
-  verbs:
-  - get
-  - list
-  - watch
-  - create
-  - update
-  - patch
-  - delete
+{{- if .Values.globalMode.enabled }}
+- apiGroups:
+  - admissionregistration.k8s.io
+  resources:
+  - mutatingwebhookconfigurations
+  - validatingwebhookconfigurations
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - update
+  - patch
+  - delete
+{{- end }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- admissionregistration.k8s.io
resources:
- mutatingwebhookconfigurations
- validatingwebhookconfigurations
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
{{- if .Values.globalMode.enabled }}
- apiGroups:
- admissionregistration.k8s.io
resources:
- mutatingwebhookconfigurations
- validatingwebhookconfigurations
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
{{- end }}
🤖 Prompt for AI Agents
In
packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml
around lines 53–64, the Role currently includes cluster-scoped webhook resources
which are invalid in namespaced mode; wrap the mutating/validating webhook
resource rules in a Helm conditional that only renders them when
.Values.globalMode (or the chart's global/cluster mode flag) is enabled.
Specifically, enclose the block with an if/endif check for the globalMode value
so the webhook permissions are omitted in namespaced mode.

Comment on lines +1 to +19
export NAME=foundationdb-operator
export NAMESPACE=cozy-$(NAME)

include ../../../scripts/package.mk

update:
rm -rf charts
git clone --depth 1 --branch v2.13.0 https://github.com/FoundationDB/fdb-kubernetes-operator.git tmp-repo
mkdir -p charts
cp -r tmp-repo/charts/fdb-operator charts/
# Remove symlinked CRDs and replace with actual files
rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbbackups.yaml
rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbclusters.yaml
rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbbackups.yaml charts/fdb-operator/crds/
cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml charts/fdb-operator/crds/
cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbrestores.yaml charts/fdb-operator/crds/
rm -rf tmp-repo
rm -rf charts/fdb-operator/charts No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Static analysis: satisfy checkmake warnings.

  • Provide all/clean/test phony targets and keep recipe bodies short. The suggested refactor resolves minphony and maxbodylength warnings.

Run:


🏁 Script executed:

#!/bin/bash
checkmake packages/system/foundationdb-operator/Makefile || true

Length of output: 1253


Satisfy checkmake warnings: add phony targets and shorten update recipe

  • Add .PHONY: all clean test to packages/system/foundationdb-operator/Makefile.
  • Reduce the update target body to ≤5 lines by extracting steps into subtargets or an external script (update target at packages/system/foundationdb-operator/Makefile:6).
🧰 Tools
🪛 checkmake (0.2.2)

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)


[warning] 6-6: Target body for "update" exceeds allowed length of 5 (13).

(maxbodylength)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/core/platform/bundles/distro-full.yaml (1)

158-164: No VM/ServiceMonitor/PodMonitor in fdb-operator chart — no VM operator dependency required; consider aligning bundle deps*

  • Chart (packages/system/foundationdb-operator) only contains FoundationDB CRDs (apps.foundationdb.org_foundationdbclusters/backups/restores); no VMServiceScrape/VMRule/ServiceMonitor/PodMonitor resources found.
  • Keep dependsOn: [cilium,cert-manager] in packages/core/platform/bundles/distro-full.yaml — adding victoria-metrics-operator is not necessary.
  • Other bundles reference victoria-metrics-operator (packages/core/platform/bundles/paas-full.yaml, distro-hosted.yaml, paas-hosted.yaml); consider aligning dependsOn entries for consistency.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d2ac46 and 15944d6.

📒 Files selected for processing (4)
  • packages/core/platform/bundles/distro-full.yaml (1 hunks)
  • packages/core/platform/bundles/distro-hosted.yaml (1 hunks)
  • packages/core/platform/bundles/paas-full.yaml (1 hunks)
  • packages/core/platform/bundles/paas-hosted.yaml (1 hunks)
🔇 Additional comments (3)
packages/core/platform/bundles/distro-hosted.yaml (1)

119-125: Hosted entry LGTM; double‑check “optional: true” intent

  • Deps on [cert-manager] look right for webhook certs.
  • In this bundle, some DB operators are non‑optional (e.g., mariadb/postgres). If FDB should follow the same default install policy, drop optional: true; if it’s experimental, keeping it optional is fine.
packages/core/platform/bundles/paas-full.yaml (1)

233-238: PaaS‑full deps consistent; verify need for victoria‑metrics dependency

  • Including [cilium, kubeovn, cert-manager] is consistent with other operators here.
  • If the operator manifests include VM* monitoring CRs, consider adding victoria-metrics-operator to dependsOn (many peers do). If not, no change needed.
packages/core/platform/bundles/paas-hosted.yaml (1)

126-131: PaaS‑hosted entry looks correct; validate default install policy

  • Deps on [cert-manager] match peers.
  • This bundle installs most DB operators by default. Confirm that making FoundationDB non‑optional here is intentional.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (6)
hack/e2e-apps/foundationdb.bats (2)

56-63: Use operator-native labels for pod selection.

FDB pods don’t reliably have app=$name; select by fdb cluster label.

-timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l app=\$name,foundationdb.org/fdb-process-class=storage --field-selector=status.phase=Running --no-headers | wc -l) -eq 3 ]; do sleep 10; done"
+timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l foundationdb.org/fdb-cluster-name=\$name,foundationdb.org/fdb-process-class=storage --field-selector=status.phase=Running --no-headers | wc -l) -eq 3 ]; do sleep 10; done"
 
-timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l app=\$name,foundationdb.org/fdb-process-class=stateless --field-selector=status.phase=Running --no-headers | wc -l) -ge 1 ]; do sleep 10; done"
+timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l foundationdb.org/fdb-cluster-name=\$name,foundationdb.org/fdb-process-class=stateless --field-selector=status.phase=Running --no-headers | wc -l) -ge 1 ]; do sleep 10; done"
 
-timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l app=\$name,foundationdb.org/fdb-process-class=cluster_controller --field-selector=status.phase=Running --no-headers | wc -l) -eq 1 ]; do sleep 10; done"
+timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l foundationdb.org/fdb-cluster-name=\$name,foundationdb.org/fdb-process-class=cluster_controller --field-selector=status.phase=Running --no-headers | wc -l) -eq 1 ]; do sleep 10; done"

33-36: Remove hardcoded credentials from test manifest.

These trigger secret scanners and set a bad precedent, even when disabled.

-      credentials:
-        accessKeyId: "oobaiRus9pah8PhohL1ThaeTa4UVa7gu"
-        secretAccessKey: "ju3eum4dekeich9ahM1te8waeGai0oog"
+      # credentials provided via a Secret when enabled
+      # secretRef:
+      #   name: fdb-backup-s3
+      #   accessKeyKey: accessKeyId
+      #   secretKeyKey: secretAccessKey
packages/apps/foundationdb/values.schema.json (2)

10-25: Do not model plaintext S3 credentials; switch to Secret reference.

Replace credentials with secretRef and require it. This avoids secret leakage and aligns with k8s best practices.

       "default": {
         "enabled": false,
         "retentionPolicy": "7d",
         "s3": {
           "bucket": "",
-          "credentials": {
-            "accessKeyId": "",
-            "secretAccessKey": ""
-          },
+          "secretRef": {
+            "name": "",
+            "accessKeyKey": "accessKeyId",
+            "secretKeyKey": "secretAccessKey"
+          },
           "endpoint": "",
           "region": "us-east-1"
         }
       },
@@
         "s3": {
           "description": "S3 configuration for backups",
           "type": "object",
           "default": {
             "bucket": "",
-            "credentials": {
-              "accessKeyId": "",
-              "secretAccessKey": ""
-            },
+            "secretRef": {
+              "name": "",
+              "accessKeyKey": "accessKeyId",
+              "secretKeyKey": "secretAccessKey"
+            },
             "endpoint": "",
             "region": "us-east-1"
           },
           "required": [
             "bucket",
-            "credentials",
+            "secretRef",
             "endpoint",
             "region"
           ],
           "properties": {
             "bucket": {
               "description": "S3 bucket name",
               "type": "string"
             },
-            "credentials": {
-              "description": "S3 credentials",
-              "type": "object",
-              "default": {
-                "accessKeyId": "",
-                "secretAccessKey": ""
-              },
-              "required": [
-                "accessKeyId",
-                "secretAccessKey"
-              ],
-              "properties": {
-                "accessKeyId": {
-                  "description": "S3 access key ID",
-                  "type": "string"
-                },
-                "secretAccessKey": {
-                  "description": "S3 secret access key",
-                  "type": "string"
-                }
-              }
-            },
+            "secretRef": {
+              "description": "Reference to a Secret containing S3 credentials",
+              "type": "object",
+              "required": ["name", "accessKeyKey", "secretKeyKey"],
+              "properties": {
+                "name": { "type": "string", "description": "Secret name" },
+                "accessKeyKey": { "type": "string", "default": "accessKeyId" },
+                "secretKeyKey": { "type": "string", "default": "secretAccessKey" }
+              }
+            },
             "endpoint": {
               "description": "S3 endpoint URL",
               "type": "string"
             },

Also applies to: 42-97


267-290: Default to non-root and extend securityContext schema.

Harden defaults; most environments require non-root.

-    "securityContext": {
-      "description": "Security context for containers",
-      "type": "object",
-      "default": {
-        "runAsGroup": 0,
-        "runAsUser": 0
-      },
-      "required": [
-        "runAsGroup",
-        "runAsUser"
-      ],
-      "properties": {
-        "runAsGroup": {
-          "description": "Group ID to run the container",
-          "type": "integer",
-          "default": 0
-        },
-        "runAsUser": {
-          "description": "User ID to run the container",
-          "type": "integer",
-          "default": 0
-        }
-      }
-    },
+    "securityContext": {
+      "description": "Security context for containers",
+      "type": "object",
+      "default": {
+        "runAsNonRoot": true,
+        "allowPrivilegeEscalation": false,
+        "runAsGroup": 1001,
+        "runAsUser": 1001
+      },
+      "required": ["runAsGroup","runAsUser"],
+      "properties": {
+        "runAsNonRoot": { "type": "boolean", "default": true },
+        "allowPrivilegeEscalation": { "type": "boolean", "default": false },
+        "runAsGroup": {
+          "description": "Group ID to run the container",
+          "type": "integer",
+          "minimum": 0,
+          "default": 1001
+        },
+        "runAsUser": {
+          "description": "User ID to run the container",
+          "type": "integer",
+          "minimum": 0,
+          "default": 1001
+        }
+      }
+    },
packages/apps/foundationdb/values.yaml (2)

58-67: Remove plaintext S3 credentials; reference a Secret.

Avoid committing secrets and leaking via ConfigMaps.

   s3:
     bucket: ""
     endpoint: ""
     region: "us-east-1"
-    credentials:
-      accessKeyId: ""
-      secretAccessKey: ""
+    secretRef:
+      name: ""           # k8s Secret name
+      accessKeyKey: accessKeyId
+      secretKeyKey: secretAccessKey

84-90: Run as non-root by default.

Harden defaults; root-by-default is risky in multi-tenant clusters.

 securityContext:
-  runAsUser: 0
-  runAsGroup: 0
+  runAsNonRoot: true
+  allowPrivilegeEscalation: false
+  runAsUser: 1001
+  runAsGroup: 1001
🧹 Nitpick comments (5)
packages/apps/foundationdb/Chart.yaml (1)

25-25: Add trailing newline at EOF.

Fix YAML lint failure.

 appVersion: "7.3.63"
+
packages/apps/foundationdb/values.schema.json (2)

217-221: Constrain replicas to sane values.

Add minimum: 1.

     "replicas": {
       "description": "Number of FoundationDB replicas (total instances)",
       "type": "integer",
-      "default": 3
+      "default": 3,
+      "minimum": 1
     },

1-4: Optionally disallow unknown keys to catch typos.

Consider additionalProperties: false at the top level (only if templates don’t rely on free-form extras).

 {
   "title": "Chart Values",
-  "type": "object",
+  "type": "object",
+  "additionalProperties": false,
packages/apps/foundationdb/values.yaml (1)

91-92: Add trailing newline at EOF.

Fix YAML lint error.

 automaticReplacements: true
+
hack/e2e-apps/foundationdb.bats (1)

5-6: Quote the here-doc to avoid accidental shell expansion.

Prevents future escapes like $VAR inside YAML.

-kubectl apply -f - <<EOF
+kubectl apply -f - <<'YAML'
@@
-EOF
+YAML

Also applies to: 19-22

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15944d6 and dc8ccc9.

📒 Files selected for processing (5)
  • hack/e2e-apps/foundationdb.bats (1 hunks)
  • packages/apps/foundationdb/Chart.yaml (1 hunks)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/apps/foundationdb/README.md
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/Chart.yaml

[error] 25-25: no new line character at the end of file

(new-line-at-end-of-file)

packages/apps/foundationdb/values.yaml

[error] 92-92: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (3)
packages/apps/foundationdb/Chart.yaml (2)

4-4: Icon path verified — file exists
Found at packages/apps/foundationdb/logos/foundationdb.svg (corresponds to /logos/foundationdb.svg).


19-25: appVersion matches values.cluster.version (7.3.63) — keep in lockstep; EOF newline unverified

Verified: packages/apps/foundationdb/Chart.yaml -> 7.3.63 and values.yaml -> 7.3.63; od was missing in the sandbox so EOF-newline check failed. Re-run an EOF-newline check for packages/apps/foundationdb/Chart.yaml and packages/apps/foundationdb/values.yaml (e.g., a small python one-liner to inspect the last byte) and report results.

hack/e2e-apps/foundationdb.bats (1)

53-55: Verify .status.databaseConfiguration.usable_regions is present and correct for readiness check

Run: kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org test -o json | jq '.status' or kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org test -o jsonpath='{.status.databaseConfiguration.usable_regions}' and confirm the field exists for the operator version used in CI; if it doesn't exist, change the wait to rely on .status.health.available (already checked below).

Location: hack/e2e-apps/foundationdb.bats:53-55

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/apps/foundationdb/values.yaml (1)

53-66: Remove plaintext S3 credentials; switch to Secret ref.

Do not ship accessKeyId/secretAccessKey in values. Reference a Kubernetes Secret instead and update template/docs accordingly.

Apply in values.yaml:

 ## @field backupS3.region {string} S3 region
-## @field backupS3.credentials {backupS3Credentials} S3 credentials
-## @field backupS3Credentials.accessKeyId {string} S3 access key ID
-## @field backupS3Credentials.secretAccessKey {string} S3 secret access key
+## @field backupS3.secretRef {secretRef} Reference to a Secret with S3 credentials
+## @field secretRef.name {string} Secret name
+## @field secretRef.accessKeyKey {string} Key in Secret for access key ID
+## @field secretRef.secretKeyKey {string} Key in Secret for secret access key
 ## @field backup.retentionPolicy {string} Retention policy for backups
 backup:
   enabled: false
   s3:
     bucket: ""
     endpoint: ""
     region: "us-east-1"
-    credentials:
-      accessKeyId: ""
-      secretAccessKey: ""
+    secretRef:
+      name: ""
+      accessKeyKey: accessKeyId
+      secretKeyKey: secretAccessKey
   retentionPolicy: "7d"

Follow-up: I can provide the template changes to consume secretKeyRef if you want.

🧹 Nitpick comments (2)
packages/apps/foundationdb/values.yaml (2)

83-89: Good: defaults run as non‑root; consider adding defense‑in‑depth flags.

Recommend enabling runAsNonRoot, disabling privilege escalation, and using RuntimeDefault seccomp; optionally read‑only root FS (if image supports it).

 securityContext:
+  runAsNonRoot: true
   runAsUser: 4059
   runAsGroup: 4059
+  allowPrivilegeEscalation: false
+  readOnlyRootFilesystem: true
+  seccompProfile:
+    type: RuntimeDefault

91-91: Fix YAMLlint: ensure newline at end of file.

Adds a trailing newline to satisfy linters/posix tools.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc8ccc9 and aecfbbb.

📒 Files selected for processing (3)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/apps/foundationdb/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/apps/foundationdb/values.schema.json
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/values.yaml

[error] 91-91: no new line character at the end of file

(new-line-at-end-of-file)

Comment thread packages/apps/foundationdb/values.yaml Outdated
Comment on lines +80 to +82
## @param imageType {string enum:"unified,split"} Container image deployment type (split recommended for production)
imageType: "split"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify CRD field names match operator v2.13.0.

Please confirm imageType and automaticReplacements align with the FoundationDB operator CR spec for v2.13.0; names changed across versions.

Also applies to: 90-91


🌐 Web query:

FoundationDB Kubernetes operator v2.13.0: what are the valid FoundationDBCluster spec fields for image type selection and automatic pod replacement? Is the field named `imageType` and `automaticReplacements`?

💡 Result:

Short answer: use spec.imageType for image selection, and spec.automationOptions.replacements.enabled for automatic replacements — there is no top-level spec.automaticReplacements field.

Sources:

  • imageType documented in the operator docs (FoundationDBCluster spec). [1]
  • AutomationOptions.Replacements.Enabled (GetEnableAutomaticReplacements) in the API / Go pkg (default true). [2]

Replace spec.automaticReplacements with spec.automationOptions.replacements.enabled; spec.imageType is correct.

Operator v2.13.0 expects spec.imageType and spec.automationOptions.replacements.enabled — there is no top-level spec.automaticReplacements.
File: packages/apps/foundationdb/values.yaml — lines 80–82 (imageType OK); lines 90–91 (update automaticReplacements → automationOptions.replacements.enabled in values and templates).

🤖 Prompt for AI Agents
In packages/apps/foundationdb/values.yaml around lines 80–82 (imageType is
correct) and lines ~90–91, replace the deprecated spec.automaticReplacements key
with spec.automationOptions.replacements.enabled: remove or rename the top-level
automaticReplacements entry in values.yaml to
automationOptions.replacements.enabled (set to true/false as appropriate) and
update any Helm chart templates that reference .Values.automaticReplacements or
spec.automaticReplacements to reference
.Values.automationOptions.replacements.enabled and
spec.automationOptions.replacements.enabled respectively so the chart matches
Operator v2.13.0’s expected structure.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

♻️ Duplicate comments (2)
packages/apps/foundationdb/templates/cluster.yaml (1)

18-35: Critical: Fix CRD field placement - multiple fields are incorrectly nested under automationOptions

Based on the v1beta2 CRD schema, several fields are incorrectly placed under automationOptions. These must be moved to the correct location in the spec:

  1. faultDomain should be at spec.faultDomain
  2. imageType should be at spec.imageType
  3. labels should be at spec.labels
  4. minimumUptimeSecondsForBounce should be at spec.minimumUptimeSecondsForBounce

Apply this diff to fix the field placement:

  automationOptions:
    replacements:
      enabled: {{ .Values.automaticReplacements }}
-    faultDomain:
-      key: {{ .Values.cluster.faultDomain.key }}
-      {{- if .Values.cluster.faultDomain.valueFrom }}
-      valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
-      {{- end }}
-    imageType: {{ .Values.imageType }}
-    labels:
-      filterOnOwnerReference: false
-      matchLabels:
-        foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
-      processClassLabels:
-        - foundationdb.org/fdb-process-class
-      processGroupIDLabels:
-        - foundationdb.org/fdb-process-group-id
-    minimumUptimeSecondsForBounce: 60
+  
+  faultDomain:
+    key: {{ .Values.cluster.faultDomain.key }}
+    {{- if .Values.cluster.faultDomain.valueFrom }}
+    valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
+    {{- end }}
+  
+  imageType: {{ .Values.imageType }}
+  
+  labels:
+    filterOnOwnerReference: false
+    matchLabels:
+      foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
+    processClassLabels:
+      - foundationdb.org/fdb-process-class
+    processGroupIDLabels:
+      - foundationdb.org/fdb-process-group-id
+  
+  minimumUptimeSecondsForBounce: 60
hack/e2e-apps/foundationdb.bats (1)

33-35: Security: Remove hardcoded credentials from test file

Hardcoded credentials trigger security scanners and set a bad example. Even for disabled features, use Secret references or environment variables.

Replace with Secret reference pattern:

      credentials:
-        accessKeyId: "oobaiRus9pah8PhohL1ThaeTa4UVa7gu"
-        secretAccessKey: "ju3eum4dekeich9ahM1te8waeGai0oog"
+        # Credentials should be provided via Secret when backup is enabled
+        # secretRef:
+        #   name: fdb-backup-credentials
🧹 Nitpick comments (3)
hack/e2e-apps/foundationdb.bats (1)

105-109: Consider adding force deletion timeout for stuck resources

If the FoundationDB cluster gets stuck during deletion (e.g., due to finalizers), the test might hang. Consider adding a force deletion after timeout.

Add graceful fallback for cleanup:

  # Clean up
  kubectl -n tenant-test delete foundationdb $name
  
  # Wait for cleanup to complete
-  timeout 120 sh -ec "while kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name 2>/dev/null; do sleep 10; done"
+  if ! timeout 120 sh -ec "while kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name 2>/dev/null; do sleep 10; done"; then
+    echo "Warning: Cluster deletion timed out, attempting force cleanup"
+    kubectl -n tenant-test patch foundationdbclusters.apps.foundationdb.org foundationdb-$name -p '{"metadata":{"finalizers":[]}}' --type=merge || true
+    kubectl -n tenant-test delete foundationdbclusters.apps.foundationdb.org foundationdb-$name --force --grace-period=0 || true
+  fi
packages/apps/foundationdb/templates/rolebinding.yaml (1)

15-17: Subjects’ name should match any truncation applied to the SA.

Keep binding consistent with the SA’s final name.

-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
packages/apps/foundationdb/templates/role.yaml (1)

22-22: Add trailing newline.

Silences linters; no functional change.

-  - delete
+  - delete
+
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aecfbbb and 4897369.

📒 Files selected for processing (5)
  • hack/e2e-apps/foundationdb.bats (1 hunks)
  • packages/apps/foundationdb/templates/cluster.yaml (1 hunks)
  • packages/apps/foundationdb/templates/role.yaml (1 hunks)
  • packages/apps/foundationdb/templates/rolebinding.yaml (1 hunks)
  • packages/apps/foundationdb/templates/serviceaccount.yaml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/templates/serviceaccount.yaml

[error] 5-5: syntax error: expected , but found ''

(syntax)

packages/apps/foundationdb/templates/role.yaml

[error] 22-22: no new line character at the end of file

(new-line-at-end-of-file)


[error] 5-5: syntax error: expected , but found ''

(syntax)

packages/apps/foundationdb/templates/rolebinding.yaml

[error] 5-5: syntax error: expected , but found ''

(syntax)

packages/apps/foundationdb/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🔇 Additional comments (10)
packages/apps/foundationdb/templates/cluster.yaml (2)

89-95: Good configuration for DNS-based locality and health monitoring

The routing and sidecar configuration looks appropriate:

  • DNS locality fields help with zone awareness
  • Liveness/readiness probes ensure proper health monitoring

90-91: Verify DNS domain configuration for multi-cluster scenarios

Templates pull dnsDomain from ConfigMap cozy-system/cozystack (default "cozy.local"); the FoundationDB CRD exposes dnsDomain; some charts hardcode "cluster.local." — ensure the ConfigMap key cluster-domain is set to the actual cluster DNS suffix (including consistent trailing-dot usage) and confirm defineDNSLocalityFields: true behaves correctly for cross-namespace / cross-cluster name resolution.

Locations: packages/apps/foundationdb/templates/cluster.yaml (dnsDomain), packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbclusters.yaml (CRD), packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml (dnsDomain), packages/system/keycloak/templates/sts.yaml (cluster-domain default).

hack/e2e-apps/foundationdb.bats (3)

54-61: Good fix: Using operator-native labels for pod selection

The test correctly uses foundationdb.org/fdb-cluster-name labels which are guaranteed to exist on FDB pods managed by the operator. This is more reliable than generic app labels.


101-103: Good security validation for non-root user context

The test properly validates that the security context is applied with the expected non-root user (4059), which is important for security compliance.


70-98: Comprehensive status validation coverage

Excellent test coverage for various cluster status fields including:

  • Health indicators (available, healthy, fullReplication)
  • Configuration validation (logs, proxies, redundancy_mode, etc.)
  • Operational status (configured, hasListenIPsForAllPods)
  • Connection string format validation

This provides good confidence in cluster health.

packages/apps/foundationdb/templates/serviceaccount.yaml (2)

4-9: YAMLlint parser warning looks template‑unaware.

The reported “expected ” at Line 5 is a false positive; rendering via helm template should be valid. Please verify with helm template.


4-9: ```shell
#!/bin/bash
set -euo pipefail

echo "=== Checking repository for ServiceAccount and usages ==="

show the target file if present

FILE="packages/apps/foundationdb/templates/serviceaccount.yaml"
if [ -f "$FILE" ]; then
echo
echo "---- $FILE ----"
sed -n '1,240p' "$FILE" || true
else
echo
echo "File not found: $FILE"
fi

echo

choose search tool

if command -v rg >/dev/null 2>&1; then
SEARCH="rg -n -S -C3"
else
SEARCH="grep -Rni --line-number --binary-files=without-match -n -C3"
fi

echo "---- Searching for serviceAccountName occurrences ----"
$SEARCH "\bserviceAccountName\b" || true

echo
echo "---- Searching for '{{ .Release.Name }}-foundationdb' or '-foundationdb' occurrences ----"
$SEARCH "{{\s*.Release.Name\s*}}\s*-foundationdb" || true
$SEARCH "-foundationdb" || true

echo
echo "---- Searching for automountServiceAccountToken occurrences ----"
$SEARCH "automountServiceAccountToken" || true

echo
echo "---- Listing files under packages/apps/foundationdb (first 3 levels) ----"
if [ -d "packages/apps/foundationdb" ]; then
find packages/apps/foundationdb -maxdepth 3 -type f -print || true
else
echo "Directory not found: packages/apps/foundationdb"
fi


</blockquote></details>
<details>
<summary>packages/apps/foundationdb/templates/rolebinding.yaml (1)</summary><blockquote>

`1-17`: **Note on YAMLlint warning.**

Same template‑unaware warning as in the SA; safe to ignore after helm template validation.

</blockquote></details>
<details>
<summary>packages/apps/foundationdb/templates/role.yaml (2)</summary><blockquote>

`1-22`: **YAMLlint syntax warning appears false‑positive.**

Likely due to Go templating. Please validate with helm template.

---

`10-22`: **RBAC scope: tighten pod permissions and add missing pod subresources if required.**

- packages/apps/foundationdb/templates/role.yaml (rules at lines ~10–22) currently grants pods: get,list,watch,create,update,patch,delete and is bound to the release ServiceAccount (see packages/apps/foundationdb/templates/rolebinding.yaml). That ServiceAccount is used by the FoundationDB podTemplate (packages/apps/foundationdb/templates/cluster.yaml → serviceAccountName). If this SA is for workload pods, remove create and delete (likely unnecessary).
- If the sidecar/init needs exec/log/status, add pods/exec, pods/log, pods/status explicitly; no pods/{exec,log,status} references were found in this chart.

Example tightening (apply if appropriate):
```diff
 rules:
 - apiGroups:
   - ""
   resources:
-  - pods
+  - pods
+  - pods/log
+  - pods/exec
+  - pods/status
   verbs:
-  - get
-  - list
-  - watch
-  - create
-  - update
-  - patch
-  - delete
+  - get
+  - list
+  - watch
+  - update
+  - patch

Comment thread hack/e2e-apps/foundationdb.bats
Comment thread packages/apps/foundationdb/templates/cluster.yaml
spec:
serviceAccountName: {{ .Release.Name }}-foundationdb
securityContext:
fsGroup: {{ .Values.securityContext.runAsGroup }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using explicit fsGroup value instead of runAsGroup

Using runAsGroup for fsGroup might cause confusion. While they often have the same value, they serve different purposes - fsGroup controls volume ownership while runAsGroup controls process GID.

Consider adding an explicit fsGroup field in your values:

-            fsGroup: {{ .Values.securityContext.runAsGroup }}
+            fsGroup: {{ .Values.securityContext.fsGroup | default .Values.securityContext.runAsGroup }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fsGroup: {{ .Values.securityContext.runAsGroup }}
fsGroup: {{ .Values.securityContext.fsGroup | default .Values.securityContext.runAsGroup }}
🤖 Prompt for AI Agents
In packages/apps/foundationdb/templates/cluster.yaml around line 52, the
template sets fsGroup to runAsGroup which conflates two distinct concerns;
update the template to read an explicit .Values.securityContext.fsGroup (and
optionally fall back to .Values.securityContext.runAsGroup only if fsGroup is
omitted) and then add an fsGroup entry to the chart's values.yaml under
securityContext so operators can configure volume ownership independently from
process GID.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .Release.Name }}-foundationdb

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Name truncation for safety.

Mirror truncation pattern used elsewhere to avoid oversize names.

-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: {{ .Release.Name }}-foundationdb
name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 5-5: syntax error: expected , but found ''

(syntax)

🤖 Prompt for AI Agents
In packages/apps/foundationdb/templates/role.yaml around line 5, the release
name is used directly for the resource name which can produce oversized names;
apply the same truncation pattern used elsewhere in the chart to limit the
length of .Release.Name before concatenating "-foundationdb" so the final name
cannot exceed the cluster/name length limits (use the existing project
helper/pattern for truncation and ensure the suffix remains intact).

Comment on lines +5 to +9
name: {{ .Release.Name }}-foundationdb
labels:
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consistent name truncation for DNS‑1123.

Match the SA’s truncation to avoid drift.

-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: {{ .Release.Name }}-foundationdb
labels:
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
labels:
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 5-5: syntax error: expected , but found ''

(syntax)

🤖 Prompt for AI Agents
In packages/apps/foundationdb/templates/rolebinding.yaml around lines 5 to 9,
the RoleBinding name is constructed directly from .Release.Name and can diverge
from the ServiceAccount naming/truncation rules; replace the literal name
expression with the exact same helper/templating expression used for the
ServiceAccount (the shared "fullname"/name helper or the same truncation
pipeline) so both resources use identical DNS-1123-safe truncation (lowercase,
invalid chars removed, truncated to 63 chars) and avoid drift.

apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Release.Name }}-foundationdb

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Guard against 63‑char DNS label overflows.

Helm release names can exceed limits. Consider truncating to 63 chars to avoid failures.

-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: {{ .Release.Name }}-foundationdb
name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 5-5: syntax error: expected , but found ''

(syntax)

🤖 Prompt for AI Agents
In packages/apps/foundationdb/templates/serviceaccount.yaml around line 5, the
ServiceAccount name uses {{ .Release.Name }} directly which can exceed the
63‑character DNS label limit; update the template to truncate or hash the
release name to 63 characters (e.g., use the Helm truncate function or combine
truncation with a short checksum) and ensure any appended suffix (like
"-foundationdb") keeps the total length ≤63 so the rendered name is always a
valid DNS label.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (3)
packages/apps/foundationdb/values.yaml (3)

58-66: Avoid plaintext cloud credentials in values; use Secret refs.

Inline keys are a compliance risk and end up in ConfigMaps. Prefer referencing a Secret.

Apply:

 backup:
   enabled: false
   s3:
     bucket: ""
     endpoint: ""
     region: "us-east-1"
-    credentials:
-      accessKeyId: ""
-      secretAccessKey: ""
+    secretRef:
+      name: ""           # k8s Secret name
+      accessKeyKey: accessKeyId
+      secretKeyKey: secretAccessKey
   retentionPolicy: "7d"

Update templates to read from the Secret keys.


90-91: Wrong field for auto-replacements; align with Operator v2.13.0.

Replace automaticReplacements with automationOptions.replacements.enabled.

Apply:

-## @param automaticReplacements {bool} Enable automatic pod replacements
-automaticReplacements: true
+## @param automationOptions {object} Operator automation options
+automationOptions:
+  replacements:
+    enabled: true

Update templates accordingly.


83-89: Augment securityContext with runAsNonRoot/allowPrivilegeEscalation.

Make least-privilege explicit; keep UID/GID 4059.

Apply:

 securityContext:
   runAsUser: 4059
   runAsGroup: 4059
+  runAsNonRoot: true
+  allowPrivilegeEscalation: false

Consider readOnlyRootFilesystem if images support it.

🧹 Nitpick comments (2)
packages/apps/foundationdb/README.md (1)

110-116: Tighten documented security posture to match values/templates.

Explicitly call out runAsNonRoot: true and allowPrivilegeEscalation: false in examples to reflect least-privilege defaults.

packages/apps/foundationdb/values.yaml (1)

91-91: Add final newline.

YAMLlint reports missing newline at EOF.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4897369 and 615b2b5.

📒 Files selected for processing (4)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
  • packages/system/dashboard/values.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/apps/foundationdb/values.schema.json
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/values.yaml

[error] 91-91: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (1)
packages/system/dashboard/values.yaml (1)

240-253: FoundationDB wiring — Chart and versions_map present; HelmRepository not found

  • packages/apps/foundationdb/Chart.yaml: contains name: foundationdb.
  • versions_map: entry "foundationdb 0.1.0 HEAD" found.
  • packages/system/dashboard/values.yaml (lines ~235–260): no 'HelmRepository' / sourceRef match — confirm sourceRef: kind: HelmRepository exists or add the HelmRepository reference.

Comment on lines +61 to +72
```yaml
backup:
enabled: true
s3:
bucket: "my-fdb-backups"
endpoint: "https://s3.amazonaws.com"
region: "us-east-1"
credentials:
accessKeyId: "AKIA..."
secretAccessKey: "..."
retentionPolicy: "7d"
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Don’t document plaintext S3 keys; switch docs to Secret refs.

Examples with accessKeyId/secretAccessKey encourage insecure usage. Show Secret-based config.

Apply:

-  s3:
-    bucket: "my-fdb-backups"
-    endpoint: "https://s3.amazonaws.com"
-    region: "us-east-1"
-    credentials:
-      accessKeyId: "AKIA..."
-      secretAccessKey: "..."
+  s3:
+    bucket: "my-fdb-backups"
+    endpoint: "https://s3.amazonaws.com"
+    region: "us-east-1"
+    secretRef:
+      name: "fdb-backup-creds"
+      accessKeyKey: "accessKeyId"
+      secretKeyKey: "secretAccessKey"

Update templates accordingly.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```yaml
backup:
enabled: true
s3:
bucket: "my-fdb-backups"
endpoint: "https://s3.amazonaws.com"
region: "us-east-1"
credentials:
accessKeyId: "AKIA..."
secretAccessKey: "..."
retentionPolicy: "7d"
```
backup:
enabled: true
s3:
bucket: "my-fdb-backups"
endpoint: "https://s3.amazonaws.com"
region: "us-east-1"
secretRef:
name: "fdb-backup-creds"
accessKeyKey: "accessKeyId"
secretKeyKey: "secretAccessKey"
retentionPolicy: "7d"

Comment thread packages/apps/foundationdb/README.md Outdated
Comment on lines +77 to +87
advanced:
# Custom FoundationDB parameters
customParameters:
- "knob_disable_posix_kernel_aio=1"

# Image type (split recommended for production)
imageType: "split"

# Enable automatic pod replacements
automaticReplacements: true
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Field name: use automationOptions.replacements.enabled (v2.13.0).

Operator expects spec.automationOptions.replacements.enabled, not top-level automaticReplacements.

Apply:

-  # Enable automatic pod replacements
-  automaticReplacements: true
+  # Enable automatic pod replacements
+  automationOptions:
+    replacements:
+      enabled: true

Ensure templates map to spec.automationOptions.replacements.enabled.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
advanced:
# Custom FoundationDB parameters
customParameters:
- "knob_disable_posix_kernel_aio=1"
# Image type (split recommended for production)
imageType: "split"
# Enable automatic pod replacements
automaticReplacements: true
```
advanced:
# Custom FoundationDB parameters
customParameters:
- "knob_disable_posix_kernel_aio=1"
# Image type (split recommended for production)
imageType: "split"
# Enable automatic pod replacements
automationOptions:
replacements:
enabled: true
🤖 Prompt for AI Agents
In packages/apps/foundationdb/README.md around lines 77 to 87, the README shows
using a top-level automaticReplacements field but the operator expects
spec.automationOptions.replacements.enabled; update the example and any
Helm/manifest templates to remove automaticReplacements and instead set
spec.automationOptions.replacements.enabled: true (or false as appropriate), and
ensure template values map into that nested path (e.g.,
values.automationOptions.replacements.enabled) so manifests render the correct
field.

Comment on lines +24 to +29
version: "7.3.63"

faultDomain:
key: "kubernetes.io/hostname"
valueFrom: "spec.nodeName"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify faultDomain.valueFrom rendering matches Operator schema.

Operator typically expects valueFrom.fieldRef.fieldPath: spec.nodeName. Ensure templates construct the nested structure (not a raw string).

Expect to see:
spec:
faultDomain:
key: kubernetes.io/hostname
valueFrom:
fieldRef:
fieldPath: spec.nodeName


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -C3 'faultDomain' packages/apps/foundationdb/templates || true

Length of output: 868


Render faultDomain.valueFrom as a nested mapping (fieldRef.fieldPath); do not pass a raw string. Template currently emits .Values.cluster.faultDomain.valueFrom verbatim (packages/apps/foundationdb/templates/cluster.yaml:21–24); with values.yaml's valueFrom: "spec.nodeName" this will render a scalar and not the Operator-expected mapping. Fix by either:

  • Update packages/apps/foundationdb/values.yaml to provide the nested mapping:
    faultDomain:
    key: kubernetes.io/hostname
    valueFrom:
    fieldRef:
    fieldPath: spec.nodeName

  • Or change the template to render the mapping safely (example):
    valueFrom:
    {{- toYaml .Values.cluster.faultDomain.valueFrom | nindent 6 }}

🤖 Prompt for AI Agents
In packages/apps/foundationdb/values.yaml around lines 24 to 29,
faultDomain.valueFrom is a raw string which will render as a scalar but the
Operator expects a nested mapping (fieldRef.fieldPath); fix by either updating
the values.yaml to provide valueFrom as a mapping with fieldRef.fieldPath (i.e.,
valueFrom: fieldRef: fieldPath: spec.nodeName) or change the cluster template to
safely render the mapping using toYaml and nindent so the nested structure is
emitted (e.g., render valueFrom: {{- toYaml
.Values.cluster.faultDomain.valueFrom | nindent <correct indent> }}) so the
Operator receives the correct mapping.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
packages/apps/foundationdb/values.yaml (3)

45-64: Replace plaintext S3 credentials with Secret ref

Avoid embedding access keys in values; default to referencing a Kubernetes Secret.

Apply this diff and adjust templates to read from the Secret:

   s3:
     bucket: ""
     endpoint: ""
     region: "us-east-1"
-    credentials:
-      accessKeyId: ""
-      secretAccessKey: ""
+    secretRef:
+      name: ""            # Secret name with S3 creds
+      accessKeyKey: accessKeyId
+      secretKeyKey: secretAccessKey

88-89: Use automationOptions.replacements.enabled instead of automaticReplacements

Operator v2.13.0 does not support a top‑level automaticReplacements field.

Apply this diff (and update templates accordingly):

-## @param automaticReplacements {bool} Enable automatic pod replacements
-automaticReplacements: true
+## @param automationOptions.replacements.enabled {bool} Enable automatic pod replacements
+automationOptions:
+  replacements:
+    enabled: true

24-26: faultDomain.valueFrom must be a nested mapping (fieldRef.fieldPath), not a string

Operator expects a structured value; the current string will render incorrectly. Update defaults accordingly.

Apply this diff:

   faultDomain:
     key: "kubernetes.io/hostname"
-    valueFrom: "spec.nodeName"
+    valueFrom:
+      fieldRef:
+        fieldPath: spec.nodeName
🧹 Nitpick comments (3)
packages/apps/foundationdb/values.yaml (3)

8-15: Fix doc annotations for processCounts and faultDomain.valueFrom type

The documented field paths/types don’t match the actual structure; this will generate confusing README.

Apply this diff:

-## @field clusterProcessCounts.stateless {int} Number of stateless processes (-1 for automatic)
-## @field clusterProcessCounts.storage {int} Number of storage processes (determines cluster size)
-## @field clusterProcessCounts.cluster_controller {int} Number of cluster controller processes
+## @field processCounts.stateless {int} Number of stateless processes (-1 for automatic)
+## @field processCounts.storage {int} Number of storage processes (determines cluster size)
+## @field processCounts.cluster_controller {int} Number of cluster controller processes
@@
-## @field clusterFaultDomain.valueFrom {string} Fault domain value source
+## @field clusterFaultDomain.valueFrom {object} Fault domain value source (fieldRef.fieldPath)

81-87: Harden securityContext defaults

Good move to non‑root. Also set runAsNonRoot and disable privilege escalation by default.

Apply this diff:

 securityContext:
+  runAsNonRoot: true
   runAsUser: 4059
   runAsGroup: 4059
+  allowPrivilegeEscalation: false

Optional: consider a podSecurityContext with fsGroup: 4059 if volumes require group ownership.


89-89: Add a trailing newline

YAMLlint warns about missing EOF newline.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 615b2b5 and eecd404.

📒 Files selected for processing (3)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/apps/foundationdb/README.md
  • packages/apps/foundationdb/values.schema.json
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/values.yaml

[error] 89-89: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (2)
packages/apps/foundationdb/values.yaml (2)

78-80: imageType default looks correct

“unified” matches supported values for recent operator versions.


1-89: No action required — values, schema and templates are consistent

automaticReplacements is present in values.yaml and values.schema.json and is consumed by templates/cluster.yaml (automationOptions.replacements.enabled); cluster.faultDomain.{key,valueFrom} is rendered from .Values.cluster.faultDomain; backup.s3 credentials are emitted as a Secret in templates/backup.yaml and referenced with secretKeyRef — no stale keys or mismatches found.

@insignia96

Isaiah Olson (insignia96) commented Sep 15, 2025

Copy link
Copy Markdown
Contributor Author

Timofei Larkin (@lllamnyp) Okay, as of this latest commit, I think this is in a good working state and I have run the tests in my cluster to verify it seems to work. Backups have not been tested yet, but the core functionality seems to be there in the rest. It is probably ready if you all would like to test it as well.

Future roadmap items would be:

  • Exporting Prometheus metrics and adding a Grafana dashboard
  • Adding a self-signed issuer and TLS for the database, but this is complicated by the need for the operator to have access to the certs to speak with the database and manage it.
  • Better tests for more complex database types and multi-region support.
  • Disaster recovery backup types, streaming to a remote FoundationDB cluster or acting as a target.
  • Update the values to make the storage claims more configurable, to allow stateless pods and storage pods to have different sizes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
packages/apps/foundationdb/values.yaml (1)

61-68: Stop shipping plaintext S3 credentials in defaults; use a Secret reference.

Avoid accidental key exposure via Git/ConfigMaps.

 backup:
   enabled: false
   s3:
     bucket: ""
     endpoint: ""
     region: "us-east-1"
-    credentials:
-      accessKeyId: ""
-      secretAccessKey: ""
+    secretRef:
+      name: ""              # Kubernetes Secret name
+      accessKeyKey: accessKeyId
+      secretKeyKey: secretAccessKey
   retentionPolicy: "7d"

Follow-up: update backup templates to read from the Secret.

packages/apps/foundationdb/templates/cluster.yaml (1)

22-40: Incorrect nesting under automationOptions (CRD mismatch) — move fields to spec.

faultDomain, imageType, labels, minimumUptimeSecondsForBounce are top-level spec fields in v1beta2; under automationOptions they will be ignored.

Apply:

   automationOptions:
     replacements:
       enabled: {{ .Values.automaticReplacements }}
-    faultDomain:
-      key: {{ .Values.cluster.faultDomain.key }}
-      {{- if .Values.cluster.faultDomain.valueFrom }}
-      valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
-      {{- end }}
-    imageType: {{ .Values.imageType }}
-    labels:
-      filterOnOwnerReference: false
-      matchLabels:
-        foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
-      processClassLabels:
-        - foundationdb.org/fdb-process-class
-      processGroupIDLabels:
-        - foundationdb.org/fdb-process-group-id
-    minimumUptimeSecondsForBounce: 60
+  imageType: {{ .Values.imageType }}
+  faultDomain:
+    key: {{ .Values.cluster.faultDomain.key }}
+    {{- if .Values.cluster.faultDomain.valueFrom }}
+    valueFrom:
+      {{- toYaml .Values.cluster.faultDomain.valueFrom | nindent 6 }}
+    {{- end }}
+  labels:
+    filterOnOwnerReference: false
+    matchLabels:
+      foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
+    processClassLabels:
+      - foundationdb.org/fdb-process-class
+    processGroupIDLabels:
+      - foundationdb.org/fdb-process-group-id
+  minimumUptimeSecondsForBounce: 60
🧹 Nitpick comments (7)
packages/apps/foundationdb/values.schema.json (2)

276-299: Expand securityContext to include runAsNonRoot, allowPrivilegeEscalation, fsGroup.

Tightens defaults and aligns with pod/container security knobs.

       "properties": {
+        "runAsNonRoot": {
+          "description": "Require the container to run as non-root",
+          "type": "boolean",
+          "default": true
+        },
         "runAsGroup": {
           "description": "Group ID to run the container",
           "type": "integer",
           "default": 4059
         },
         "runAsUser": {
           "description": "User ID to run the container",
           "type": "integer",
           "default": 4059
+        },
+        "fsGroup": {
+          "description": "File system group for volume ownership",
+          "type": "integer"
+        },
+        "allowPrivilegeEscalation": {
+          "description": "Whether a process can gain more privileges than its parent",
+          "type": "boolean",
+          "default": false
         }
       }

5-9: Consider renaming automaticReplacements to automationOptions.replacements.enabled (schema surface).

Mirrors operator shape and avoids ambiguity, but keep a compatibility alias if you change it.

packages/apps/foundationdb/values.yaml (4)

28-31: faultDomain.valueFrom should be a mapping (fieldRef.fieldPath), not a scalar.

Adjust to Downward API shape so the operator parses it correctly.

 faultDomain:
   key: "kubernetes.io/hostname"
-  valueFrom: "spec.nodeName"
+  valueFrom:
+    fieldRef:
+      fieldPath: spec.nodeName

85-91: Harden securityContext defaults and allow explicit fsGroup.

Add runAsNonRoot and allowPrivilegeEscalation; expose fsGroup to separate from runAsGroup.

 securityContext:
-  runAsUser: 4059
-  runAsGroup: 4059
+  runAsNonRoot: true
+  allowPrivilegeEscalation: false
+  runAsUser: 4059
+  runAsGroup: 4059
+  # Optional; if omitted, template should fall back to runAsGroup
+  fsGroup: 4059

92-93: Optional: rename automaticReplacements to automationOptions.replacements.enabled.

Aligns values with operator structure; keep the old key as a deprecated alias in templates to avoid breaking users.

-## @param automaticReplacements {bool} Enable automatic pod replacements
-automaticReplacements: true
+## @param automationOptions.replacements.enabled {bool} Enable automatic pod replacements
+automationOptions:
+  replacements:
+    enabled: true

93-93: Add newline at EOF.

Silences linters; no behavior change.

packages/apps/foundationdb/templates/cluster.yaml (1)

56-57: fsGroup should be configurable, not hard‑wired to runAsGroup.

Allow explicit fsGroup with fallback to runAsGroup.

-            fsGroup: {{ .Values.securityContext.runAsGroup }}
+            fsGroup: {{ .Values.securityContext.fsGroup | default .Values.securityContext.runAsGroup }}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eecd404 and 6679530.

📒 Files selected for processing (7)
  • hack/e2e-apps/foundationdb.bats (1 hunks)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/templates/_resources.tpl (1 hunks)
  • packages/apps/foundationdb/templates/cluster.yaml (1 hunks)
  • packages/apps/foundationdb/templates/workloadmonitor.yaml (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/apps/foundationdb/templates/_resources.tpl
  • hack/e2e-apps/foundationdb.bats
  • packages/apps/foundationdb/README.md
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/templates/workloadmonitor.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/values.yaml

[error] 93-93: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (2)
packages/apps/foundationdb/templates/cluster.yaml (1)

54-54: ServiceAccount template present — no action required.
packages/apps/foundationdb/templates/serviceaccount.yaml defines metadata.name: {{ .Release.Name }}-foundationdb and packages/apps/foundationdb/templates/rolebinding.yaml contains matching references.

packages/apps/foundationdb/templates/workloadmonitor.yaml (1)

11-19: Verify WorkloadMonitor schema fields (replicas/minReplicas/kind/type/selector)

Could not open the WorkloadMonitor CRD template in the workspace (rg found references but the CRD file wasn't readable). Confirm that the fields used in the template match the WorkloadMonitor CRD (cozystack.io/v1alpha1).

Files to check:

  • packages/apps/foundationdb/templates/workloadmonitor.yaml (spec block around lines 11–19)
  • packages/cozystack-controller/templates/crds/cozystack.io_workloadmonitors.yaml

Comment on lines +25 to +29
faultDomain:
key: {{ .Values.cluster.faultDomain.key }}
{{- if .Values.cluster.faultDomain.valueFrom }}
valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
{{- end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

faultDomain.valueFrom rendered as scalar; emit proper mapping.

After updating values.yaml, render the mapping via toYaml to preserve structure.

-      {{- if .Values.cluster.faultDomain.valueFrom }}
-      valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
-      {{- end }}
+      {{- if .Values.cluster.faultDomain.valueFrom }}
+      valueFrom:
+        {{- toYaml .Values.cluster.faultDomain.valueFrom | nindent 8 }}
+      {{- end }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
faultDomain:
key: {{ .Values.cluster.faultDomain.key }}
{{- if .Values.cluster.faultDomain.valueFrom }}
valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
{{- end }}
faultDomain:
key: {{ .Values.cluster.faultDomain.key }}
{{- if .Values.cluster.faultDomain.valueFrom }}
valueFrom:
{{- toYaml .Values.cluster.faultDomain.valueFrom | nindent 8 }}
{{- end }}
🤖 Prompt for AI Agents
In packages/apps/foundationdb/templates/cluster.yaml around lines 25 to 29,
faultDomain.valueFrom is being rendered as a scalar which flattens nested
mappings; change the template to render the entire valueFrom structure with
toYaml and proper indentation (pipe through toYaml and indent by the same number
of spaces as the surrounding block) so nested keys are preserved when valueFrom
is present.

Comment on lines +16 to +25
"s3": {
"bucket": "",
"credentials": {
"accessKeyId": "",
"secretAccessKey": ""
},
"endpoint": "",
"region": "us-east-1"
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace plaintext S3 credentials with Secret reference in schema (security/privacy).

Do not model accessKeyId/secretAccessKey inline. Switch to secretRef and make it required; update defaults accordingly.

Apply this diff (two places shown; mirrors values.yaml):

@@
-        "s3": {
-          "bucket": "",
-          "credentials": {
-            "accessKeyId": "",
-            "secretAccessKey": ""
-          },
-          "endpoint": "",
-          "region": "us-east-1"
-        }
+        "s3": {
+          "bucket": "",
+          "secretRef": {
+            "name": "",
+            "accessKeyKey": "accessKeyId",
+            "secretKeyKey": "secretAccessKey"
+          },
+          "endpoint": "",
+          "region": "us-east-1"
+        }
@@
-        "s3": {
+        "s3": {
           "description": "S3 configuration for backups",
           "type": "object",
           "default": {
             "bucket": "",
-            "credentials": {
-              "accessKeyId": "",
-              "secretAccessKey": ""
-            },
+            "secretRef": {
+              "name": "",
+              "accessKeyKey": "accessKeyId",
+              "secretKeyKey": "secretAccessKey"
+            },
             "endpoint": "",
             "region": "us-east-1"
           },
           "required": [
             "bucket",
-            "credentials",
+            "secretRef",
             "endpoint",
             "region"
           ],
           "properties": {
             "bucket": { "description": "S3 bucket name", "type": "string" },
-            "credentials": {
-              "description": "S3 credentials",
-              "type": "object",
-              "default": { "accessKeyId": "", "secretAccessKey": "" },
-              "required": ["accessKeyId","secretAccessKey"],
-              "properties": {
-                "accessKeyId": { "description": "S3 access key ID", "type": "string" },
-                "secretAccessKey": { "description": "S3 secret access key", "type": "string" }
-              }
-            },
+            "secretRef": {
+              "description": "Reference to a Secret containing S3 credentials",
+              "type": "object",
+              "required": ["name","accessKeyKey","secretKeyKey"],
+              "properties": {
+                "name": { "type": "string", "description": "Secret name" },
+                "accessKeyKey": { "type": "string", "default": "accessKeyId" },
+                "secretKeyKey": { "type": "string", "default": "secretAccessKey" }
+              }
+            },
             "endpoint": { "description": "S3 endpoint URL", "type": "string" },
             "region": { "description": "S3 region", "type": "string", "default": "us-east-1" }
           }
         }

Optional: support legacy credentials via oneOf for a deprecation window.

Also applies to: 42-97

Comment on lines +125 to +147
"faultDomain": {
"description": "Fault domain configuration",
"type": "object",
"default": {
"key": "kubernetes.io/hostname",
"valueFrom": "spec.nodeName"
},
"required": [
"key",
"valueFrom"
],
"properties": {
"key": {
"description": "Fault domain key",
"type": "string",
"default": "kubernetes.io/hostname"
},
"valueFrom": {
"description": "Fault domain value source",
"type": "string",
"default": "spec.nodeName"
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

faultDomain.valueFrom should be an object (fieldRef.fieldPath), not a string.

Operator expects a nested mapping. Adjust schema so clients can submit valid structures.

-            "valueFrom": {
-              "description": "Fault domain value source",
-              "type": "string",
-              "default": "spec.nodeName"
-            }
+            "valueFrom": {
+              "description": "Fault domain value source",
+              "type": "object",
+              "default": { "fieldRef": { "fieldPath": "spec.nodeName" } },
+              "required": ["fieldRef"],
+              "properties": {
+                "fieldRef": {
+                  "type": "object",
+                  "required": ["fieldPath"],
+                  "properties": {
+                    "fieldPath": { "type": "string", "default": "spec.nodeName" }
+                  }
+                }
+              }
+            }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/apps/foundationdb/values.schema.json around lines 125 to 147, the
faultDomain.valueFrom is currently defined as a string but the operator expects
a nested object ({ fieldRef: { fieldPath: string } }). Change valueFrom's type
to "object", add properties so it contains a "fieldRef" object with a
"fieldPath" string, set the default to { "fieldRef": { "fieldPath":
"spec.nodeName" } }, and update required arrays to require "fieldRef" (and
"fieldPath" inside it) so clients can submit the nested mapping the operator
expects.

@lllamnyp

Copy link
Copy Markdown
Member

Timofei Larkin (@lllamnyp) I have marked this as ready for review after making the changes you mentioned. I do have one bare metal node in my cluster that could work to run the test setup in the repo. I am working on getting that set up to test on my end as well.

Great! We'll get this tested.

@lllamnyp Timofei Larkin (lllamnyp) added the ok-to-test Indicates a non-member PR is safe to run CI on label Sep 16, 2025
@lllamnyp

Timofei Larkin (lllamnyp) commented Sep 16, 2025

Copy link
Copy Markdown
Member

Isaiah Olson (@insignia96) could you rebase your branch against main to trigger the workflow for the newest CI config?

Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
…rator by default

Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
…t images and use unified by default

Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
…cy mode, update tests, and fix workload monitor

Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
@insignia96

Isaiah Olson (insignia96) commented Sep 17, 2025

Copy link
Copy Markdown
Contributor Author

Timofei Larkin (@lllamnyp) Okay, this should be done now.

As far as the backups and other roadmap items I mentioned, I am running into a bit of an issue with the backup and TLS functions and I wanted to solicit the advice of the maintainers on the best way to handle this for Cozystack. FoundationDB and the operator have some interesting constraints on credentials and certificates. In order to run commands against the database it is managing when TLS is used, the operator needs to have access to the cluster CA cert and a client cert/key pair, and for backups the operator needs access to the same blob credentials secret that the backup-agent pods in the actual database also need. Since the operator fundamentally lacks support for the kind of multi-tenancy Cozystack is designed for, because it cannot handle more than one TLS configuration or blob credential file at a time, I am thinking the best solution may be to migrate the operator to an extra feature that can be installed per-namespace, to allow isolation between tenant secrets and CAs, but the need to have the secrets in both parent and child namespaces and the operators limitations might cause an issue with properly implementing tenant inheritance it is implemented for other extra features. The operator can only be in global mode or watching one namespace. If this approach sounds okay, I could rework this to move the operator from a system namespace to an extra feature.

As it stands now, the chart as-is would require only some minor updates to allow cluster administrators to enable backups and TLS, but it would not be possible for the operator to manage any other clusters that are non-TLS or using different certs, and the cluster administrator would have to manually manage the secrets for the operator in the system-level opearator namespace similar to the process for backing up tenant Kubernetes using Velero.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (17)
packages/apps/foundationdb/templates/serviceaccount.yaml (1)

5-5: DNS-1123-safe name truncation for ServiceAccount

Use a truncation pipeline to avoid >63 char names.

-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
packages/apps/foundationdb/templates/role.yaml (1)

5-5: DNS-1123-safe name truncation for Role

Mirror the SA naming to prevent overflow.

-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
packages/apps/foundationdb/templates/rolebinding.yaml (1)

5-17: Apply consistent truncation to RoleBinding, roleRef, and subject names

Keep all three names identical and DNS‑1123 safe.

-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
@@
-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
@@
-  name: {{ .Release.Name }}-foundationdb
+  name: {{ printf "%s-foundationdb" .Release.Name | trunc 63 | trimSuffix "-" }}
packages/system/foundationdb-operator/Chart.yaml (1)

1-3: Declare fdb-operator subchart dependency and add EOF newline

Without this, the operator won’t be packaged/installed; also add newline at EOF.

 apiVersion: v2
 name: cozy-foundationdb-operator
 version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
+dependencies:
+  - name: fdb-operator
+    version: 2.13.0
+    repository: "file://charts/fdb-operator"
packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml (1)

21-25: Always set namespace on ServiceAccount subjects (both bindings).

For ServiceAccount subjects, namespace must be set regardless of globalMode; otherwise apply may fail.

 subjects:
 - kind: ServiceAccount
   name: {{ include "fdb-operator.serviceAccountName" . }}
-  {{- if .Values.globalMode.enabled }}
-  namespace: {{ .Release.Namespace }}
-  {{- end }}
+  namespace: {{ .Release.Namespace }}
@@
 subjects:
 - kind: ServiceAccount
   name: {{ include "fdb-operator.serviceAccountName" . }}
-  {{- if .Values.globalMode.enabled }}
-  namespace: {{ .Release.Namespace }}
-  {{- end }}
+  namespace: {{ .Release.Namespace }}

Also applies to: 39-43

packages/apps/foundationdb/templates/backup.yaml (2)

42-44: Do not force root; reuse chart securityContext.

Hardcoding runAsUser: 0 weakens security and diverges from values.

-            securityContext:
-              runAsUser: 0
+            securityContext:
+              {{- toYaml .Values.securityContext | nindent 14 }}

50-55: Fix S3 blobStoreConfiguration: drop accountName; wire region via urlParameters.

Mapping bucket → accountName is incorrect; region should be passed via urlParameters for S3.

-  blobStoreConfiguration:
-    accountName: {{ .Values.backup.s3.bucket }}
-    bucket: {{ .Values.backup.s3.bucket }}
-    {{- if .Values.backup.s3.endpoint }}
-    endpoint: {{ .Values.backup.s3.endpoint }}
-    {{- end }}
+  blobStoreConfiguration:
+    bucket: {{ .Values.backup.s3.bucket }}
+    {{- if .Values.backup.s3.endpoint }}
+    endpoint: {{ .Values.backup.s3.endpoint }}
+    {{- end }}
+    {{- if .Values.backup.s3.region }}
+    urlParameters:
+      - region={{ .Values.backup.s3.region }}
+    {{- end }}
packages/apps/foundationdb/values.schema.json (2)

14-97: Model S3 auth via Secret reference; remove plaintext credentials from schema.

Inline access keys in values are a security risk; switch to secretRef.

       "default": {
         "enabled": false,
         "retentionPolicy": "7d",
         "s3": {
           "bucket": "",
-          "credentials": {
-            "accessKeyId": "",
-            "secretAccessKey": ""
-          },
+          "secretRef": {
+            "name": "",
+            "accessKeyKey": "accessKeyId",
+            "secretKeyKey": "secretAccessKey"
+          },
           "endpoint": "",
           "region": "us-east-1"
         }
       },
@@
         "s3": {
           "description": "S3 configuration for backups",
           "type": "object",
           "default": {
             "bucket": "",
-            "credentials": {
-              "accessKeyId": "",
-              "secretAccessKey": ""
-            },
+            "secretRef": {
+              "name": "",
+              "accessKeyKey": "accessKeyId",
+              "secretKeyKey": "secretAccessKey"
+            },
             "endpoint": "",
             "region": "us-east-1"
           },
           "required": [
             "bucket",
-            "credentials",
+            "secretRef",
             "endpoint",
             "region"
           ],
           "properties": {
             "bucket": { "description": "S3 bucket name", "type": "string" },
-            "credentials": {
-              "description": "S3 credentials",
-              "type": "object",
-              "default": { "accessKeyId": "", "secretAccessKey": "" },
-              "required": ["accessKeyId","secretAccessKey"],
-              "properties": {
-                "accessKeyId": { "description": "S3 access key ID", "type": "string" },
-                "secretAccessKey": { "description": "S3 secret access key", "type": "string" }
-              }
-            },
+            "secretRef": {
+              "description": "Reference to a Secret containing S3 credentials",
+              "type": "object",
+              "required": ["name","accessKeyKey","secretKeyKey"],
+              "properties": {
+                "name": { "type": "string", "description": "Secret name" },
+                "accessKeyKey": { "type": "string", "default": "accessKeyId" },
+                "secretKeyKey": { "type": "string", "default": "secretAccessKey" }
+              }
+            },
             "endpoint": { "description": "S3 endpoint URL", "type": "string" },
             "region": { "description": "S3 region", "type": "string", "default": "us-east-1" }
           }
         }

100-147: faultDomain.valueFrom must be an object (fieldRef.fieldPath), not a string.

Align schema with operator expectations.

-          "default": {
-            "key": "kubernetes.io/hostname",
-            "valueFrom": "spec.nodeName"
-          },
+          "default": {
+            "key": "kubernetes.io/hostname",
+            "valueFrom": { "fieldRef": { "fieldPath": "spec.nodeName" } }
+          },
           "required": [
             "key",
             "valueFrom"
           ],
           "properties": {
@@
-            "valueFrom": {
-              "description": "Fault domain value source",
-              "type": "string",
-              "default": "spec.nodeName"
-            }
+            "valueFrom": {
+              "description": "Fault domain value source",
+              "type": "object",
+              "default": { "fieldRef": { "fieldPath": "spec.nodeName" } },
+              "required": ["fieldRef"],
+              "properties": {
+                "fieldRef": {
+                  "type": "object",
+                  "required": ["fieldPath"],
+                  "properties": {
+                    "fieldPath": { "type": "string", "default": "spec.nodeName" }
+                  }
+                }
+              }
+            }

Also applies to: 124-147

packages/apps/foundationdb/values.yaml (2)

28-31: Render faultDomain.valueFrom as a nested mapping.

Current string will render incorrectly in the CR.

   faultDomain:
     key: "kubernetes.io/hostname"
-    valueFrom: "spec.nodeName"
+    valueFrom:
+      fieldRef:
+        fieldPath: "spec.nodeName"

60-68: Do not keep plaintext cloud credentials in values; switch to Secret ref.

Replace inline access keys with a Secret reference and update templates accordingly.

 backup:
   enabled: false
   s3:
     bucket: ""
     endpoint: ""
     region: "us-east-1"
-    credentials:
-      accessKeyId: ""
-      secretAccessKey: ""
+    secretRef:
+      name: ""              # k8s Secret name
+      accessKeyKey: accessKeyId
+      secretKeyKey: secretAccessKey
packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml (2)

53-64: If you insist on namespaced mode, gate webhook perms behind globalMode.

As an alternative to the unconditional ClusterRole, keep webhook rules only when running in global/cluster scope.

- - apiGroups:
-   - admissionregistration.k8s.io
-   resources:
-   - mutatingwebhookconfigurations
-   - validatingwebhookconfigurations
-   verbs:
-   - get
-   - list
-   - watch
-   - create
-   - update
-   - patch
-   - delete
+{{- if .Values.globalMode.enabled }}
+- apiGroups:
+  - admissionregistration.k8s.io
+  resources:
+  - mutatingwebhookconfigurations
+  - validatingwebhookconfigurations
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - update
+  - patch
+  - delete
+{{- end }}

3-7: Blocker: Cluster‑scoped rules under a Role — render ClusterRole unconditionally.

This Role/ClusterRole switch allows cluster‑scoped resources (webhook configurations) to be granted by a namespaced Role when globalMode is disabled, which Kubernetes rejects. Always render a ClusterRole and ensure the binding is a ClusterRoleBinding.

Apply:

-{{- if .Values.globalMode.enabled }}
-kind: ClusterRole
-{{- else }}
-kind: Role
-{{- end }}
+kind: ClusterRole

Make sure rbac_role_binding.yaml binds via ClusterRoleBinding to the same name.

packages/apps/foundationdb/templates/cluster.yaml (3)

27-29: Quote valueFrom to preserve “$” and special chars.

Avoid YAML/Helm surprises; render as a quoted string.

-      valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
+      valueFrom: {{ .Values.cluster.faultDomain.valueFrom | quote }}

Note: valueFrom is a string in v1beta2 (e.g., spec.nodeName or $RACK). (github.com)


56-56: Read fsGroup explicitly (fallback to runAsGroup).

Don’t conflate runAsGroup and fsGroup; allow independent control.

-            fsGroup: {{ .Values.securityContext.runAsGroup }}
+            fsGroup: {{ .Values.securityContext.fsGroup | default .Values.securityContext.runAsGroup }}

22-39: Wrong field placements: move faultDomain, imageType, labels, minimumUptimeSecondsForBounce to spec top‑level.

These are top‑level fields in the v1beta2 schema, not under automationOptions. Keep automationOptions.replacements.enabled where it is.

Reference examples show:

  • spec.faultDomain with key and valueFrom (string like spec.nodeName or $RACK). (github.com)
  • spec.imageType at top level (unified/split). (github.com)
  • spec.labels and spec.minimumUptimeSecondsForBounce at top level. (forums.foundationdb.org)

Apply:

   automationOptions:
     replacements:
       enabled: {{ .Values.automaticReplacements }}
-    faultDomain:
-      key: {{ .Values.cluster.faultDomain.key }}
-      {{- if .Values.cluster.faultDomain.valueFrom }}
-      valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
-      {{- end }}
-    imageType: {{ .Values.imageType }}
-    labels:
-      filterOnOwnerReference: false
-      matchLabels:
-        foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
-      processClassLabels:
-        - foundationdb.org/fdb-process-class
-      processGroupIDLabels:
-        - foundationdb.org/fdb-process-group-id
-    minimumUptimeSecondsForBounce: 60
+
+  faultDomain:
+    key: {{ .Values.cluster.faultDomain.key }}
+    {{- if .Values.cluster.faultDomain.valueFrom }}
+    valueFrom: {{ .Values.cluster.faultDomain.valueFrom | quote }}
+    {{- end }}
+  imageType: {{ .Values.imageType | quote }}
+  labels:
+    filterOnOwnerReference: false
+    matchLabels:
+      foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
+    processClassLabels:
+      - foundationdb.org/fdb-process-class
+    processGroupIDLabels:
+      - foundationdb.org/fdb-process-group-id
+  minimumUptimeSecondsForBounce: 60
hack/e2e-apps/foundationdb.bats (1)

27-36: Good cleanup: no hardcoded credentials.

S3 credentials are empty placeholders now; avoids secret leakage in tests.

🧹 Nitpick comments (9)
packages/core/platform/bundles/distro-full.yaml (1)

158-164: Ensure namespace creation path is defined.

Confirm cozy-foundationdb-operator namespace is created (e.g., HelmRelease createNamespace: true or a separate namespace manifest). Otherwise this release will fail to install.

packages/apps/foundationdb/Chart.yaml (1)

25-25: Add trailing newline at EOF

YAML/tooling expect a newline at EOF.

packages/apps/foundationdb/templates/role.yaml (1)

10-22: Scope RBAC to least privilege (optional)

If pods aren’t created/managed via this SA, drop create/update/patch/delete.

   verbs:
-  - get
-  - list
-  - watch
-  - create
-  - update
-  - patch
-  - delete
+  - get
+  - list
+  - watch
packages/system/foundationdb-operator/values.yaml (1)

4-4: Add trailing newline at EOF

Minor YAML lint fix.

packages/apps/foundationdb/Makefile (1)

1-4: Declare phony targets and default goal

Improves make UX and avoids accidental file/target collisions.

+ .PHONY: all generate clean test
+ all: generate
  include ../../../scripts/package.mk

  generate:
  	cozyvalues-gen -v values.yaml -s values.schema.json -r README.md
+
+ clean:
+	@true
+
+ test:
+	@true
packages/apps/foundationdb/values.yaml (1)

93-93: Add trailing newline.

Minor formatting nit.

packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml (1)

91-99: Add a readinessProbe to avoid serving before handlers are ready.

Mirror liveness on /metrics for readiness.

         livenessProbe:
           httpGet:
             path: /metrics
             port: metrics
+        readinessProbe:
+          httpGet:
+            path: /metrics
+            port: metrics
packages/system/foundationdb-operator/Makefile (1)

6-19: Refactor update target to satisfy checkmake and harden the flow.

Adds PHONY targets, shortens update body, pre-cleans tmp-repo, and splits steps.

+ .PHONY: all clean test update fetch-upstream stage-charts stage-crds post-update clean-tmp
 export NAME=foundationdb-operator
 export NAMESPACE=cozy-$(NAME)
 
 include ../../../scripts/package.mk
 
+all: update
+
+clean:
+	rm -rf charts tmp-repo
+
 update:
-	rm -rf charts
-	git clone --depth 1 --branch v2.13.0 https://github.com/FoundationDB/fdb-kubernetes-operator.git tmp-repo
-	mkdir -p charts
-	cp -r tmp-repo/charts/fdb-operator charts/
-	# Remove symlinked CRDs and replace with actual files
-	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbbackups.yaml
-	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbclusters.yaml
-	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
-	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbbackups.yaml charts/fdb-operator/crds/
-	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml charts/fdb-operator/crds/
-	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbrestores.yaml charts/fdb-operator/crds/
-	rm -rf tmp-repo
-	rm -rf charts/fdb-operator/charts
+	$(MAKE) clean
+	$(MAKE) fetch-upstream
+	$(MAKE) stage-charts stage-crds
+	$(MAKE) post-update
+	$(MAKE) clean-tmp
+
+fetch-upstream:
+	rm -rf tmp-repo
+	git clone --depth 1 --branch v2.13.0 https://github.com/FoundationDB/fdb-kubernetes-operator.git tmp-repo
+	mkdir -p charts
+
+stage-charts:
+	cp -r tmp-repo/charts/fdb-operator charts/
+
+stage-crds:
+	# Remove symlinked CRDs and replace with actual files
+	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbbackups.yaml
+	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbclusters.yaml
+	rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
+	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbbackups.yaml charts/fdb-operator/crds/
+	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml charts/fdb-operator/crds/
+	cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbrestores.yaml charts/fdb-operator/crds/
+
+post-update:
+	rm -rf charts/fdb-operator/charts
+
+clean-tmp:
+	rm -rf tmp-repo
+
+test:
+	@echo "Optionally: helm lint packages/system/foundationdb-operator/charts/fdb-operator || true"
hack/e2e-apps/foundationdb.bats (1)

49-54: Minor: add failure diagnostics while waiting for the cluster.

On timeout, consider printing describe/events for the HR and FDBCluster to ease debugging.

Example:

-  timeout 300 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name; do sleep 15; done"
+  timeout 300 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name; do sleep 15; done" || {
+    kubectl -n tenant-test describe hr foundationdb-$name || true
+    kubectl -n tenant-test describe foundationdbclusters.apps.foundationdb.org foundationdb-$name || true
+    kubectl -n tenant-test get events --sort-by=.lastTimestamp | tail -n 50 || true
+    exit 1
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f08b479 and edc12e3.

⛔ Files ignored due to path filters (1)
  • packages/apps/foundationdb/logos/foundationdb.svg is excluded by !**/*.svg
📒 Files selected for processing (37)
  • hack/e2e-apps/foundationdb.bats (1 hunks)
  • packages/apps/foundationdb/.helmignore (1 hunks)
  • packages/apps/foundationdb/Chart.yaml (1 hunks)
  • packages/apps/foundationdb/Makefile (1 hunks)
  • packages/apps/foundationdb/README.md (1 hunks)
  • packages/apps/foundationdb/charts/cozy-lib (1 hunks)
  • packages/apps/foundationdb/templates/_resources.tpl (1 hunks)
  • packages/apps/foundationdb/templates/backup.yaml (1 hunks)
  • packages/apps/foundationdb/templates/cluster.yaml (1 hunks)
  • packages/apps/foundationdb/templates/dashboard-resourcemap.yaml (1 hunks)
  • packages/apps/foundationdb/templates/role.yaml (1 hunks)
  • packages/apps/foundationdb/templates/rolebinding.yaml (1 hunks)
  • packages/apps/foundationdb/templates/serviceaccount.yaml (1 hunks)
  • packages/apps/foundationdb/templates/workloadmonitor.yaml (1 hunks)
  • packages/apps/foundationdb/values.schema.json (1 hunks)
  • packages/apps/foundationdb/values.yaml (1 hunks)
  • packages/apps/versions_map (1 hunks)
  • packages/core/platform/bundles/distro-full.yaml (1 hunks)
  • packages/core/platform/bundles/distro-hosted.yaml (1 hunks)
  • packages/core/platform/bundles/paas-full.yaml (1 hunks)
  • packages/core/platform/bundles/paas-hosted.yaml (1 hunks)
  • packages/system/cozystack-api/openapi-schemas/foundationdb.json (1 hunks)
  • packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml (1 hunks)
  • packages/system/dashboard/values.yaml (1 hunks)
  • packages/system/foundationdb-operator/.helmignore (1 hunks)
  • packages/system/foundationdb-operator/Chart.yaml (1 hunks)
  • packages/system/foundationdb-operator/Makefile (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/NOTES.txt (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml (1 hunks)
  • packages/system/foundationdb-operator/charts/fdb-operator/values.yaml (1 hunks)
  • packages/system/foundationdb-operator/values.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/apps/foundationdb/charts/cozy-lib
  • packages/apps/foundationdb/.helmignore
🚧 Files skipped from review as they are similar to previous changes (14)
  • packages/core/platform/bundles/paas-hosted.yaml
  • packages/system/cozystack-api/openapi-schemas/foundationdb.json
  • packages/system/foundationdb-operator/.helmignore
  • packages/apps/versions_map
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/NOTES.txt
  • packages/system/foundationdb-operator/charts/fdb-operator/templates/_helpers.tpl
  • packages/apps/foundationdb/README.md
  • packages/system/cozystack-api/templates/cozystack-resource-definitions.yaml
  • packages/core/platform/bundles/paas-full.yaml
  • packages/system/foundationdb-operator/charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
  • packages/system/foundationdb-operator/charts/fdb-operator/Chart.yaml
  • packages/apps/foundationdb/templates/_resources.tpl
  • packages/core/platform/bundles/distro-hosted.yaml
  • packages/system/dashboard/values.yaml
🧰 Additional context used
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/templates/backup.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/values.yaml

[error] 93-93: no new line character at the end of file

(new-line-at-end-of-file)

packages/apps/foundationdb/templates/dashboard-resourcemap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/Chart.yaml

[error] 25-25: no new line character at the end of file

(new-line-at-end-of-file)

packages/apps/foundationdb/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/templates/role.yaml

[error] 22-22: no new line character at the end of file

(new-line-at-end-of-file)


[error] 5-5: syntax error: expected , but found ''

(syntax)

packages/apps/foundationdb/templates/rolebinding.yaml

[error] 5-5: syntax error: expected , but found ''

(syntax)

packages/apps/foundationdb/templates/serviceaccount.yaml

[error] 5-5: syntax error: expected , but found ''

(syntax)

packages/apps/foundationdb/templates/workloadmonitor.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/foundationdb-operator/Chart.yaml

[error] 3-3: no new line character at the end of file

(new-line-at-end-of-file)

packages/system/foundationdb-operator/charts/fdb-operator/templates/manager/deployment.yaml

[error] 7-7: syntax error: expected the node content, but found '-'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml

[error] 4-4: syntax error: could not find expected ':'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role_binding.yaml

[error] 4-4: syntax error: could not find expected ':'

(syntax)

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml

[error] 2-2: syntax error: expected the node content, but found '-'

(syntax)

packages/system/foundationdb-operator/values.yaml

[error] 4-4: no new line character at the end of file

(new-line-at-end-of-file)

🪛 checkmake (0.2.2)
packages/apps/foundationdb/Makefile

[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

packages/system/foundationdb-operator/Makefile

[warning] 6-6: Target body for "update" exceeds allowed length of 5 (13).

(maxbodylength)


[warning] 1-1: Missing required phony target "all"

(minphony)


[warning] 1-1: Missing required phony target "clean"

(minphony)


[warning] 1-1: Missing required phony target "test"

(minphony)

🔇 Additional comments (11)
packages/core/platform/bundles/distro-full.yaml (2)

158-164: Looks correct; verify metrics CRD dependency.

Block shape, namespace, and dependsOn order are consistent with other operators. If the chart installs ServiceMonitor/PrometheusRule by default, add a dependency on victoria-metrics-operator (or gate it via values) to avoid CRD race.

Option if metrics are on by default:

-  dependsOn: [cilium,cert-manager]
+  dependsOn: [cilium,cert-manager,victoria-metrics-operator]

158-164: Cross-bundle consistency check.

Please confirm identical release entries exist (and are ordered before rabbitmq-operator) in distro-hosted.yaml and the paas-* bundles, matching optional: true and dependencies.

packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/serviceaccount.yaml (1)

2-17: LGTM on conditional SA with helpers

Template uses standard helpers and optional blocks correctly.

Please ensure .Values.serviceAccount.create defaults to true in the chart’s values and that manager Deployment references the same helper for serviceAccountName.

packages/apps/foundationdb/Chart.yaml (1)

21-25: Keep appVersion aligned with defaults (values.yaml) — resolved

Chart appVersion (packages/apps/foundationdb/Chart.yaml) = 7.3.63 matches values.cluster.version (packages/apps/foundationdb/values.yaml) = 7.3.63.

packages/apps/foundationdb/templates/dashboard-resourcemap.yaml (1)

1-22: LGTM — gated config map for dashboard resource map looks correct.

Conditional rendering and embedded resources list are consistent with the app’s templates.

packages/system/foundationdb-operator/charts/fdb-operator/values.yaml (1)

1-71: Operator values look sane; image pins and security contexts are reasonable.

No changes requested.

packages/apps/foundationdb/templates/workloadmonitor.yaml (1)

1-20: LGTM — WorkloadMonitor wiring matches values and helpers.

Replicas/minReplicas source and selectors look correct.

packages/apps/foundationdb/values.yaml (1)

92-93: Map automaticReplacements → spec.automationOptions.replacements.enabled

  • Ensure packages/apps/foundationdb/values.yaml automaticReplacements (lines 92–93) is mapped by the chart/templates into FoundationDBCluster.spec.automationOptions.replacements.enabled (boolean), or rename the values key for clarity.
  • Confirm templates expose spec.imageType (values "split" (default) or "unified") when generating the cluster.
packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml (2)

113-130: Verify binding exists for the optional nodes reader ClusterRole.

If .Values.nodeReadClusterRole is enabled, ensure there’s a matching ClusterRoleBinding to the service account.


2-7: Render templates before linting (yamllint fails on Helm templating)

Yamllint parse errors come from Helm template markers in this file; render the chart and lint the rendered YAML or configure yamllint to ignore Helm tags.

File: packages/system/foundationdb-operator/charts/fdb-operator/templates/rbac/rbac_role.yaml (lines 2–7)

Run locally/CI:

helm template fdb-op ./packages/system/foundationdb-operator/charts/fdb-operator \
  --set globalMode.enabled=true | yamllint -

Verification note: helm is not available in the verification sandbox (helm: command not found). Run the command locally or in CI and share yamllint output.

packages/apps/foundationdb/templates/cluster.yaml (1)

54-55: Confirm ServiceAccount exists.

serviceAccountName references “{{ .Release.Name }}-foundationdb”. Ensure packages/apps/foundationdb/templates/serviceaccount.yaml is present.

Comment on lines +1 to +4
fdb-operator:
globalMode:
enabled: true
nodeReadClusterRole: true No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Top-level subchart values ignored without dependency declaration

These values won’t merge unless the operator subchart is declared in Chart.yaml.

Fix by adding a dependency in packages/system/foundationdb-operator/Chart.yaml (see comment there). Keep these keys once the dependency exists.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 4-4: no new line character at the end of file

(new-line-at-end-of-file)

🤖 Prompt for AI Agents
In packages/system/foundationdb-operator/values.yaml around lines 1 to 4, the
top-level fdb-operator keys will be ignored unless the operator subchart is
listed as a dependency in packages/system/foundationdb-operator/Chart.yaml;
update that Chart.yaml to declare the operator subchart dependency (name,
repository and version) per the comment in that Chart.yaml, then keep the
existing fdb-operator.globalMode.enabled and fdb-operator.nodeReadClusterRole
keys in values.yaml so they merge correctly once the dependency is present.

@lllamnyp

Copy link
Copy Markdown
Member

Sorry for taking a while, I was away for the latter half of last week. Looks like we're still struggling to get external PRs working properly. I'll test this manually and will come back with feedback soon.

@IvanHunters

Copy link
Copy Markdown
Collaborator

Hi Isaiah Olson (@insignia96) !

Thanks for writing the test. This is a very cool job, but there are problems with deploying applications in your PR.
In particular, this is due to the fact that pvc cannot be created.
Here are the errors:

0/3 nodes are available: persistentvolumeclaim "foundationdb-test-storage-31036-data" not found. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.
0/3 nodes are available: persistentvolumeclaim "foundationdb-test-storage-68314-data" not found. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.
0/3 nodes are available: persistentvolumeclaim "foundationdb-test-log-27880-data" not found. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.
0/3 nodes are available: persistentvolumeclaim "foundationdb-test-log-45086-data" not found. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.
0/3 nodes are available: persistentvolumeclaim "foundationdb-test-storage-34320-data" not found. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.

Please correct the errors so that the work with pvc is properly organized.

Resolve conflicts for FoundationDB feature by @insignia96

Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
@lllamnyp

Copy link
Copy Markdown
Member

I'm making the executive decision to go ahead and merge this and then fix any rough edges in upstream. Joke's on us for not having proper CI for external contributions. Thanks for your amazing work!

@lllamnyp
Timofei Larkin (lllamnyp) merged commit d86742e into cozystack:main Oct 10, 2025
1 of 2 checks passed
@insignia96

Copy link
Copy Markdown
Contributor Author

Timofei Larkin (@lllamnyp) Thanks! I haven't had a look at the PVC error mentioned above. It works on my cluster, but that's hardly a guarantee I didn't miss something. The chart defaults to the default local storage class by leaving it blank, so that might have caused it. Glad to see it merged!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Indicates a non-member PR is safe to run CI on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants