Skip to content

Conversation

@sylr
Copy link
Contributor

@sylr sylr commented Oct 29, 2025

Signed-off-by: Sylvain Rabot [email protected]

@sylr sylr requested a review from a team as a code owner October 29, 2025 17:29
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 29, 2025

Walkthrough

This PR introduces a namespace prefix configuration feature. It adds a CLI flag --namespace-prefix parsed into the Platform struct, includes utility functions to compute namespace names with optional prefixes, and updates resource controllers across the codebase to use platform-aware namespace resolution instead of direct stack names.

Changes

Cohort / File(s) Summary
Build & CLI Configuration
Makefile, cmd/main.go
Makefile build target updated to source from cmd/main.go instead of main.go. New --namespace-prefix CLI flag added and passed into Platform initialization.
Core Platform Structure
internal/core/platform.go
Added NamespacePrefix string field to Platform struct for storing the namespace prefix configuration.
Namespace Naming Utilities
internal/core/names.go
New functions GetNamespaceName() (returns prefixed namespace or stack name) and GetNamespacedResourceNameWithPrefix() (generates NamespacedName with prefix-aware namespace).
Resource Controllers - Namespace Resolution
internal/resources/benthos/controller.go, internal/resources/ledgers/deployments.go, internal/resources/payments/deployments.go, internal/resources/resourcereferences/init.go, internal/resources/stacks/init.go
Updated resource reconciliation logic to replace direct stack name namespace assignments with GetNamespaceName() calls and replaced GetNamespacedResourceName() calls with GetNamespacedResourceNameWithPrefix() to support platform-aware namespace prefixing.
Documentation
README.md
Added "Namespace Prefix Configuration" section documenting CLI flag usage and Helm chart configuration for the namespace prefix feature.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as cmd/main.go
    participant Platform as core.Platform
    participant Reconciler as Resource Controller
    participant Utilities as core.names

    User->>CLI: Provide --namespace-prefix flag
    CLI->>Platform: Initialize with NamespacePrefix
    
    Note over Reconciler: During resource reconciliation
    Reconciler->>Utilities: GetNamespaceName(platform, stackName)
    
    alt Prefix configured
        Utilities-->>Reconciler: prefix + stackName
    else No prefix
        Utilities-->>Reconciler: stackName
    end
    
    Reconciler->>Reconciler: Create/Update/Delete with<br/>platform-aware namespace
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify that all resource controllers using namespace names have been updated consistently to use the new utility functions
  • Ensure the namespace prefix logic (returning stackName when prefix is empty vs. concatenating) is applied correctly across all invocation sites
  • Validate that the Makefile change to source from cmd/main.go doesn't affect any build configurations or entry point assumptions elsewhere in the codebase

Poem

🐰 A prefix to paths, a platform-aware name,
Resources now namespaced, all perfectly tame!
With GetNamespaceName we dance through the stack,
Prefixes optional—no need to look back!
Burrow-blessed builds, our Makefile now gleams! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ❓ Inconclusive The pull request description consists only of a "Signed-off-by" Git metadata line with no actual descriptive content about the changeset. While this line is conventionally associated with commits, it provides zero meaningful information about what changes are being made, why they're being made, or how they relate to the changeset. This renders the description too vague and generic to convey any information about the modifications across the multiple files in this PR. Consider adding a meaningful PR description that explains the purpose, motivation, and scope of the namespace prefix feature. This helps reviewers understand the intent and provides context for the changes made across cmd/main.go, the core platform files, and the various resource controllers.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat: add possibility to prefix stack namespaces" is directly and comprehensively related to the changeset. The title accurately summarizes the primary change across all modified files, which collectively implement the ability to configure and use namespace prefixes via a new CLI flag, new functions, and updated resource handling. The title is concise, clear, and specific enough for a teammate to understand the main change at a glance.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch prefixed-namespace

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.

Copy link
Contributor

@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: 2

🧹 Nitpick comments (1)
internal/core/names.go (1)

26-33: LGTM! Consider adding prefix validation.

The function logic is correct and handles the empty prefix case properly. However, no validation ensures the prefix (or resulting namespace name) complies with Kubernetes naming constraints.

While Kubernetes will reject invalid names at the API level, consider adding validation here for better error messages. Kubernetes namespace names must:

  • Contain only lowercase alphanumeric characters or '-'
  • Start and end with an alphanumeric character
  • Be no more than 63 characters
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e610fb2 and 3900538.

⛔ Files ignored due to path filters (2)
  • helm/operator/templates/deployment.yaml is excluded by !**/*.yaml
  • helm/operator/values.yaml is excluded by !**/*.yaml
📒 Files selected for processing (10)
  • Makefile (1 hunks)
  • README.md (1 hunks)
  • cmd/main.go (3 hunks)
  • internal/core/names.go (1 hunks)
  • internal/core/platform.go (1 hunks)
  • internal/resources/benthos/controller.go (1 hunks)
  • internal/resources/ledgers/deployments.go (3 hunks)
  • internal/resources/payments/deployments.go (1 hunks)
  • internal/resources/resourcereferences/init.go (2 hunks)
  • internal/resources/stacks/init.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
internal/resources/resourcereferences/init.go (1)
internal/core/names.go (1)
  • GetNamespaceName (28-33)
internal/resources/ledgers/deployments.go (2)
internal/core/utils.go (1)
  • DeleteIfExists (141-151)
internal/core/names.go (1)
  • GetNamespacedResourceNameWithPrefix (36-41)
internal/resources/payments/deployments.go (2)
internal/core/utils.go (1)
  • DeleteIfExists (141-151)
internal/core/names.go (1)
  • GetNamespacedResourceNameWithPrefix (36-41)
internal/resources/stacks/init.go (2)
internal/core/names.go (1)
  • GetNamespaceName (28-33)
internal/core/utils.go (1)
  • CreateOrUpdate (123-139)
internal/core/names.go (1)
internal/core/platform.go (1)
  • Platform (3-15)
internal/resources/benthos/controller.go (1)
internal/core/names.go (1)
  • GetNamespaceName (28-33)
🔇 Additional comments (14)
internal/core/platform.go (1)

13-14: LGTM!

The NamespacePrefix field addition is clean and well-documented.

internal/core/names.go (1)

35-41: LGTM!

The function correctly delegates namespace computation to GetNamespaceName and constructs the NamespacedName properly.

internal/resources/stacks/init.go (1)

205-210: LGTM!

The namespace resolution correctly uses the platform-aware GetNamespaceName helper, ensuring that namespaces are created with the configured prefix.

internal/resources/payments/deployments.go (1)

167-188: LGTM!

The uninstall logic correctly uses GetNamespacedResourceNameWithPrefix to ensure resources are deleted from the prefixed namespace. Both Deployment and Service cleanup are handled consistently.

Makefile (1)

88-89: LGTM!

The build target correctly references the relocated entry point at cmd/main.go. This follows standard Go project structure conventions.

internal/resources/benthos/controller.go (1)

209-221: LGTM!

The namespace resolution for the audit ConfigMap deletion correctly uses GetNamespaceName to ensure the resource is deleted from the prefixed namespace when audit is disabled.

internal/resources/resourcereferences/init.go (1)

112-115: LGTM!

The namespace resolution correctly uses GetNamespaceName when retrieving the old resource for cleanup.

cmd/main.go (3)

70-70: LGTM!

The variable declaration follows the established pattern and naming conventions.


81-81: LGTM!

The flag definition is clear and provides helpful format guidance. The empty default ensures backward compatibility.


123-129: LGTM!

The Platform struct initialization correctly includes the new NamespacePrefix field alongside existing configuration. The implementation is clean and consistent.

internal/resources/ledgers/deployments.go (4)

69-69: LGTM!

The update to use GetNamespacedResourceNameWithPrefix correctly incorporates platform-aware namespace resolution for deployment cleanup during strategy changes.


387-396: LGTM!

The remove helper function correctly applies platform-aware namespace resolution to both deployment and service cleanup operations. The changes are consistent and properly structured.


406-408: LGTM!

The ledger-gateway deployment deletion correctly uses the platform-aware namespace resolution, maintaining consistency with the other cleanup operations in this function.


69-69: Verify that tests remain compatible with platform-aware namespace resolution in production code.

The changes in internal/resources/ledgers/deployments.go correctly and consistently apply GetNamespacedResourceNameWithPrefix. However, test files (ledger_controller_test.go, benthos_controller_test.go, auth_scopes_settings_test.go, benthosstream_controller_test.go) still use the older GetNamespacedResourceName pattern without platform context. Confirm that:

  1. Tests still pass with the production code changes
  2. Test file updates are either planned separately or intentionally use the old pattern for the test environment

Comment on lines +150 to 151
newResource.SetNamespace(core.GetNamespaceName(ctx.GetPlatform(), stack.Name))
newResource.SetName(req.Spec.Name)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify all namespace usages are updated.

The namespace resolution correctly uses GetNamespaceName when creating the new resource. However, we should verify that all locations in the codebase that use stack.Name for namespace resolution have been updated to use the platform-aware helper.

Run the following script to find potential locations where stack.Name might still be used for namespace resolution without the prefix:


🏁 Script executed:

#!/bin/bash
# Search for patterns where stack.Name might be used as a namespace
# Focus on SetNamespace, Namespace: stack.Name, and types.NamespacedName patterns

echo "=== Checking SetNamespace calls ==="
rg -n 'SetNamespace\(\s*stack\.Name\s*\)' --type go

echo "=== Checking Namespace field assignments ==="
rg -n 'Namespace:\s*stack\.Name' --type go

echo "=== Checking types.NamespacedName with stack.Name ==="
rg -n 'types\.NamespacedName\s*{[^}]*Namespace:\s*stack\.Name' --type go

echo "=== Checking direct stack.Name usage in namespace contexts ==="
# Look for GetClient().Get/Create/Update with stack.Name
rg -nC3 '(Get|Create|Update|Delete|List)\(ctx,.*stack\.Name' --type go | grep -v GetNamespaceName

Length of output: 1383



---

🏁 Script executed:

```shell
#!/bin/bash
# Find GetNamespaceName definition and understand the pattern
echo "=== GetNamespaceName definition ==="
rg -nA5 'func GetNamespaceName' --type go

echo ""
echo "=== Count of GetNamespaceName usages ==="
rg -n 'GetNamespaceName\(' --type go | wc -l

echo ""
echo "=== Sample usages of GetNamespaceName ==="
rg -nB2 'GetNamespaceName\(' --type go | head -30

Length of output: 2179


🏁 Script executed:

#!/bin/bash
# Check a few production code locations to understand context
echo "=== Context for ingress.go:129 ==="
rg -nB10 -A5 'Namespace: stack.Name' internal/resources/gateways/ingress.go | head -20

echo ""
echo "=== Context for authclients/init.go:54 ==="
rg -nB10 -A5 'Namespace: stack.Name' internal/resources/authclients/init.go | head -20

Length of output: 1000


Update namespace usage across multiple files to use GetNamespaceName helper consistently.

The reviewed file correctly uses GetNamespaceName, but verification found 5+ production code locations still using stack.Name directly for namespace resolution without the platform-aware prefix transformation:

  • internal/resources/gateways/ingress.go:129
  • internal/resources/gateways/configuration.go:19
  • internal/resources/caddy/caddy.go:153
  • internal/resources/auths/configuration.go:42
  • internal/resources/authclients/init.go:54
  • internal/resources/ledgers/init.go:115 (via client.InNamespace(stack.Name))

These must be updated to use core.GetNamespaceName(ctx.GetPlatform(), stack.Name) to ensure namespace prefix configuration is applied consistently across all resource creation/lookup operations.

🤖 Prompt for AI Agents
In internal/resources/gateways/ingress.go around line 129,
internal/resources/gateways/configuration.go around line 19,
internal/resources/caddy/caddy.go around line 153,
internal/resources/auths/configuration.go around line 42,
internal/resources/authclients/init.go around line 54, and
internal/resources/ledgers/init.go around line 115, update any direct use of
stack.Name for namespace resolution to call
core.GetNamespaceName(ctx.GetPlatform(), stack.Name) instead; replace
occurrences used for resource creation, lookups, and client.InNamespace(...) so
the platform-aware namespace prefix is applied consistently.

Comment on lines +132 to +149
## Namespace Prefix Configuration

The operator creates namespaces for each stack with the format `<organisationID>-<stackID>`. You can configure a prefix to be added to all namespace names by using the `--namespace-prefix` command line flag.

**Example:**
- Without prefix: `myorg-mystack`
- With prefix `dev-`: `dev-myorg-mystack`

**Command line usage:**
```sh
make run -- --namespace-prefix=dev-
```

**Helm chart usage:**
```yaml
operator:
namespacePrefix: "dev-"
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Add migration guidance for existing deployments.

The documentation doesn't address what happens to existing stacks when the namespace prefix is added or changed. When the prefix is enabled on an existing operator deployment, new namespaces will be created rather than renaming existing ones, potentially leaving orphaned resources in the old namespaces.

Consider adding a warning and migration instructions for existing deployments.

Additionally, the documentation states the format is <organisationID>-<stackID>, but the code uses stackName directly. Can you clarify the relationship between these concepts? If stackName already includes the organization ID, the documentation should reflect this.


I'll verify the review comment by examining the codebase for the namespace prefix implementation and how it handles existing deployments.

I'll verify the review comment by examining the codebase for the namespace prefix implementation and how it handles existing deployments.


🏁 Script executed:

#!/bin/bash
# Search for namespace prefix implementation in the codebase
echo "=== Searching for namespace prefix logic ==="
rg -i "namespace.*prefix" -A 5 -B 5 --type=go --type=yaml --type=ts --type=js

echo ""
echo "=== Searching for namespace creation logic ==="
rg -nP '\bnamespace\b.*creation|createNamespace|namespace.*format' -A 3 -B 3 --type=go --type=yaml

echo ""
echo "=== Searching for stackName usage ==="
rg -nP '\bstackName\b' -A 2 -B 2 --type=go --type=ts

echo ""
echo "=== Searching for organisationID references ==="
rg -nP '\borganis.*ID|organisationID' -A 2 -B 2 --type=go --type=yaml

echo ""
echo "=== Checking for migration or upgrade documentation ==="
find . -name "*.md" -type f | head -20 | xargs grep -l -i "migrat\|upgrad\|breaking\|orphan" 2>/dev/null | head -10

Length of output: 21345


🏁 Script executed:

#!/bin/bash
# Search for namespace prefix implementation in the codebase
echo "=== Searching for namespace prefix logic ==="
rg -i "namespace.*prefix" -A 5 -B 5 --type=go --type=yaml --type=ts --type=js

echo ""
echo "=== Searching for namespace creation logic ==="
rg -nP '\bnamespace\b.*creation|createNamespace|namespace.*format' -A 3 -B 3 --type=go --type=yaml

echo ""
echo "=== Searching for stackName usage ==="
rg -nP '\bstackName\b' -A 2 -B 2 --type=go --type=ts

echo ""
echo "=== Searching for organisationID references ==="
rg -nP '\borganis.*ID|organisationID' -A 2 -B 2 --type=go --type=yaml

echo ""
echo "=== Checking for migration or upgrade documentation ==="
find . -name "*.md" -type f | head -20 | xargs grep -l -i "migrat\|upgrad\|breaking\|orphan" 2>/dev/null | head -10

Length of output: 21345


🏁 Script executed:

#!/bin/bash
# Search for namespace deletion/cleanup logic when prefix changes
echo "=== Searching for namespace cleanup or deletion logic ==="
rg -nP 'DeleteNamespace|delete.*namespace|cleanup' -A 3 -B 3 --type=go

echo ""
echo "=== Check README.md around lines 132-149 ==="
sed -n '120,160p' README.md

Length of output: 1508


Clarify namespace format documentation and add migration guidance for prefix changes.

The codebase confirms both concerns:

  1. Migration guidance is missing: When the namespace prefix is added or changed on an existing deployment, the operator will create new namespaces for stacks (e.g., dev-myorg-mystack) while leaving the original namespaces (e.g., myorg-mystack) orphaned and unmanaged. There is no cleanup or migration logic to handle this scenario.

  2. Documentation format is misleading: The documentation states the format is <organisationID>-<stackID> as separate components, but the code implementation (in internal/core/names.go) treats stackName as an atomic value that already contains the full identifier. The format description should clarify that stackName is already in the form organisation-stack.

Update README to:

  • Warn that enabling or changing the prefix on existing deployments will create new namespaces, leaving old resources orphaned
  • Provide migration steps for existing deployments (e.g., instructions to manually migrate resources or guidelines on coordinating the upgrade)
  • Clarify that the namespace format is <prefix><stackName> where stackName includes both organization and stack identifiers
🤖 Prompt for AI Agents
In README.md around lines 132 to 149, update the Namespace Prefix Configuration
section to (1) warn that enabling or changing --namespace-prefix (or
operator.namespacePrefix) on an existing deployment will cause the operator to
create new namespaces like <prefix><stackName> and leave previous namespaces
orphaned, (2) add concise migration guidance: recommended upgrade order, example
manual migration steps (move/replicate resources, update CRs, rebind services)
and a note to coordinate downtime/backups, and (3) clarify the namespace format
wording to state explicitly that the operator builds namespaces as
<prefix><stackName> where stackName is an atomic value that already contains
organisation and stack identifiers (e.g., stackName="myorg-mystack" → namespace
"dev-myorg-mystack"); keep examples for CLI and Helm usage and a short reminder
to plan cleanup of old namespaces.

flag.StringVar(&env, "env", "staging", "The current environment in use for the operator")
flag.StringVar(&licenceSecret, "licence-secret", "", "The licence secret that contains the token and the issuer")
flag.StringVar(&utilsVersion, "utils-version", "latest", "The version of the operator utils image")
flag.StringVar(&namespacePrefix, "namespace-prefix", "", "The prefix to use when creating namespaces (format: <prefix><organisationID>-<stackID>)")
Copy link
Member

Choose a reason for hiding this comment

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

Use CRD Settings instead of Flag on Operator

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.

3 participants