Skip to content

Deploy Fournos in a dedicated namespace#79

Open
avasilevskii wants to merge 3 commits intoopenshift-psap:mainfrom
avasilevskii:dedicated-operator-namespace
Open

Deploy Fournos in a dedicated namespace#79
avasilevskii wants to merge 3 commits intoopenshift-psap:mainfrom
avasilevskii:dedicated-operator-namespace

Conversation

@avasilevskii
Copy link
Copy Markdown
Collaborator

@avasilevskii avasilevskii commented May 6, 2026

Closes #36.

Summary by CodeRabbit

  • New Features

    • Added multi-namespace deployment support for controller and execution components.
    • Enabled production Forge execution asset deployment.
    • Introduced Vault secret synchronization documentation for pipeline runs.
  • Documentation

    • Expanded deployment and operational guidance for production usage.
    • Added cluster onboarding workflow and connectivity configuration steps.
    • Documented secret management patterns and lifecycle ownership.
  • Chores

    • Updated namespace configurations across deployment manifests.

Signed-off-by: avasilev <avasilev@redhat.com>
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 6, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign tosokin for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

Warning

Rate limit exceeded

@avasilevskii has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 36 minutes and 53 seconds before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: afa014e4-a569-4a38-ba0e-b9aa5cdb428c

📥 Commits

Reviewing files that changed from the base of the PR and between 1b48333 and 264948e.

📒 Files selected for processing (1)
  • manifests/deployment.yaml
📝 Walkthrough

Walkthrough

This PR introduces a dual-namespace deployment model for Fournos, separating the operator controller (FOURNOS_CONTROLLER_NAMESPACE) from the execution workload namespace (FOURNOS_NAMESPACE). Changes span Makefile, manifests, scripts, orchestration logic, and documentation to propagate namespace variables, update RBAC bindings, and coordinate multi-namespace deployment, moving away from the previous single psap-automation namespace.

Changes

Multi-Namespace Deployment Model

Layer / File(s) Summary
Namespace Configuration
Makefile, tests/forge/deploy/orchestration/config.yaml
New FOURNOS_CONTROLLER_NAMESPACE variable (default: fournos-controller-local) and CONTROLLER_NAMESPACE config entry added; Makefile dev-setup/ci-setup export namespace defaults.
RBAC & ServiceAccount Manifests
manifests/ocpci-sa/*, manifests/rbac/clusterrolebinding_fournos.yaml, manifests/rbac/rolebinding_fournos.yaml, manifests/secrets-ns-rbac.yaml
ServiceAccount and RoleBinding namespaces updated from psap-automation to fournos-controller; RBAC manifests now reference ${CONTROLLER_NAMESPACE} placeholder for per-deployment namespace substitution.
Deployment & Env Configuration
manifests/deployment.yaml, hacks/generate-ocpci-kubeconfig.sh
Added FOURNOS_CONTROLLER_NAMESPACE environment variable sourced from pod metadata; changed default NAMESPACE in kubeconfig generator from psap-automation to fournos-controller.
Setup & Deployment Scripts
dev/setup.sh, Makefile (deploy target)
dev/setup.sh now creates CONTROLLER_NAMESPACE and Fournos namespace separately, deploys RBAC and ServiceAccounts across both namespaces with envsubst substitutions; Makefile deploy target creates/applies namespaces and manifests per-namespace with CONTROLLER_NAMESPACE substitution.
Orchestration Logic
tests/forge/deploy/orchestration/deploy.py
New ensure_controller_namespace() function creates controller namespace; new top-level deploy() orchestrator manages full sequence; manifest deployment separated by namespace (controller RBAC to controller namespace, execution RBAC/CRD to execution namespace); cleanup refactored to operate across both namespaces.
Dev/CI Runtime
Makefile (dev-run, ci-run)
dev-run and ci-run targets now propagate FOURNOS_CONTROLLER_NAMESPACE environment and launch operator via python -m fournos with explicit namespace variables.
Documentation
README.md
Deployment instructions consolidated to use make deploy with environment variables; new sections added for Vault secret synchronization flow, production Forge execution assets, and cluster onboarding.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

  • openshift-psap/fournos#9: Earlier namespace-handling refactor that removes hardcoded psap-automation and introduces templated deployment, laying groundwork for this dual-namespace model.
  • openshift-psap/fournos#27: Coordinates operator namespace configuration propagation through Makefile, dev/setup, and manifests—related foundational changes to the namespace handling approach.
  • openshift-psap/fournos#56: Modifies secrets-namespace RBAC wiring (manifests/secrets-ns-rbac.yaml) with SECRETS_NAMESPACE and controller namespace placeholders, touching the same manifest-level namespace separation logic.

Poem

🐰 The operator hops to its cozy burrow now,
CONTROLLER_NAMESPACE—clean as a rabbit's brow!
Two namespaces dancing in harmony sweet,
Orchestration and RBAC in perfect beat.
No more tangled corners where workloads compete—
A separate space makes the deployment complete! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change in the pull request - deploying Fournos in a dedicated namespace - which aligns with the core objective across all modified files.
Linked Issues check ✅ Passed All code changes align with the objective to move Fournos from the psap-automation namespace to a dedicated fournos-controller namespace, including namespace variable introduction, RBAC updates, and deployment orchestration.
Out of Scope Changes check ✅ Passed All changes focus on the namespace migration objective - introducing namespace variables, updating RBAC manifests, reconfiguring deployment scripts, and orchestrating the new multi-namespace deployment structure.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Comment thread hacks/generate-ocpci-kubeconfig.sh Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
manifests/rbac/rolebinding_fournos.yaml (1)

13-15: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: second ServiceAccount subject is missing the required namespace.

For subjects[*] of kind: ServiceAccount, Kubernetes API validation requires the namespace field. As written, applying this RoleBinding will fail with a validation error: subjects[1].namespace: Required value. Per the official Kubernetes documentation, RBAC subjects of kind ServiceAccount must specify the namespace they live in.

The second entry has the same name: fournos as the first subject. The Makefile applies sa_fournos.yaml to both $(FOURNOS_CONTROLLER_NAMESPACE) and $(FOURNOS_NAMESPACE), then applies this RoleBinding with -n $(FOURNOS_NAMESPACE). The apparent intent is to bind the fournos ServiceAccount from the execution namespace (different from the first subject). This requires an explicit namespace specification—likely a new ${NAMESPACE} template variable to match the pattern already used elsewhere in the Makefile.

🔧 Suggested fix (introduce a NAMESPACE token for the execution namespace)
 subjects:
   - kind: ServiceAccount
     name: fournos
     namespace: ${CONTROLLER_NAMESPACE}
   - kind: ServiceAccount
     name: fournos
+    namespace: ${NAMESPACE}

…and update the corresponding make deploy step to pass NAMESPACE:

-    cat $$rbac_file | CONTROLLER_NAMESPACE=$(FOURNOS_CONTROLLER_NAMESPACE) envsubst '$$CONTROLLER_NAMESPACE' | kubectl apply -f- -n $(FOURNOS_NAMESPACE); \
+    cat $$rbac_file | CONTROLLER_NAMESPACE=$(FOURNOS_CONTROLLER_NAMESPACE) NAMESPACE=$(FOURNOS_NAMESPACE) envsubst '$$CONTROLLER_NAMESPACE $$NAMESPACE' | kubectl apply -f- -n $(FOURNOS_NAMESPACE); \

If the second subject is unintentional, drop it instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@manifests/rbac/rolebinding_fournos.yaml` around lines 13 - 15, The
RoleBinding subjects list has a second subject with kind: ServiceAccount and
name: fournos but is missing the required namespace field, causing Kubernetes
validation errors; either remove the duplicate subject if unintended or add an
explicit namespace to that subject (e.g., the execution namespace token used
elsewhere) and update the related Makefile deployment to pass the new NAMESPACE
variable so the RoleBinding references the correct ServiceAccount namespace;
locate the subjects block in rolebinding_fournos.yaml (the entries with kind:
ServiceAccount and name: fournos) and align it with the sa_fournos.yaml /
FOURNOS_CONTROLLER_NAMESPACE and FOURNOS_NAMESPACE usage.
🧹 Nitpick comments (3)
hacks/generate-ocpci-kubeconfig.sh (1)

9-9: ⚡ Quick win

Hardcoded namespace won't match dev/CI defaults.

The Makefile defines FOURNOS_CONTROLLER_NAMESPACE defaults of fournos-controller-local (dev) and fournos-controller-ci-test (CI), but this script hardcodes fournos-controller. Running this helper against a dev/CI cluster will silently loop on Line 19 waiting for a secret that lives in a different namespace. Consider making this overridable via an env var.

♻️ Proposed change
-NAMESPACE="fournos-controller"
+NAMESPACE="${NAMESPACE:-fournos-controller}"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hacks/generate-ocpci-kubeconfig.sh` at line 9, The script
hacks/generate-ocpci-kubeconfig.sh hardcodes NAMESPACE="fournos-controller"
which mismatches Makefile defaults and causes waiting for a secret in the wrong
namespace; make NAMESPACE configurable by reading an environment variable (e.g.
FOURNOS_CONTROLLER_NAMESPACE) with a sensible default fallback, update any
references in the script that use NAMESPACE (search for the NAMESPACE symbol and
any lines that wait for the secret) so the script uses the env-overridable
value, and document the env var usage in the script header or help text.
Makefile (1)

35-55: 💤 Low value

Deploy target rework looks correct; one consistency note.

The multi-namespace flow is well structured: namespaces created idempotently via dry-run, RBAC scoped per namespace, envsubst correctly limits substitution to $$CONTROLLER_NAMESPACE/$$SECRETS_NAMESPACE/$$NAMESPACE. A few small notes:

  • Line 41 applies sa_fournos.yaml into the execution namespace as well as the controller namespace. This is meaningful only if the second subject of manifests/rbac/rolebinding_fournos.yaml is fixed (see comment on that file). With its current shape, the SA in the execution namespace would be unbound by the local RoleBinding.
  • Line 99 / Line 106 still default FOURNOS_NAMESPACE to psap-automation-ci-test for CI. That's the execution namespace and may be intentional, but if the goal is to fully detach Fournos from the psap-automation-* naming, consider renaming to e.g. fournos-ci-test for symmetry with the controller default.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 35 - 55, The deploy target applies the same
ServiceAccount manifest (sa_fournos.yaml) into both FOURNOS_CONTROLLER_NAMESPACE
and FOURNOS_NAMESPACE, but the RoleBinding (rolebinding_fournos.yaml) currently
does not bind the execution-namespace SA so the second apply is ineffective;
either remove the second kubectl apply for sa_fournos.yaml in FOURNOS_NAMESPACE
or update rolebinding_fournos.yaml so its subjects include the ServiceAccount in
FOURNOS_NAMESPACE (or make the RoleBinding reference a
ClusterRole/ClusterRoleBinding if cross-namespace binding is intended). Also,
normalize the CI default names for clarity by updating the FOURNOS_NAMESPACE
default (currently set elsewhere) from the psap-automation-* name to a
Fournos-specific name like fournos-ci-test if you want symmetric naming with the
controller.
tests/forge/deploy/orchestration/deploy.py (1)

367-403: 💤 Low value

Deploy ordering is correct: SA first in controller ns, then bindings in execution ns.

controller_rbac (SA) is deployed before rbac (Role/RoleBinding whose subjects reference the controller-ns SA), matching what the bindings need at apply time. The empty-list guard at line 379 is nice; you may want the same if rbac_files: guard on line 392 for symmetry, since manifests_config["rbac"] is currently a hard KeyError if the key is ever omitted in a future config variant — minor.

♻️ Optional symmetry tweak
-    # Deploy execution RBAC + CRD to execution namespace
-    rbac_files = manifests_config["rbac"]
-    crd_files = manifests_config["crd"]
+    # Deploy execution RBAC + CRD to execution namespace
+    rbac_files = manifests_config.get("rbac", [])
+    crd_files = manifests_config.get("crd", [])
     manifest_files = rbac_files + crd_files
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/forge/deploy/orchestration/deploy.py` around lines 367 - 403, The code
assumes manifests_config contains "rbac" and "crd" and will raise KeyError if
those keys are omitted; change the block that sets rbac_files/crd_files and
calls _deploy_manifest_list to first fetch them safely (e.g., using
manifests_config.get("rbac", []) and manifests_config.get("crd", [])) and add an
if rbac_files: guard (mirroring the controller_rbac_files guard) before logging
and calling _deploy_manifest_list for the RBAC+CRD deployment so missing keys
result in no-op instead of an exception.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@dev/setup.sh`:
- Around line 93-99: The Role in manifests/rbac/role_fournos.yaml is missing
permissions for KopfPeering which Kopf needs for leader election when the
operator runs in namespace-scoped mode; update role_fournos.yaml to add a rule
granting apiGroups: "kopf.dev" for resources "kopfpeerings" with verbs "list",
"watch", "patch", and "get" so the controller (running with --namespace
$FOURNOS_NAMESPACE) can access KopfPeering objects; alternatively document or
change the operator startup to use --standalone if peering is not required.

In `@manifests/deployment.yaml`:
- Around line 24-27: The deployment injects FOURNOS_CONTROLLER_NAMESPACE which
is unused; either remove that env var from the manifest or add a consuming
Settings field and usage: extend fourn os.settings.Settings
(env_prefix="FOURNOS_") with a controller_namespace: str | None field (or
similar) and wire any operator logic that needs the controller namespace to read
settings.controller_namespace (e.g., RBAC/secret resolution/self-reference code
paths such as resolve-job or secret read functions); if you choose to remove the
var, delete the FOURNOS_CONTROLLER_NAMESPACE env entry from the manifest to
avoid dead config.
- Around line 22-23: The deployment manifest sets FOURNOS_NAMESPACE to the
literal "${NAMESPACE}", which forces templating; change it to the same
in-cluster lookup used by FOURNOS_CONTROLLER_NAMESPACE (i.e., use an env var
with valueFrom.fieldRef.fieldPath: metadata.namespace) so the pod receives the
actual namespace without requiring envsubst, and if you prefer keeping
templating instead update Fournos_Design_Document.md to explicitly document the
Makefile/envsubst workflow and the requirement to replace ${NAMESPACE}.

---

Outside diff comments:
In `@manifests/rbac/rolebinding_fournos.yaml`:
- Around line 13-15: The RoleBinding subjects list has a second subject with
kind: ServiceAccount and name: fournos but is missing the required namespace
field, causing Kubernetes validation errors; either remove the duplicate subject
if unintended or add an explicit namespace to that subject (e.g., the execution
namespace token used elsewhere) and update the related Makefile deployment to
pass the new NAMESPACE variable so the RoleBinding references the correct
ServiceAccount namespace; locate the subjects block in rolebinding_fournos.yaml
(the entries with kind: ServiceAccount and name: fournos) and align it with the
sa_fournos.yaml / FOURNOS_CONTROLLER_NAMESPACE and FOURNOS_NAMESPACE usage.

---

Nitpick comments:
In `@hacks/generate-ocpci-kubeconfig.sh`:
- Line 9: The script hacks/generate-ocpci-kubeconfig.sh hardcodes
NAMESPACE="fournos-controller" which mismatches Makefile defaults and causes
waiting for a secret in the wrong namespace; make NAMESPACE configurable by
reading an environment variable (e.g. FOURNOS_CONTROLLER_NAMESPACE) with a
sensible default fallback, update any references in the script that use
NAMESPACE (search for the NAMESPACE symbol and any lines that wait for the
secret) so the script uses the env-overridable value, and document the env var
usage in the script header or help text.

In `@Makefile`:
- Around line 35-55: The deploy target applies the same ServiceAccount manifest
(sa_fournos.yaml) into both FOURNOS_CONTROLLER_NAMESPACE and FOURNOS_NAMESPACE,
but the RoleBinding (rolebinding_fournos.yaml) currently does not bind the
execution-namespace SA so the second apply is ineffective; either remove the
second kubectl apply for sa_fournos.yaml in FOURNOS_NAMESPACE or update
rolebinding_fournos.yaml so its subjects include the ServiceAccount in
FOURNOS_NAMESPACE (or make the RoleBinding reference a
ClusterRole/ClusterRoleBinding if cross-namespace binding is intended). Also,
normalize the CI default names for clarity by updating the FOURNOS_NAMESPACE
default (currently set elsewhere) from the psap-automation-* name to a
Fournos-specific name like fournos-ci-test if you want symmetric naming with the
controller.

In `@tests/forge/deploy/orchestration/deploy.py`:
- Around line 367-403: The code assumes manifests_config contains "rbac" and
"crd" and will raise KeyError if those keys are omitted; change the block that
sets rbac_files/crd_files and calls _deploy_manifest_list to first fetch them
safely (e.g., using manifests_config.get("rbac", []) and
manifests_config.get("crd", [])) and add an if rbac_files: guard (mirroring the
controller_rbac_files guard) before logging and calling _deploy_manifest_list
for the RBAC+CRD deployment so missing keys result in no-op instead of an
exception.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e568e9f8-b6a0-41fa-abd7-016ccfe14a4a

📥 Commits

Reviewing files that changed from the base of the PR and between 664bf78 and 1b48333.

📒 Files selected for processing (14)
  • Makefile
  • README.md
  • dev/setup.sh
  • hacks/generate-ocpci-kubeconfig.sh
  • manifests/deployment.yaml
  • manifests/ocpci-sa/rbac-wip-ns.yaml
  • manifests/ocpci-sa/rolebinding.yaml
  • manifests/ocpci-sa/sa.yaml
  • manifests/ocpci-sa/secret.yaml
  • manifests/rbac/clusterrolebinding_fournos.yaml
  • manifests/rbac/rolebinding_fournos.yaml
  • manifests/secrets-ns-rbac.yaml
  • tests/forge/deploy/orchestration/config.yaml
  • tests/forge/deploy/orchestration/deploy.py

Comment thread dev/setup.sh
Comment thread manifests/deployment.yaml
Comment thread manifests/deployment.yaml Outdated
Signed-off-by: avasilev <avasilev@redhat.com>
Signed-off-by: avasilev <avasilev@redhat.com>
Comment thread manifests/deployment.yaml
Comment on lines 22 to +23
- name: FOURNOS_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
value: "${NAMESPACE}"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe we can have a more meaningful name than FOURNOS_NAMESPACE 🤔

  • FOURNOS_WORKLOAD_NAMESPACE?
  • FOURNOS_TARGET_NAMESPACE?
    not sure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TASK: deploy FOURNOS in the fournos-controller namespace

2 participants