Skip to content

Support multiple VLAN networks per tenant space#68

Merged
HiranAdikari merged 2 commits intowso2:mainfrom
HiranAdikari:feature/67-multi-vlan-tenant-networks
Apr 21, 2026
Merged

Support multiple VLAN networks per tenant space#68
HiranAdikari merged 2 commits intowso2:mainfrom
HiranAdikari:feature/67-multi-vlan-tenant-networks

Conversation

@HiranAdikari
Copy link
Copy Markdown
Contributor

Summary

  • vlan_id changed from number to list(number) — each entry provisions a separate harvester_network via for_each, so networks can be added or removed independently without replacing others
  • Auto-route path (no vyos_endpoint) now supports multiple VLANs; VyOS path still requires exactly one VLAN (enforced by a precondition)
  • network_namespace_name override allows brownfield callers to import an existing namespace whose name differs from the <project>-net default
  • vlan_network_names map override allows brownfield callers to import existing harvester_network resources with non-default names
  • network_name output replaced by network_names map keyed by VLAN ID string

Test plan

  • Plan with vlan_id = [1000] and vyos_endpoint set — confirms VyOS path still works, single VLAN, manual route
  • Plan with vlan_id = [608, 609] and no vyos_endpoint — confirms multi-VLAN auto-route, two harvester_network resources created
  • Plan with vlan_id = [1000, 1001] and vyos_endpoint set — VyOS precondition fires with clear error
  • Import brownfield with network_namespace_name and vlan_network_names overrides — no diff after import
  • Plan with vlan_id = null — no network resources created, network_names output is empty map

Closes #67

🤖 Generated with Claude Code

- vlan_id is now list(number); each entry creates a harvester_network
  via for_each so networks can be added/removed independently
- Auto-route path (no vyos_endpoint) supports multiple VLANs; VyOS
  path still requires exactly one VLAN (precondition enforced)
- network_namespace_name override lets callers import brownfield
  namespaces whose names differ from the <project>-net default
- vlan_network_names map override lets callers import brownfield
  harvester_network resources with non-default names
- network_name output replaced by network_names map keyed by VLAN ID

Closes wso2#67

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

Warning

Rate limit exceeded

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

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 46 minutes and 43 seconds.

⌛ 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1988216c-a080-4ba3-81cc-f1419b6cc54e

📥 Commits

Reviewing files that changed from the base of the PR and between 21ae842 and 431d087.

📒 Files selected for processing (1)
  • modules/management/tenant-space/variables.tf
📝 Walkthrough

Walkthrough

The tenant-space module now supports multiple VLANs per tenant by converting vlan_id from a scalar number to an array. Harvester networks are created via for_each, one per VLAN, while the single-VLAN VyOS provisioning path is preserved and enforced via a resource precondition. Network namespace and individual network names can be overridden for brownfield imports.

Changes

Cohort / File(s) Summary
Variable Declarations
variables.tf
Changed vlan_id type from number to list(number) with updated validation. Added network_namespace_name (string override) and vlan_network_names (map for per-VLAN name overrides) to support brownfield imports.
Resource Logic
main.tf
Refactored network namespace creation to depend on non-empty vlan_id array. Converted harvester_network from count to for_each iteration over VLAN IDs. Added rancher2_project precondition to enforce single-VLAN requirement for VyOS path, routing multi-VLAN cases to auto-route mode. Updated VyOS invocation to use var.vlan_id[0] and made route configuration conditional on local.use_vyos.
Output Exports
outputs.tf
Renamed network_name output to network_names and changed type from string to map(string), mapping VLAN IDs to Harvester network references in the form <namespace>/<name>.

Sequence Diagram

sequenceDiagram
    participant Input as vlan_id Input
    participant Validate as Validation
    participant Decision as Control Flow
    participant NS as Network Namespace
    participant Networks as Harvester Networks
    participant VyOS as VyOS Module

    Input->>Validate: Pass vlan_id (list or null)
    Validate->>Validate: Check non-empty list, VLAN range 1–4094
    Validate-->>Decision: Validation result
    
    Decision->>Decision: Determine use_vyos<br/>(single VLAN + auto-route disabled)
    
    alt use_vyos = true
        Decision->>Decision: Enforce precondition:<br/>length(vlan_id) == 1
        Decision-->>NS: ✓ Proceed
    else use_vyos = false
        Decision->>Decision: Multi-VLAN or auto-route enabled
        Decision-->>NS: vyos_endpoint = null
    end
    
    NS->>NS: Create network_namespace<br/>(with optional name override)
    NS->>Networks: Create harvester_network per VLAN
    
    loop For each VLAN ID
        Networks->>Networks: Set vlan_id from array element
        alt local.use_vyos = true
            Networks->>Networks: Configure route_cidr/route_gateway
        else
            Networks->>Networks: Set route_cidr/route_gateway = null<br/>(auto-route mode)
        end
    end
    
    alt local.use_vyos = true
        Networks->>VyOS: Invoke vyos_tenant module<br/>with vlan_id[0]
    else
        Networks-->>VyOS: (skipped)
    end
    
    Networks->>Networks: Export network_names map<br/>(VLAN ID → namespace/name)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description provides a clear summary of changes, technical details about the implementation, and a comprehensive test plan with five specific scenarios. However, it does not follow the repository's template structure (Purpose, Goals, Approach, User stories, Release note, Documentation, etc.). Restructure the description to match the repository template, including Purpose/Goals/Approach sections, or confirm if the custom format is acceptable for infrastructure changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely captures the primary change: enabling multiple VLAN networks per tenant space, which is the core feature introduced in this PR.
Linked Issues check ✅ Passed The changes fully implement the coding requirements from issue #67: vlan_id type changed from number to list(number), multi-VLAN support with for_each for harvester_network, VyOS precondition enforcement for single VLAN, network_namespace_name and vlan_network_names overrides for brownfield imports, and network_name output replaced with network_names map.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing multi-VLAN support in the tenant-space module as specified in issue #67. No unrelated modifications or feature creep detected in the three modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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.

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: 1

🧹 Nitpick comments (3)
modules/management/tenant-space/main.tf (1)

58-61: Precondition looks correct; consider echoing the VLAN count in the error for faster debugging.

Logic is sound: !local.use_vyos || length(var.vlan_id) == 1 cleanly rejects the VyOS + multi-VLAN combination. Minor ergonomic suggestion only — interpolating length(var.vlan_id) in the error message helps operators identify the offending configuration quickly.

Optional message tweak
-      error_message = "VyOS path requires exactly one VLAN ID. Set vyos_endpoint = null for multi-VLAN auto-route configurations."
+      error_message = "VyOS path requires exactly one VLAN ID (got ${var.vlan_id == null ? 0 : length(var.vlan_id)}). Set vyos_endpoint = null for multi-VLAN auto-route configurations."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/management/tenant-space/main.tf` around lines 58 - 61, Update the
precondition error message to include the actual VLAN count for easier
debugging: in the precondition block that checks "local.use_vyos" and
"length(var.vlan_id) == 1", change the error_message to interpolate
length(var.vlan_id) (e.g., include the value of length(var.vlan_id) in the
string) so the log shows the offending VLAN count when the condition fails.
modules/management/tenant-space/variables.tf (2)

112-123: Consider rejecting duplicate VLAN IDs in validation.

harvester_network.tenant uses toset([for id in var.vlan_id : tostring(id)]) in main.tf, which silently dedupes. If a caller accidentally passes [608, 608], Terraform will plan a single resource with no warning. A cheap validation here surfaces the mistake at plan time.

Proposed validation tweak
   validation {
     condition = var.vlan_id == null || (
       length(var.vlan_id) > 0 &&
+      length(var.vlan_id) == length(toset(var.vlan_id)) &&
       alltrue([for id in var.vlan_id : id >= 1 && id <= 4094])
     )
-    error_message = "vlan_id must be null or a non-empty list of valid 802.1Q VLAN IDs (1–4094)."
+    error_message = "vlan_id must be null or a non-empty list of unique 802.1Q VLAN IDs (1–4094)."
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/management/tenant-space/variables.tf` around lines 112 - 123, The
vlan_id variable validation should also reject duplicate IDs so callers get a
plan-time error instead of silent dedupe by harvester_network.tenant; update the
validation block for variable "vlan_id" to require that either var.vlan_id is
null or (length(var.vlan_id) > 0, all entries are in 1..4094, and
length(var.vlan_id) == length(distinct(var.vlan_id)) to ensure uniqueness), and
adjust the error_message to mention duplicates; this prevents inputs like
[608,608] from being silently collapsed by the toset/tostring logic in main.tf's
harvester_network.tenant.

125-135: Add name-format validation to the new override variables.

Both network_namespace_name and values of vlan_network_names become Kubernetes/Harvester resource names. Without validation, malformed values fail deep inside the provider with opaque errors. The namespaces variable already includes such validation; the same RFC 1123 DNS label constraints should apply here.

Validate network_namespace_name to allow null or a string matching the RFC 1123 pattern (lowercase alphanumeric and hyphens, 1–63 characters). Validate all values in vlan_network_names map against the same constraints.

As a forward-looking enhancement (blocked until Terraform 1.9 or later in this repo), consider asserting that every key in vlan_network_names corresponds to an entry in var.vlan_id via a precondition block on a resource. This prevents stale or misspelled overrides from silently no-op-ing via lookup(..., default).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/management/tenant-space/variables.tf` around lines 125 - 135, Add
RFC1123 name-format validation to the new override variables: for variable
"network_namespace_name" add a validation block that allows null or a string
matching the RFC1123 DNS label regex (lowercase alphanumeric and hyphen, 1–63
chars), and for variable "vlan_network_names" add a validation that iterates
over all map values and ensures each value matches the same RFC1123 regex;
reference the variable blocks named network_namespace_name and
vlan_network_names and use Terraform's validation.rule with regex(match) and a
clear error_message when the constraint fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@modules/management/tenant-space/main.tf`:
- Line 10: The current expression using coalesce for network_namespace
(network_namespace = local.create_net_ns ? coalesce(var.network_namespace_name,
"${var.project_name}-net") : null) will accept an empty string as a valid value;
update the logic to guard against empty strings by either adding RFC 1123 +
non-empty validation on var.network_namespace_name in variables.tf or change the
fallback to an explicit empty-string check (e.g., use var.network_namespace_name
!= "" ? var.network_namespace_name : "${var.project_name}-net") so that an empty
string does not become the namespace, keeping local.create_net_ns and
var.project_name references intact.

---

Nitpick comments:
In `@modules/management/tenant-space/main.tf`:
- Around line 58-61: Update the precondition error message to include the actual
VLAN count for easier debugging: in the precondition block that checks
"local.use_vyos" and "length(var.vlan_id) == 1", change the error_message to
interpolate length(var.vlan_id) (e.g., include the value of length(var.vlan_id)
in the string) so the log shows the offending VLAN count when the condition
fails.

In `@modules/management/tenant-space/variables.tf`:
- Around line 112-123: The vlan_id variable validation should also reject
duplicate IDs so callers get a plan-time error instead of silent dedupe by
harvester_network.tenant; update the validation block for variable "vlan_id" to
require that either var.vlan_id is null or (length(var.vlan_id) > 0, all entries
are in 1..4094, and length(var.vlan_id) == length(distinct(var.vlan_id)) to
ensure uniqueness), and adjust the error_message to mention duplicates; this
prevents inputs like [608,608] from being silently collapsed by the
toset/tostring logic in main.tf's harvester_network.tenant.
- Around line 125-135: Add RFC1123 name-format validation to the new override
variables: for variable "network_namespace_name" add a validation block that
allows null or a string matching the RFC1123 DNS label regex (lowercase
alphanumeric and hyphen, 1–63 chars), and for variable "vlan_network_names" add
a validation that iterates over all map values and ensures each value matches
the same RFC1123 regex; reference the variable blocks named
network_namespace_name and vlan_network_names and use Terraform's
validation.rule with regex(match) and a clear error_message when the constraint
fails.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 10f22417-872b-4bd7-88f2-61a851335b81

📥 Commits

Reviewing files that changed from the base of the PR and between 71d351d and 21ae842.

📒 Files selected for processing (3)
  • modules/management/tenant-space/main.tf
  • modules/management/tenant-space/outputs.tf
  • modules/management/tenant-space/variables.tf

Comment thread modules/management/tenant-space/main.tf
Guard against an empty string being passed as the network namespace
override — coalesce accepts "" as truthy so validation is the right
fix, consistent with other string variables in this module.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HiranAdikari HiranAdikari merged commit 9d502de into wso2:main Apr 21, 2026
3 of 4 checks passed
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.

Support multiple VLANs per tenant space with brownfield name overrides

2 participants