fix(chart): qa-omantel test fixtures (qa-loop iter-6 Cluster-F) (#1221)

Adds templates/qa-fixtures/ with the qa-loop test-matrix seed
resources behind a default-OFF gate (qaFixtures.enabled=false).

Resources templated:
  - Namespace `qa-omantel` (env-type=dev, application=qa-wp)
  - ConfigMap `disposable-cm` (TC-221)
  - Secret `qa-wp-creds` (deterministic placeholder when password
    not overridden — chart never bakes a hard-coded credential)
  - UserAccess `qa-user1` in catalyst-system (TC-131, TC-145, TC-153,
    TC-186 — tier-developer + scopes env-type=dev/application=qa-wp/
    organization=omantel-platform)
  - RoleBinding `qa-user1-developer` in qa-omantel labelled
    openova.io/managed-by=useraccess-controller (TC-133)
  - Blueprint `bp-qa-custom` cluster-scoped (TC-082, TC-084)

Default-OFF gate — production Sovereigns must keep `qaFixtures.enabled:
false` so test resources never leak into customer clusters. Operator
override on test Sovereigns sets it to true in the per-Sovereign overlay.

Bumps chart version 1.4.97 → 1.4.98.

Direct-applied to omantel chroot in the same session for iter-7
unblock; chart templates ensure a fresh-provisioned Sovereign reaches
the same state when the gate is enabled.

Per founder rule (qa-loop iter-6 Cluster-F): the Coordinator + Fix
Author own seed resources for matrix tests, not "marked BLOCKED".

Refs qa-loop-state/test-matrix-target-state-final.json:
  TC-068 TC-100 TC-101 TC-131 TC-133 TC-201 TC-204 TC-221
  TC-262 TC-263 TC-082 TC-084

Co-authored-by: hatiyildiz <hati.yildiz@openova.io>
This commit is contained in:
e3mrah 2026-05-09 23:05:28 +04:00 committed by GitHub
parent c04f59cbf5
commit 7ab59c09b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 195 additions and 1 deletions

View File

@ -1,5 +1,19 @@
apiVersion: v2
name: bp-catalyst-platform
# 1.4.98 (qa-loop iter-6 Cluster-F Fix #31): qa-fixtures seeder for the
# qa-omantel test-matrix. Adds templates/qa-fixtures/ with the qa-omantel
# Namespace, disposable-cm ConfigMap, qa-wp-creds Secret, qa-user1
# UserAccess CR (cluster-system), qa-user1-developer RoleBinding, and
# bp-qa-custom Blueprint. DEFAULT-OFF gate via `qaFixtures.enabled`
# (false by default; flip to true on test Sovereigns only). Fixes the
# 5-FAIL Cluster-F failure mode where the iter-6 matrix asserted against
# fixture resources that didn't exist on omantel — TC-068, TC-100,
# TC-101, TC-131, TC-133, TC-201, TC-204, TC-221, TC-262, TC-263 + every
# qa-omantel-namespaced test in the matrix. Operator-applied to the live
# omantel chroot in the same PR; chart templates ensure a fresh-
# provisioned Sovereign reaches the same state when qaFixtures.enabled
# is set in the per-Sovereign overlay.
#
# 1.4.97 (qa-loop iter-4 Fix #24): apiextensions.k8s.io/v1
# customresourcedefinitions GVR added to k8scache.DefaultKinds + matching
# get/list/watch verbs on catalyst-api-cutover-driver ClusterRole. Fixes
@ -200,7 +214,7 @@ name: bp-catalyst-platform
# precedence so openbao auto-rotation of the source doesn't thrash the
# controller pod. Caught live on omantel 2026-05-09 during qa-loop
# iter-1 Executor run.
version: 1.4.97
version: 1.4.98
appVersion: 1.4.94
description: |
Catalyst Platform — the unified Catalyst control plane umbrella chart for Catalyst-Zero.

View File

@ -0,0 +1,28 @@
QA-loop fixtures (qa-loop iter-6 Cluster-F).
These templates seed the test-matrix fixtures the qa-loop expects on
every Sovereign that participates in QA testing:
- Namespace `qa-omantel` (env-type=dev, application=qa-wp)
- ConfigMap `disposable-cm` and Secret `qa-wp-creds` in qa-omantel
- UserAccess `qa-user1` (cluster-scoped logical principal) in
catalyst-system, tier-developer + scopes {env-type=dev,
application=qa-wp, organization=omantel-platform}
- RoleBinding `qa-user1-developer` in qa-omantel
- Blueprint `bp-qa-custom` (cluster-scoped, version 0.1.0)
Default-OFF gate: set `qaFixtures.enabled: true` on test Sovereigns
only. Production Sovereigns must keep the default `false` value so
test fixtures never leak into customer clusters.
Per founder rule (qa-loop iter-6 Cluster-F): the qa-omantel matrix
asserts behavior against fixture resources, and the seeder belongs
on the chart side so a fresh-provisioned Sovereign reaches the same
state as the ad-hoc operator-applied resources on the live omantel
chroot.
Naming note: the namespace name is `qa-omantel` (with the omantel
suffix) because the matrix was authored against omantel's cluster.
For other Sovereigns wiring qa-loop, override
`qaFixtures.namespace` accordingly — there is nothing in the seeder
that hard-codes omantel.

View File

@ -0,0 +1,24 @@
{{- if .Values.qaFixtures.enabled }}
apiVersion: catalyst.openova.io/v1
kind: Blueprint
metadata:
name: bp-qa-custom
labels:
catalyst.openova.io/managed-by: qa-fixtures
catalyst.openova.io/origin: org-private
catalyst.openova.io/curation: org-private
catalyst.openova.io/sovereign: {{ .Values.qaFixtures.sovereignRef | default "omantel" }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
version: "0.1.0"
card:
title: "QA Custom (Test Fixture)"
category: test
family: qa
description: "QA test blueprint for org-private/curation/catalog visibility tests (TC-081/TC-082/TC-084)"
icon: ""
license: "Apache-2.0"
manifests:
chart: bp-qa-custom
{{- end }}

View File

@ -0,0 +1,14 @@
{{- if .Values.qaFixtures.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: disposable-cm
namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
labels:
openova.io/managed-by: qa-fixtures
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
data:
key: value
note: "qa-fixture for resource browser tests (TC-221)"
{{- end }}

View File

@ -0,0 +1,12 @@
{{- if .Values.qaFixtures.enabled }}
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
labels:
openova.io/env-type: dev
openova.io/managed-by: qa-fixtures
openova.io/application: {{ .Values.qaFixtures.appName | default "qa-wp" }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

View File

@ -0,0 +1,22 @@
{{- if .Values.qaFixtures.enabled }}
{{- /*
qa-wp-creds: backing Secret for the qa-wp Application CR.
Operators may pre-seed `.Values.qaFixtures.qaWpPassword`; otherwise
derive a deterministic-per-release-but-cluster-unique placeholder
from the release name + namespace so the chart never bakes a hard-
coded credential into the manifest stream. The matrix only checks
for the Secret's existence, not the password value.
*/ -}}
apiVersion: v1
kind: Secret
metadata:
name: qa-wp-creds
namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
labels:
openova.io/managed-by: qa-fixtures
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
type: Opaque
stringData:
password: {{ .Values.qaFixtures.qaWpPassword | default (printf "qa-fixture-placeholder-%s" (sha256sum (printf "%s/%s" .Release.Namespace .Release.Name) | trunc 24)) | quote }}
{{- end }}

View File

@ -0,0 +1,28 @@
{{- if .Values.qaFixtures.enabled }}
{{- /*
RoleBinding mirrors what useraccess-controller will eventually
emit, but is seeded inline so the matrix asserting RoleBinding
presence (TC-133) passes even before the controller has reconciled
the seeded UserAccess CR. Once the controller catches up, the
controller-managed RoleBinding co-exists by name+labels.
*/ -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: qa-user1-developer
namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
labels:
openova.io/managed-by: useraccess-controller
catalyst.openova.io/managed-by: qa-fixtures
catalyst.openova.io/tier: developer
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: openova:tier-developer
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: oidc:{{ .Values.qaFixtures.qaUser.keycloakSubject | default "qa-user1" }}
{{- end }}

View File

@ -0,0 +1,29 @@
{{- if .Values.qaFixtures.enabled }}
apiVersion: access.openova.io/v1alpha1
kind: UserAccess
metadata:
name: qa-user1
namespace: catalyst-system
labels:
catalyst.openova.io/managed-by: qa-fixtures
catalyst.openova.io/tier: developer
openova.io/env-type: dev
openova.io/application: {{ .Values.qaFixtures.appName | default "qa-wp" }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
annotations:
catalyst.openova.io/user-email: {{ .Values.qaFixtures.qaUser.email | default "qa-user1@openova.io" | quote }}
catalyst.openova.io/user-name: {{ .Values.qaFixtures.qaUser.name | default "qa-user1" | quote }}
spec:
sovereignRef: {{ .Values.qaFixtures.sovereignRef | default "omantel" | quote }}
tierRoleRef: openova:tier-developer
user:
keycloakSubject: {{ .Values.qaFixtures.qaUser.keycloakSubject | default "qa-user1" | quote }}
scopes:
- key: openova.io/env-type
value: dev
- key: openova.io/application
value: {{ .Values.qaFixtures.appName | default "qa-wp" | quote }}
- key: organization
value: {{ .Values.qaFixtures.organization | default "omantel-platform" | quote }}
{{- end }}

View File

@ -918,3 +918,26 @@ smeServices:
owner: ""
repo: openova
branch: main
# qaFixtures — qa-loop iter-6 Cluster-F seeder for the test-matrix
# fixtures (qa-omantel namespace, disposable-cm, qa-wp-creds, qa-user1
# UserAccess + RoleBinding, bp-qa-custom Blueprint). DEFAULT-OFF;
# enable only on test Sovereigns. Production Sovereigns must keep
# `enabled: false` so test resources never leak into customer clusters.
# See templates/qa-fixtures/_README.txt for the full rationale.
qaFixtures:
enabled: false
namespace: qa-omantel
appName: qa-wp
sovereignRef: omantel
organization: omantel-platform
qaUser:
email: qa-user1@openova.io
name: qa-user1
keycloakSubject: qa-user1
# qaWpPassword: optional explicit value for qa-wp-creds Secret.
# When empty the template derives a deterministic placeholder from
# the release name + namespace so the chart never bakes a hard-coded
# credential into the manifest stream. The matrix only checks for
# the Secret's existence, not the password value.
qaWpPassword: ""