refactor(hermes-triage-demo): ConfigMap fixture replaces Longhorn PVC

- Pipeline ensures the fixture ConfigMap and seeds unhealthy via patch-file
- Test-runner mounts the ConfigMap read-only; no storage attach involved
- New hermes-demo-repair SA + Role scoped to patching only the fixture CM
- Removes the fixture PVC (Flux prunes it)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jenkins 2026-08-05 17:42:10 -03:00
parent 3e6783e44d
commit 167ab91b60
4 changed files with 64 additions and 38 deletions

View File

@ -1,17 +0,0 @@
# services/hermes-triage-demo/fixture-pvc.yaml
# Single-file demo fixture: holds one state value ("healthy"/"unhealthy").
# The Jenkins test-runner reads it; the Ariadne repair Job writes it back to healthy.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hermes-triage-demo-fixture
namespace: hermes-triage-demo
labels:
app.kubernetes.io/part-of: hermes-triage-demo
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 100Mi

View File

@ -3,5 +3,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- fixture-pvc.yaml
- rbac.yaml

View File

@ -1,8 +1,19 @@
# services/hermes-triage-demo/rbac.yaml
# Lets Jenkins agent pods (SA jenkins/jenkins) create and observe the demo
# test-runner Job in this namespace only. The Ariadne repair path needs no
# grant here: its ariadne-job-spawner ClusterRole already covers Job
# create/watch, and the repair pod itself only mounts the fixture PVC.
# Two scoped grants:
# 1. Jenkins agent pods (SA jenkins/jenkins) create and observe the demo
# test-runner Job and manage the fixture ConfigMap (ensure + seed).
# 2. The Ariadne-created repair Job runs as SA hermes-demo-repair, which can
# patch only the fixture ConfigMap back to healthy.
# The Ariadne repair path needs no Job-create grant here: its
# ariadne-job-spawner ClusterRole already covers Job create/watch.
apiVersion: v1
kind: ServiceAccount
metadata:
name: hermes-demo-repair
namespace: hermes-triage-demo
labels:
app.kubernetes.io/part-of: hermes-triage-demo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
@ -20,6 +31,13 @@ rules:
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["hermes-triage-demo-fixture"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
@ -36,3 +54,32 @@ subjects:
- kind: ServiceAccount
name: jenkins
namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: demo-repair
namespace: hermes-triage-demo
labels:
app.kubernetes.io/part-of: hermes-triage-demo
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["hermes-triage-demo-fixture"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: demo-repair
namespace: hermes-triage-demo
labels:
app.kubernetes.io/part-of: hermes-triage-demo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: demo-repair
subjects:
- kind: ServiceAccount
name: hermes-demo-repair
namespace: hermes-triage-demo

View File

@ -492,7 +492,12 @@ data:
def buildNum = '' + env.BUILD_NUMBER
def incidentId = 'hermes-triage-demo/' + buildNum
def jobName = 'hermes-demo-test-' + buildNum
def seed = params.SEED_FAILURE ? 'true' : 'false'
sh 'kubectl -n hermes-triage-demo get configmap hermes-triage-demo-fixture || kubectl -n hermes-triage-demo create configmap hermes-triage-demo-fixture --from-literal=state=healthy'
if (params.SEED_FAILURE) {
writeFile file: 'seed.json', text: '{"data":{"state":"unhealthy"}}'
sh 'kubectl -n hermes-triage-demo patch configmap hermes-triage-demo-fixture --type merge --patch-file seed.json'
echo 'Demo failure armed: fixture state set to unhealthy'
}
def manifest = [
'apiVersion: batch/v1',
'kind: Job',
@ -520,29 +525,21 @@ data:
' env:',
' - name: INCIDENT_ID',
' value: "' + incidentId + '"',
' - name: SEED_FAILURE',
' value: "' + seed + '"',
' command:',
' - sh',
' - -c',
' - |',
' STATE_FILE=/fixture/state',
' if [ "$SEED_FAILURE" = "true" ]; then',
' echo unhealthy > "$STATE_FILE"',
' fi',
' if [ ! -f "$STATE_FILE" ]; then',
' echo healthy > "$STATE_FILE"',
' fi',
' STATE=$(cat "$STATE_FILE")',
' STATE=$(cat /fixture/state)',
' if [ "$STATE" = "healthy" ]; then',
' echo "{\\\\"event\\\\":\\\\"hermes_demo_test_pass\\\\",\\\\"incident_id\\\\":\\\\"$INCIDENT_ID\\\\",\\\\"message\\\\":\\\\"fixture state healthy\\\\"}"',
' echo "{\\"event\\":\\"hermes_demo_test_pass\\",\\"incident_id\\":\\"$INCIDENT_ID\\",\\"message\\":\\"fixture state healthy\\"}"',
' exit 0',
' fi',
' echo "{\\\\"event\\\\":\\\\"hermes_demo_test_failure\\\\",\\\\"incident_id\\\\":\\\\"$INCIDENT_ID\\\\",\\\\"classification_hint\\\\":\\\\"demo_fixture_unhealthy\\\\",\\\\"message\\\\":\\\\"expected fixture state healthy; found $STATE\\\\"}"',
' echo "{\\"event\\":\\"hermes_demo_test_failure\\",\\"incident_id\\":\\"$INCIDENT_ID\\",\\"classification_hint\\":\\"demo_fixture_unhealthy\\",\\"message\\":\\"expected fixture state healthy; found $STATE\\"}"',
' exit 1',
' volumeMounts:',
' - name: fixture',
' mountPath: /fixture',
' readOnly: true',
' resources:',
' requests:',
' cpu: 25m',
@ -552,10 +549,10 @@ data:
' memory: 32Mi',
' volumes:',
' - name: fixture',
' persistentVolumeClaim:',
' claimName: hermes-triage-demo-fixture'
' configMap:',
' name: hermes-triage-demo-fixture'
]
writeFile file: 'test-runner-job.yaml', text: manifest.join('\\n') + '\\n'
writeFile file: 'test-runner-job.yaml', text: manifest.join('\n') + '\n'
sh 'kubectl -n hermes-triage-demo create -f test-runner-job.yaml'
def verdict = 'unknown'
timeout(time: 3, unit: 'MINUTES') {