[Feature] Tenant namespace management module - #255
Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: VimukthiPerera <15902071+VimukthiPerera@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ole binding for_each
Convert the dc-controlplane RKE2 cluster to a 3-node HA layout with
kube-vip serving the apiserver VIP, and bring the cloud-ui Deployment
+ Service + Ingress into the dc-controlplane-services module so a
cluster rebuild restores routing without waiting for the cloud-ui CI
workflow.
Storage:
* Create a single-replica, dataLocality=best-effort Longhorn
StorageClass on the Harvester host cluster for control-plane VM
root disks. Drops etcd fsync latency 5-10x vs the default 2-replica
SC; best-effort lets Longhorn migrate the volume on host failure
so the VM can restart elsewhere.
* Bake a VirtualMachineImage on the local SC because Harvester's VM
provisioner ignores HarvesterConfig.disk_info.storageClassName --
cloned PVCs inherit the source image's SC, so the image itself
has to be on the local SC for the VM disks to land there.
CodeRabbit findings addressed in the same change:
* Wrap dc-api self-signed cert dns_names in distinct(compact(...))
and add an opt-in auto_include_cloudui_in_tls_sans variable for
consumers who want one-knob TLS coverage of the cloud-ui hostname.
* Refresh cloudui_hostname description to reflect that the module
now creates the Deployment + Service when cloudui_image is set.
* harvester_image.dcapi_node now uses local.vm_storage_class_name so
vm_storage_class_override is honored when the operator sets it.
* Update strict-local wording to best-effort everywhere it appears
in storage-class descriptions and comments.
* Add a check{} block asserting length(node_ips) == node_count.
Uses check{} rather than validation{} because cross-variable refs
in validation blocks need Terraform 1.9+ and required_version is
>= 1.7.
* Apply trimspace() to user_data + storage_class_name override
checks in workloads/k8s-cluster so whitespace-only inputs fall
through to defaults instead of masking as real overrides.
Four fixes from automated review: * dc-controlplane-services: cloud-ui probe path is now configurable via cloudui_health_path. Default stays /healthz because the wso2 cloud-ui image's nginx.conf serves it; consumers that ship a stock nginx-unprivileged image (no /healthz) override to /. * dc-controlplane-services: stale comment above the cloud-ui Ingress said the Deployment + Service were applied by a workflow. The module owns both now — comment rewritten to reflect that. * dc-controlplane-services: cloudui_service_port and cloudui_replicas now have validation blocks. Non-positive or non-integer inputs fail at plan time instead of producing broken kube objects. * dc-controlplane: vm_storage_class_override is trimspace'd before the empty-string check so a whitespace-only override no longer wins precedence and propagates an invalid storage class name.
Add structured issue forms under .github/ISSUE_TEMPLATE so issues are filed with consistent, triage-ready fields: - 01-bug: area, description, repro steps, severity, version - 02-improvement: area, current limitation, suggested improvement - 03-task: area, description, related issues - 04-epic: description, goals, child checklist, design doc - config.yml: route security reports to a private advisory The forms are adapted from the consumer project's templates and genericized for this public repository: the internal project-board reference and internal environment names were removed, and the area options now list this repository's own components (dc-api, cloud-ui, dcctl, Terraform, operators, docs). The consumer-only change-request template is intentionally omitted. Each form auto-applies its Type/* label. The broader label taxonomy is managed in repository settings, not in this change. Closes wso2#127 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Repurpose the deprecated main branch as the repository's front door.
GitHub renders this branch's README first, so it now opens with a
branch-navigation map and the OCD roadmap instead of Terraform module
usage (which belongs on the terraform branch).
- ASCII diagram + table mapping the terraform, controlplane, and
operators branches to the stack and roadmap phases.
- Full roadmap: Phase 1 (Platform Foundation) and Phase 2 (Cloud
Control Plane, M1-M5), pointing to MILESTONES.md for detail.
main carries no code; the previous Terraform-flavored README content
remains available on the terraform branch.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add short dcctl and cloud-ui VNet-creation clips to the entry-point README, laid out side by side so the two demos stay compact. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The repository PR template was the generic WSO2-product template (Certification, Marketing, Training, FindSecurityBugs, a JDK/DB/browser test matrix, ...). Almost none of it applies to this repo's products — the Go control plane, the Terraform module catalog, or the operators — so contributors faced a wall of N/A fields just to open a PR. Replace it with a short template: Summary, Changes, Testing, and a checklist (tests/validation pass, docs updated, no committed secrets, no internal/other-repo names). GitHub serves the PR template only from the default branch, so this single file governs PRs against every branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CodeRabbit reads its configuration only from the repository's default branch, so base_branches must be set here on main. Without it, CodeRabbit uses dashboard defaults and reviews only the default branch, skipping pull requests targeting the long-lived controlplane, terraform, operators, and terraform-provider-dcapi branches. Add a single .coderabbit.yaml on main that opts those branches into auto-review via reviews.auto_review.base_branches, with anchored regexes so each matches exactly. The default branch stays covered automatically. This supersedes the per-branch .coderabbit.yaml files added earlier; they live on non-default branches and are therefore never read. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…project quota limits
📝 WalkthroughWalkthroughThis change adds a Terraform module that creates Rancher namespaces from normalized inputs. It supports shared metadata, cluster waiting, optional container limits, optional resource quotas, and outputs for namespace resources and IDs. ChangesTenant namespace management
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@modules/management/tenant-namespace/main.tf`:
- Around line 30-31: Update the labels configuration in the tenant namespace
resource to merge var.labels first, then set the required
"field.cattle.io/projectId" label from var.project_id so caller-provided labels
cannot override it; leave annotations unchanged.
In `@modules/management/tenant-namespace/variables.tf`:
- Around line 6-15: Replace the names-only namespaces input with per-namespace
quota configuration, and add a project-level quota input. Derive each
namespace’s quota from its explicit values or the remaining project quota when
unspecified, then validate the aggregate explicit and calculated quotas do not
exceed the project quota before creating rancher2_namespace.this resources.
Update the resource_quota usage in main.tf so each namespace receives only its
calculated quota rather than one shared object.
🪄 Autofix
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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 6bb304bf-b06e-4214-a49f-88e7279364b9
📒 Files selected for processing (4)
modules/management/tenant-namespace/main.tfmodules/management/tenant-namespace/outputs.tfmodules/management/tenant-namespace/variables.tfmodules/management/tenant-namespace/versions.tf
|
Implementing asymmetric resource and container limits within a single module execution specifically, adding local math to sum explicit limits, subtract them from the project total, and auto-split the remainder. significantly increases the complexity of our Terraform logic. It makes the module harder to read, maintain, and troubleshoot if validation errors occur. Instead of building this complex logic into a single "one-size-fits-all" module, we should create a custom module dedicated exclusively to creating namespaces under a project. How the New Design WorksKeep it Simple and Uniform: The custom module will be designed to create multiple namespaces, but it will apply the same resource and container limits to every namespace defined within that specific module block. Handling Different Quotas:
Example UsageUnder this design, users achieve asymmetric quotas by composing multiple simple blocks rather than writing one complex block: # Section 1: Standard namespaces with uniform limits
module "standard_namespaces" {
source = "./modules/rancher-namespace"
project_id = var.project_id
namespaces = ["backend", "frontend"]
cpu_limit = "2"
memory_limit = "4Gi"
}
# Section 2: A specialized namespace with custom limits
module "data_namespace" {
source = "./modules/rancher-namespace"
project_id = var.project_id
namespaces = ["database"]
cpu_limit = "8" # Higher custom limit
memory_limit = "16Gi" # Higher custom limit
}
|
add: proper description explaining the module fix: change to local variables Update the label format to display namespace quota information correctly Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> fix: add spacing
33997cf to
a3cc3fc
Compare
|
Just noticed, this is pointing at the wrong branch (main), because all the Terraform code go into the |
|
Noted ! |
Summary
This PR introduces the
management/tenant-namespaceTerraform module, providing a standardized, reusable way to provision and manage Kubernetes namespaces within a Rancher v2 project.Previously, namespace creation lacked a unified approach for enforcing tenant guardrails. This module solves that by bundling namespace creation with strict governance controls, allowing administrators to seamlessly apply container resource limits and project-level resource quotas across multiple namespaces at once.
Closes #243
Changes
New Features:
for_eachloop to dynamically provision multiple namespaces simultaneously based on a provided list.resource_quotato enforce limits on Pods, ConfigMaps, Persistent Volume Claims, Services, and Storage.container_resource_limitto set default CPU and memory requests/limits for deployments within the namespace.labelsandannotationsfor organizational tagging.Refactors & Improvements:
local.namespacesto safely handle null inputs and convert the namespace listtoset()for thefor_eachloop.rancher2provider and an existingproject_id).Testing
terraform fmtandterraform validateto ensure syntax and module structure are correct.terraform planusing a test configuration passing multiple namespace names, a custom resource quota, and container limits. Verified the plan output correctly mapped all nested dynamic blocks.kubectlthat:Checklist
Summary by CodeRabbit