mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-03 10:37:21 +09:00
test(kubernetes): port the Phase-1 OIDC render-side suites to Chainsaw
Main added kubernetes-oidc-system.bats and kubernetes-oidc-customconfig.bats after the Chainsaw migration branch was cut; without a port the 260 lines of coverage would vanish with the hack/e2e-apps/ deletion. Both are light cluster e2e (apply CR -> assert rendered objects; no Kamaji bringup, minReplicas: 0), exactly Chainsaw's declarative shape: - System mode: KamajiControlPlane carries --authentication-config + the chart-owned volume/mount; the AuthenticationConfiguration Secret carries the cozy-realm issuer (regex, script step) + per-cluster audience; per-cluster KeycloakClient/KeycloakClientScope land in the cozy realm - CustomConfig: the flag is still wired; the Secret carries the tenant-supplied issuer and NOT the cozy realm (fail-loud negation); no Keycloak objects and no pre-rendered OIDC kubeconfig Secret, expressed as error ops ordered after the positive asserts so an unreconciled HR cannot false-pass them The port also sheds two latent bats bugs: cozytest defines no skip() (the Keycloak guard would have died with exit 127 had it ever fired) and the api-resources group probe exits 0 even when the group is absent — the chart capability-gates Keycloak rendering and CI always ships the operator, so the asserts are unconditional here. Assisted-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
This commit is contained in:
1 parent
6c76a462a0
commit
cac07db8fc
4 files changed
+322
No files matched your search
@@ -0,0 +1,117 @@
|
||||
# Chainsaw port of hack/e2e-apps/kubernetes-oidc-customconfig.bats.
|
||||
#
|
||||
# Phase-1 OIDC CustomConfig selector e2e — render-side only. Pairs with the
|
||||
# kubernetes-oidc-system suite; see its header for why no Kamaji bringup and
|
||||
# no HR Ready wait (minReplicas: 0, HR asserted to exist only).
|
||||
#
|
||||
# What is exercised on a live cluster: spec.oidc.mode: CustomConfig is
|
||||
# admitted; the HelmRelease renders; the tenant-supplied
|
||||
# AuthenticationConfiguration is wired onto the KamajiControlPlane; and —
|
||||
# crucially — NO Keycloak objects are created in the cozy realm when the
|
||||
# tenant brings their own issuer, and the placeholder OIDC kubeconfig Secret
|
||||
# is NOT pre-rendered (System mode pre-renders it; CustomConfig distributes
|
||||
# out-of-band).
|
||||
#
|
||||
# The absence checks run AFTER the positive authn-config Secret assert
|
||||
# establishes the chart has finished rendering — otherwise a not-yet-
|
||||
# reconciled HR would false-pass them, a hazard the sequential bats never had.
|
||||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
name: kubernetes-oidc-customconfig
|
||||
spec:
|
||||
catch:
|
||||
- events: {}
|
||||
- describe:
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
name: kubernetes-oidc-byo
|
||||
- describe:
|
||||
apiVersion: controlplane.cluster.x-k8s.io/v1alpha1
|
||||
kind: KamajiControlPlane
|
||||
name: kubernetes-oidc-byo
|
||||
steps:
|
||||
- name: create-kubernetes-oidc-byo
|
||||
try:
|
||||
- apply:
|
||||
file: kubernetes-oidc-byo.yaml
|
||||
- assert:
|
||||
timeout: 1m
|
||||
resource:
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: kubernetes-oidc-byo
|
||||
- assert:
|
||||
timeout: 3m
|
||||
resource:
|
||||
apiVersion: controlplane.cluster.x-k8s.io/v1alpha1
|
||||
kind: KamajiControlPlane
|
||||
metadata:
|
||||
name: kubernetes-oidc-byo
|
||||
|
||||
- name: kamajicontrolplane-still-carries-authentication-config
|
||||
try:
|
||||
- assert:
|
||||
resource:
|
||||
apiVersion: controlplane.cluster.x-k8s.io/v1alpha1
|
||||
kind: KamajiControlPlane
|
||||
metadata:
|
||||
name: kubernetes-oidc-byo
|
||||
spec:
|
||||
apiServer:
|
||||
(contains(extraArgs, '--authentication-config=/etc/kubernetes/authentication-config/config.yaml')): true
|
||||
|
||||
- name: authn-config-secret-carries-tenant-issuer
|
||||
try:
|
||||
- assert:
|
||||
timeout: 1m
|
||||
resource:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: kubernetes-oidc-byo-oidc-authn-config
|
||||
- script:
|
||||
content: |
|
||||
set -eu
|
||||
body=$(kubectl -n "$NAMESPACE" get secret kubernetes-oidc-byo-oidc-authn-config \
|
||||
-o jsonpath='{.data.config\.yaml}' | base64 -d)
|
||||
echo "$body" | grep -qF "url: https://idp.byo.example.test"
|
||||
echo "$body" | grep -qF "cozystack-byo-oidc-byo"
|
||||
# Fail-loud negation (a bare `! ... | grep` is vacuous under set -e):
|
||||
# the cozy-realm issuer must NOT appear in a BYO config.
|
||||
if echo "$body" | grep -qE 'url: https://keycloak\.[^/]+/realms/cozy'; then
|
||||
echo "FAIL: BYO AuthenticationConfiguration must not carry the cozy realm issuer" >&2
|
||||
exit 1
|
||||
fi
|
||||
check:
|
||||
($error == null): true
|
||||
|
||||
# Absence proofs — ordered after the positive asserts above (chart has
|
||||
# rendered), so `error` op polling to its timeout is a real negative, not a
|
||||
# not-yet-reconciled false pass.
|
||||
- name: no-keycloak-objects-and-no-prerendered-kubeconfig
|
||||
try:
|
||||
- error:
|
||||
timeout: 30s
|
||||
resource:
|
||||
apiVersion: v1.edp.epam.com/v1
|
||||
kind: KeycloakClient
|
||||
metadata:
|
||||
name: tenant-test-kubernetes-oidc-byo
|
||||
- error:
|
||||
timeout: 30s
|
||||
resource:
|
||||
apiVersion: v1.edp.epam.com/v1
|
||||
kind: KeycloakClientScope
|
||||
metadata:
|
||||
name: tenant-test-kubernetes-oidc-byo-audience
|
||||
# System mode pre-renders <release>-oidc-kubeconfig as a placeholder;
|
||||
# CustomConfig must not.
|
||||
- error:
|
||||
timeout: 30s
|
||||
resource:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: kubernetes-oidc-byo-oidc-kubeconfig
|
||||
@@ -0,0 +1,48 @@
|
||||
apiVersion: apps.cozystack.io/v1alpha1
|
||||
kind: Kubernetes
|
||||
metadata:
|
||||
name: oidc-byo
|
||||
spec:
|
||||
addons:
|
||||
ingressNginx:
|
||||
enabled: false
|
||||
hosts: []
|
||||
valuesOverride: {}
|
||||
controlPlane:
|
||||
apiServer:
|
||||
resources: {}
|
||||
resourcesPreset: small
|
||||
replicas: 1
|
||||
nodeGroups:
|
||||
md0:
|
||||
diskSize: 20Gi
|
||||
gpus: []
|
||||
instanceType: u1.micro
|
||||
maxReplicas: 1
|
||||
minReplicas: 0
|
||||
resources: {}
|
||||
roles:
|
||||
- worker
|
||||
storageClass: replicated
|
||||
version: v1.35
|
||||
oidc:
|
||||
mode: CustomConfig
|
||||
customConfig:
|
||||
config: |
|
||||
apiVersion: apiserver.config.k8s.io/v1beta1
|
||||
kind: AuthenticationConfiguration
|
||||
jwt:
|
||||
- issuer:
|
||||
url: https://idp.byo.example.test
|
||||
audiences:
|
||||
- cozystack-byo-oidc-byo
|
||||
claimMappings:
|
||||
username:
|
||||
claim: preferred_username
|
||||
prefix: ""
|
||||
groups:
|
||||
claim: groups
|
||||
prefix: ""
|
||||
users:
|
||||
- email: byo-admin@example.test
|
||||
role: admin
|
||||
@@ -0,0 +1,123 @@
|
||||
# Chainsaw port of hack/e2e-apps/kubernetes-oidc-system.bats.
|
||||
#
|
||||
# Phase-1 OIDC System-mode e2e — render-side only. Pairs with the
|
||||
# kubernetes-oidc-customconfig suite (BYO issuer path).
|
||||
#
|
||||
# Does NOT spin up a full Kamaji control plane: that path is covered by the
|
||||
# kubernetes-latest/previous suites and would add another ~25 min bringup for
|
||||
# a feature whose end-to-end OIDC browser flow is explicitly out of scope
|
||||
# (see docs/oidc-tenant.md -> Phase 1). minReplicas: 0 means no worker VMs;
|
||||
# the suite runs in minutes. Accordingly the HR is only asserted to EXIST
|
||||
# (cozystack-api materialised it), never Ready.
|
||||
#
|
||||
# What is exercised on a live cluster: the new spec.oidc.* fields are
|
||||
# admitted by the aggregated API; the HelmRelease renders the OIDC templates;
|
||||
# and the resulting KamajiControlPlane / AuthenticationConfiguration Secret /
|
||||
# KeycloakClient / KeycloakClientScope carry the expected per-cluster shape.
|
||||
# The Keycloak asserts are unconditional: the chart capability-gates their
|
||||
# rendering on v1.edp.epam.com/v1 (oidc-keycloak.yaml), and the CI platform
|
||||
# always ships the operator — the bats' api-resources guard was dead code
|
||||
# there (and its `skip` did not exist under cozytest anyway).
|
||||
#
|
||||
# The Kubernetes CR is applied declaratively, so Chainsaw auto-cleanup
|
||||
# deletes it at test end — the bats' hand-rolled cleanup_kr/cozy_cleanup
|
||||
# hooks have no equivalent here by construction.
|
||||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
name: kubernetes-oidc-system
|
||||
spec:
|
||||
catch:
|
||||
- events: {}
|
||||
- describe:
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
name: kubernetes-oidc-system
|
||||
- describe:
|
||||
apiVersion: controlplane.cluster.x-k8s.io/v1alpha1
|
||||
kind: KamajiControlPlane
|
||||
name: kubernetes-oidc-system
|
||||
steps:
|
||||
- name: create-kubernetes-oidc-system
|
||||
try:
|
||||
- apply:
|
||||
file: kubernetes-oidc-system.yaml
|
||||
# cozystack-api materialises the HelmRelease…
|
||||
- assert:
|
||||
timeout: 1m
|
||||
resource:
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: kubernetes-oidc-system
|
||||
# …and the chart renders the KamajiControlPlane (no Ready wait — that
|
||||
# would require the Kamaji bringup this suite deliberately avoids).
|
||||
- assert:
|
||||
timeout: 3m
|
||||
resource:
|
||||
apiVersion: controlplane.cluster.x-k8s.io/v1alpha1
|
||||
kind: KamajiControlPlane
|
||||
metadata:
|
||||
name: kubernetes-oidc-system
|
||||
|
||||
- name: kamajicontrolplane-oidc-wiring
|
||||
try:
|
||||
- assert:
|
||||
resource:
|
||||
apiVersion: controlplane.cluster.x-k8s.io/v1alpha1
|
||||
kind: KamajiControlPlane
|
||||
metadata:
|
||||
name: kubernetes-oidc-system
|
||||
spec:
|
||||
apiServer:
|
||||
# --authentication-config is appended to extraArgs; the
|
||||
# chart-owned mount lands on extraVolumeMounts.
|
||||
(contains(extraArgs, '--authentication-config=/etc/kubernetes/authentication-config/config.yaml')): true
|
||||
(extraVolumeMounts[?name == 'authentication-config']):
|
||||
- name: authentication-config
|
||||
deployment:
|
||||
# The chart-owned volume lands on extraVolumes.
|
||||
(extraVolumes[?name == 'authentication-config']):
|
||||
- name: authentication-config
|
||||
|
||||
- name: authn-config-secret
|
||||
try:
|
||||
- assert:
|
||||
timeout: 1m
|
||||
resource:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: kubernetes-oidc-system-oidc-authn-config
|
||||
# The issuer check is a regex (any keycloak.<host>), so it stays a script;
|
||||
# the per-cluster audience literal rides along.
|
||||
- script:
|
||||
content: |
|
||||
set -eu
|
||||
body=$(kubectl -n "$NAMESPACE" get secret kubernetes-oidc-system-oidc-authn-config \
|
||||
-o jsonpath='{.data.config\.yaml}' | base64 -d)
|
||||
echo "$body" | grep -qE 'url: https://keycloak\.[^/]+/realms/cozy'
|
||||
echo "$body" | grep -qF -- "- tenant-test-kubernetes-oidc-system"
|
||||
check:
|
||||
($error == null): true
|
||||
|
||||
- name: keycloak-objects-in-cozy-realm
|
||||
try:
|
||||
- assert:
|
||||
timeout: 1m
|
||||
resource:
|
||||
apiVersion: v1.edp.epam.com/v1
|
||||
kind: KeycloakClient
|
||||
metadata:
|
||||
name: tenant-test-kubernetes-oidc-system
|
||||
spec:
|
||||
public: true
|
||||
- assert:
|
||||
timeout: 1m
|
||||
resource:
|
||||
apiVersion: v1.edp.epam.com/v1
|
||||
kind: KeycloakClientScope
|
||||
metadata:
|
||||
name: tenant-test-kubernetes-oidc-system-audience
|
||||
spec:
|
||||
(protocolMappers[0].protocolMapper): oidc-audience-mapper
|
||||
@@ -0,0 +1,34 @@
|
||||
apiVersion: apps.cozystack.io/v1alpha1
|
||||
kind: Kubernetes
|
||||
metadata:
|
||||
name: oidc-system
|
||||
spec:
|
||||
addons:
|
||||
ingressNginx:
|
||||
enabled: false
|
||||
hosts: []
|
||||
valuesOverride: {}
|
||||
controlPlane:
|
||||
apiServer:
|
||||
resources: {}
|
||||
resourcesPreset: small
|
||||
replicas: 1
|
||||
nodeGroups:
|
||||
md0:
|
||||
diskSize: 20Gi
|
||||
gpus: []
|
||||
instanceType: u1.micro
|
||||
maxReplicas: 1
|
||||
minReplicas: 0
|
||||
resources: {}
|
||||
roles:
|
||||
- worker
|
||||
storageClass: replicated
|
||||
version: v1.35
|
||||
oidc:
|
||||
mode: System
|
||||
users:
|
||||
- email: e2e-admin@example.test
|
||||
role: admin
|
||||
- email: e2e-viewer@example.test
|
||||
role: view
|
||||
Reference in new issue
Block a user