Azure / Azure/unbounded

operator: unify namespace ownership for orca/inventory/machine-ops (follow-up to #529)

Open
#531 0 comments 0 reactions 0 assignees View on GitHub
enhancement go
Dominant language
Go
Stars
28
Forks
11
Avg merge
1d 8h
Merged PRs (30d)
55

Description

### Summary

PR #530 (closing #529) made the unbounded-operator the sole runtime owner of the shared `unbounded-system` Namespace for the operator-managed components (gantry, machina, metalman, net, storage): those components skip `Namespace` objects during reconcile, and every operator-managed template ships the identical canonical label set (`unbounded.SystemNamespaceLabels()`), enforced by the drift guard.

Three deploy flows that also default into `unbounded-system` were deliberately left out of scope (see #529 "Out of scope" and the `operatorManaged: false` rows in `internal/unbounded/namespace_drift_test.go`): **orca**, **inventory**, and **machine-ops**. They are not part of the operator's component registry, so the operator never reconciles them. This issue tracks bringing them under the same single-owner / unified-label posture.

### Current behavior / evidence

All three render a `Namespace` whose name defaults to `unbounded-system`, but with labels that diverge from the canonical set the operator now maintains:

| Component | Template | `app.kubernetes.io/name` |
|---|---|---|
| orca | `deploy/orca/01-namespace.yaml.tmpl` | `orca` |
| inventory | `deploy/inventory/common/01-namespace.yaml.tmpl` | *(none)* |
| machine-ops | `deploy/machine-ops/00-namespace.yaml.tmpl` | *(none)* |

The drift guard currently name-checks these (asserts the default namespace name) but does not assert their labels, because they are not operator-managed.

### Impact

- **Not churn today, but a latent divergence.** The operator's `BootstrapMaintainer` reasserts `SystemNamespaceLabels()` (including `app.kubernetes.io/name: unbounded-cloud`) every interval with `ForceOwnership`. If any of these flows is applied into the same cluster/namespace as the operator, the operator will (correctly) flip `app.kubernetes.io/name` away from `orca`/absent to `unbounded-cloud`.
- **Potential tug-of-war under GitOps.** A one-time `kubectl apply` is harmless (the operator wins on the next tick and it stays). But if orca/inventory/machine-ops are reconciled by a tool that periodically re-applies their Namespace under a stable field manager, the shared `app.kubernetes.io/name` key would ping-pong between that manager and `unbounded-operator` - the same class of problem #529 fixed for the operator-managed set.
- The single-identity goal for `unbounded-system` is only partially realized while these templates carry divergent/absent identity labels.

### Open question

Confirm the intended topology: are orca / inventory / machine-ops ever deployed into the same `unbounded-system` namespace as the operator, or are they control-plane-side / standalone flows that never co-reside with it? The chosen direction below depends on this.

### Proposed direction (pick per component)

1. **If a component should be operator-owned at runtime:** add it to the operator's managed set (or at least route its Namespace through the operator), and rely on the existing central `Namespace` skip.
2. **If a component stays standalone but shares `unbounded-system`:** unify its template's Namespace to the identical `SystemNamespaceLabels()` (canonical name + managed-by + PSA), and flip its row to `operatorManaged: true` in `namespace_drift_test.go` so the drift guard enforces parity. This matches the direct-apply parity contract PR #530 established for the operator-managed components.
3. **If a component must not share `unbounded-system`:** give it its own namespace default (like `deploy/playpen` uses `playpen`) so it never contends for the shared object.

### Acceptance criteria

- [ ] Decision recorded for each of orca, inventory, machine-ops (own the namespace, unify labels, or separate namespace).
- [ ] No divergent/absent identity labels remain on any template that defaults into `unbounded-system`.
- [ ] `namespace_drift_test.go` asserts labels (not just name) for every template that shares `unbounded-system`.
- [ ] `make fmt`, `make lint`, `go test ./internal/operator/... ./internal/unbounded/...` pass.

### References

- #529 / PR #530 - operator now owns `unbounded-system` for the operator-managed components; these three were explicitly out of scope.
- Canonical label source of truth: `internal/unbounded/unbounded.go` (`SystemNamespaceLabels`).
- Drift guard: `internal/unbounded/namespace_drift_test.go` (`operatorManaged` flag).

Contributor guide

Open the contributing guide

Research direction

Start by reviewing #529 and PR #530, then inspect deploy/orca/01-namespace.yaml.tmpl, deploy/inventory/common/01-namespace.yaml.tmpl, deploy/machine-ops/00-namespace.yaml.tmpl, internal/unbounded/unbounded.go, and internal/unbounded/namespace_drift_test.go. Record the namespace decision for each component, update the affected templates and drift assertions, and run make fmt, make lint, and the specified Go tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes
Domain
devops, infrastructure, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.