From ee36e479be4247de619a594e9d5d195ab299b745 Mon Sep 17 00:00:00 2001 From: stxkxs Date: Mon, 15 Jun 2026 18:22:39 -0700 Subject: [PATCH] platform: read ownership labels under agents.nanohype.dev/* with legacy fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The eks-agent-platform operator migrated its k8s labels from eks-agent-platform/* to the resource-tagging standard's agents.nanohype.dev/* prefix. The platform audit reads those ownership labels off each tenant namespace (platform / tenant / persona) to flag conformance gaps — so it now reads the canonical agents.nanohype.dev/* keys, falling back to the legacy eks-agent-platform/* keys so the audit is correct against both a migrated and a not-yet-migrated cluster. The check is now an ordered slice (deterministic finding output) keyed on the canonical label; the remediation text points at agents.nanohype.dev. Adds a test asserting a namespace carrying only the legacy labels stays conformant. Verified: task build + go vet + gofmt clean; go test ./internal/platform green; internal/platform coverage 83.2% (floor 80%). --- internal/platform/audit.go | 33 ++++++++++++++++++++++++++------- internal/platform/audit_test.go | 18 ++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/internal/platform/audit.go b/internal/platform/audit.go index ff69ff8..4719a57 100644 --- a/internal/platform/audit.go +++ b/internal/platform/audit.go @@ -30,9 +30,17 @@ var ( ) const ( - platformLabel = "eks-agent-platform/platform" - tenantLabel = "eks-agent-platform/tenant" - personaLabel = "eks-agent-platform/persona" + // Canonical ownership labels (resource-tagging standard). The operator + // stamps these on each tenant namespace; the audit accepts the legacy + // eks-agent-platform/* keys below as a fallback for a not-yet-migrated cluster. + platformLabel = "agents.nanohype.dev/platform" + tenantLabel = "agents.nanohype.dev/tenant" + personaLabel = "agents.nanohype.dev/persona" + + legacyPlatformLabel = "eks-agent-platform/platform" + legacyTenantLabel = "eks-agent-platform/tenant" + legacyPersonaLabel = "eks-agent-platform/persona" + pssEnforce = "pod-security.kubernetes.io/enforce" irsaAnnotation = "eks.amazonaws.com/role-arn" @@ -112,11 +120,22 @@ func auditPlatform(ctx context.Context, typed kubernetes.Interface, dyn dynamic. fmt.Sprintf("namespace %s is %q, want restricted", pssEnforce, orUnset(nsObj.Labels[pssEnforce])), "Restore the restricted Pod Security Standards label on the tenant namespace.")) } - for key, want := range map[string]string{platformLabel: name, tenantLabel: tenant, personaLabel: persona} { - if nsObj.Labels[key] != want { + // Read the canonical label, falling back to the legacy eks-agent-platform/* + // key so the audit is correct against both a migrated and a not-yet-migrated + // cluster. Ordered (not a map) for deterministic finding output. + for _, c := range []struct{ key, legacy, want string }{ + {platformLabel, legacyPlatformLabel, name}, + {tenantLabel, legacyTenantLabel, tenant}, + {personaLabel, legacyPersonaLabel, persona}, + } { + got := nsObj.Labels[c.key] + if got == "" { + got = nsObj.Labels[c.legacy] + } + if got != c.want { out = append(out, f(cloud.SeverityLow, cloud.PlatformLabelMissing, ns, - fmt.Sprintf("namespace label %s is %q, want %q", key, orUnset(nsObj.Labels[key]), want), - "Restore the eks-agent-platform ownership labels (drive cost attribution and network selection).")) + fmt.Sprintf("namespace label %s is %q, want %q", c.key, orUnset(got), c.want), + "Restore the agents.nanohype.dev ownership labels (drive cost attribution and network selection).")) } } diff --git a/internal/platform/audit_test.go b/internal/platform/audit_test.go index c16db4d..68d7ecf 100644 --- a/internal/platform/audit_test.go +++ b/internal/platform/audit_test.go @@ -142,6 +142,24 @@ func TestAudit_Conformant(t *testing.T) { } } +func TestAudit_AcceptsLegacyLabels(t *testing.T) { + // A not-yet-migrated cluster still carries the legacy eks-agent-platform/* + // ownership labels; the audit must accept them via fallback (no + // PlatformLabelMissing finding) and stay otherwise conformant. + objs := conformantObjects() + objs[0] = &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: tNS, Labels: map[string]string{ + pssEnforce: "restricted", legacyPlatformLabel: tName, legacyTenantLabel: tTen, legacyPersonaLabel: tPers, + }}} + typed := kubefake.NewSimpleClientset(objs...) + findings, err := Audit(context.Background(), typed, conformantDyn(), conformantRole()) + if err != nil { + t.Fatal(err) + } + if len(findings) != 0 { + t.Fatalf("legacy labels should be accepted, got %d findings: %+v", len(findings), findings) + } +} + func TestAudit_DriftDetected(t *testing.T) { // Namespace exists but PSS is wrong; NetworkPolicy and ServiceAccount absent. typed := kubefake.NewSimpleClientset(