Skip to content

Commit 34a797a

Browse files
committed
fix: add ClusterStaticEntry workaround for SPIRE ignoreNamespaces
The ZTWIM operator hardcodes ignoreNamespaces: ["openshift-*"] in the spire-controller-manager config, which prevents SPIRE from issuing identities to pods in openshift-pipelines. Work around this by creating ClusterStaticEntry resources that register the tekton-chains-controller directly, bypassing the ignoreNamespaces filter. A PostSync Job dynamically discovers node UIDs to build the correct parentID for each SPIRE agent. Signed-off-by: Min Zhang <minzhang@redhat.com>
1 parent 394da18 commit 34a797a

1 file changed

Lines changed: 143 additions & 0 deletions

File tree

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
{{- if and .Values.chains.enabled .Values.chains.signers.x509.fulcio.enabled }}
2+
{{- if eq .Values.chains.signers.x509.fulcio.provider "spiffe" }}
3+
---
4+
apiVersion: v1
5+
kind: ServiceAccount
6+
metadata:
7+
name: tekton-chains-spire-config
8+
namespace: {{ .Release.Namespace }}
9+
annotations:
10+
argocd.argoproj.io/sync-wave: "48"
11+
---
12+
apiVersion: rbac.authorization.k8s.io/v1
13+
kind: ClusterRole
14+
metadata:
15+
name: tekton-chains-spire-config
16+
annotations:
17+
argocd.argoproj.io/sync-wave: "48"
18+
rules:
19+
- apiGroups: [""]
20+
resources: ["nodes"]
21+
verbs: ["list"]
22+
- apiGroups: ["spire.spiffe.io"]
23+
resources: ["clusterstaticentries"]
24+
verbs: ["get", "list", "create", "update", "patch", "delete"]
25+
---
26+
apiVersion: rbac.authorization.k8s.io/v1
27+
kind: ClusterRoleBinding
28+
metadata:
29+
name: tekton-chains-spire-config
30+
annotations:
31+
argocd.argoproj.io/sync-wave: "48"
32+
roleRef:
33+
apiGroup: rbac.authorization.k8s.io
34+
kind: ClusterRole
35+
name: tekton-chains-spire-config
36+
subjects:
37+
- kind: ServiceAccount
38+
name: tekton-chains-spire-config
39+
namespace: {{ .Release.Namespace }}
40+
---
41+
apiVersion: batch/v1
42+
kind: Job
43+
metadata:
44+
name: tekton-chains-spire-entries
45+
namespace: {{ .Release.Namespace }}
46+
annotations:
47+
argocd.argoproj.io/sync-wave: "48"
48+
argocd.argoproj.io/hook: PostSync
49+
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
50+
labels:
51+
{{- include "tekton-chains.labels" . | nindent 4 }}
52+
spec:
53+
backoffLimit: 5
54+
template:
55+
metadata:
56+
labels:
57+
{{- include "tekton-chains.selectorLabels" . | nindent 8 }}
58+
spec:
59+
serviceAccountName: tekton-chains-spire-config
60+
restartPolicy: Never
61+
containers:
62+
- name: create-entries
63+
image: registry.redhat.io/openshift4/ose-cli-rhel9:latest
64+
imagePullPolicy: IfNotPresent
65+
resources:
66+
requests:
67+
cpu: 50m
68+
memory: 128Mi
69+
limits:
70+
cpu: 200m
71+
memory: 256Mi
72+
command: ["/bin/bash", "-c"]
73+
args:
74+
- |
75+
set -euo pipefail
76+
77+
TRUST_DOMAIN=$(oc get configmap spire-controller-manager \
78+
-n zero-trust-workload-identity-manager \
79+
-o jsonpath='{.data.controller-manager-config\.yaml}' \
80+
| grep trustDomain | awk '{print $2}')
81+
CLUSTER_NAME=$(oc get configmap spire-controller-manager \
82+
-n zero-trust-workload-identity-manager \
83+
-o jsonpath='{.data.controller-manager-config\.yaml}' \
84+
| grep 'clusterName:' | awk '{print $2}')
85+
CLASS_NAME=$(oc get configmap spire-controller-manager \
86+
-n zero-trust-workload-identity-manager \
87+
-o jsonpath='{.data.controller-manager-config\.yaml}' \
88+
| grep 'className:' | head -1 | awk '{print $2}')
89+
90+
echo "Trust domain: $TRUST_DOMAIN"
91+
echo "Cluster name: $CLUSTER_NAME"
92+
echo "Class name: $CLASS_NAME"
93+
94+
NODES=$(oc get nodes -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.uid}{"\n"}{end}')
95+
echo ""
96+
echo "Nodes:"
97+
echo "$NODES"
98+
99+
echo "$NODES" | while read -r NODE_NAME NODE_UID; do
100+
[ -z "$NODE_NAME" ] && continue
101+
ENTRY_NAME="tekton-chains-controller-${NODE_NAME}"
102+
PARENT_ID="spiffe://${TRUST_DOMAIN}/spire/agent/k8s_psat/${CLUSTER_NAME}/${NODE_UID}"
103+
SPIFFE_ID="spiffe://${TRUST_DOMAIN}/ns/openshift-pipelines/sa/tekton-chains-controller"
104+
105+
echo ""
106+
echo "Creating ClusterStaticEntry: $ENTRY_NAME"
107+
echo " parentID: $PARENT_ID"
108+
109+
oc apply -f - <<ENTRY_EOF
110+
apiVersion: spire.spiffe.io/v1alpha1
111+
kind: ClusterStaticEntry
112+
metadata:
113+
name: ${ENTRY_NAME}
114+
labels:
115+
app.kubernetes.io/part-of: tekton-chains
116+
app.kubernetes.io/managed-by: tekton-chains-spire-config
117+
spec:
118+
className: ${CLASS_NAME}
119+
parentID: "${PARENT_ID}"
120+
spiffeID: "${SPIFFE_ID}"
121+
selectors:
122+
- "k8s:ns:openshift-pipelines"
123+
- "k8s:sa:tekton-chains-controller"
124+
ENTRY_EOF
125+
done
126+
127+
echo ""
128+
echo "Cleaning up stale entries..."
129+
EXISTING=$(oc get clusterstaticentries -l app.kubernetes.io/managed-by=tekton-chains-spire-config -o name 2>/dev/null || true)
130+
for entry in $EXISTING; do
131+
ENTRY_SHORT=$(echo "$entry" | sed 's|clusterstaticentry.spire.spiffe.io/||')
132+
NODE_PART=$(echo "$ENTRY_SHORT" | sed 's|tekton-chains-controller-||')
133+
if ! echo "$NODES" | grep -q "^${NODE_PART} "; then
134+
echo "Removing stale entry: $ENTRY_SHORT"
135+
oc delete "$entry" || true
136+
fi
137+
done
138+
139+
echo ""
140+
echo "Done. Current entries:"
141+
oc get clusterstaticentries -l app.kubernetes.io/managed-by=tekton-chains-spire-config
142+
{{- end }}
143+
{{- end }}

0 commit comments

Comments
 (0)