Skip to content

Commit fc1f938

Browse files
committed
test: expired CA certs integration test
1 parent dff0523 commit fc1f938

13 files changed

+449
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% if test_scenario['values']['openshift'] == 'true' %}
2+
# see https://github.com/stackabletech/issues/issues/566
3+
---
4+
apiVersion: kuttl.dev/v1beta1
5+
kind: TestStep
6+
commands:
7+
- script: kubectl patch namespace $NAMESPACE -p '{"metadata":{"labels":{"pod-security.kubernetes.io/enforce":"privileged"}}}'
8+
timeout: 120
9+
{% endif %}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
apiVersion: kuttl.dev/v1beta1
3+
kind: TestStep
4+
commands:
5+
- script: envsubst '$NAMESPACE' < 01_secretclass.yaml | kubectl --namespace=$NAMESPACE apply -f -
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
apiVersion: secrets.stackable.tech/v1alpha1
3+
kind: SecretClass
4+
metadata:
5+
name: tls-short-ca
6+
spec:
7+
backend:
8+
autoTls:
9+
ca:
10+
secret:
11+
name: secret-provisioner-tls-ca-short
12+
namespace: $NAMESPACE
13+
autoGenerate: true
14+
caCertificateLifetime: 5m
15+
---
16+
apiVersion: secrets.stackable.tech/v1alpha1
17+
kind: SecretClass
18+
metadata:
19+
name: tls-normal-ca
20+
spec:
21+
backend:
22+
autoTls:
23+
ca:
24+
secret:
25+
name: secret-provisioner-tls-ca-normal
26+
namespace: $NAMESPACE
27+
autoGenerate: true
28+
caCertificateLifetime: 365d
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
kind: Role
3+
apiVersion: rbac.authorization.k8s.io/v1
4+
metadata:
5+
name: use-integration-tests-scc
6+
rules:
7+
- apiGroups:
8+
- ""
9+
resources:
10+
- configmaps
11+
- secrets
12+
verbs:
13+
- create
14+
- get
15+
- list
16+
{% if test_scenario['values']['openshift'] == "true" %}
17+
- apiGroups: ["security.openshift.io"]
18+
resources: ["securitycontextconstraints"]
19+
resourceNames: ["privileged"]
20+
verbs: ["use"]
21+
{% endif %}
22+
---
23+
apiVersion: v1
24+
kind: ServiceAccount
25+
metadata:
26+
name: integration-tests-sa
27+
---
28+
kind: RoleBinding
29+
apiVersion: rbac.authorization.k8s.io/v1
30+
metadata:
31+
name: use-integration-tests-scc
32+
subjects:
33+
- kind: ServiceAccount
34+
name: integration-tests-sa
35+
roleRef:
36+
kind: Role
37+
name: use-integration-tests-scc
38+
apiGroup: rbac.authorization.k8s.io
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
# TrustStore without caExpiryThreshold - should include all CAs even if expired
3+
apiVersion: secrets.stackable.tech/v1alpha1
4+
kind: TrustStore
5+
metadata:
6+
name: truststore-all-cas
7+
spec:
8+
secretClassName: tls-short-ca
9+
format: tls-pem
10+
---
11+
# TrustStore with caExpiryThreshold - should filter out CAs close to expiry
12+
apiVersion: secrets.stackable.tech/v1alpha1
13+
kind: TrustStore
14+
metadata:
15+
name: truststore-filtered-cas
16+
spec:
17+
secretClassName: tls-short-ca
18+
format: tls-pem
19+
caExpiryThreshold: 1h
20+
---
21+
# TrustStore with normal CA lifetime for comparison
22+
apiVersion: secrets.stackable.tech/v1alpha1
23+
kind: TrustStore
24+
metadata:
25+
name: truststore-normal-cas
26+
spec:
27+
secretClassName: tls-normal-ca
28+
format: tls-pem
29+
caExpiryThreshold: 1d
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
apiVersion: kuttl.dev/v1beta1
3+
kind: TestAssert
4+
timeout: 30
5+
---
6+
apiVersion: v1
7+
kind: ConfigMap
8+
metadata:
9+
name: truststore-all-cas
10+
---
11+
apiVersion: v1
12+
kind: ConfigMap
13+
metadata:
14+
name: truststore-filtered-cas
15+
---
16+
apiVersion: v1
17+
kind: ConfigMap
18+
metadata:
19+
name: truststore-normal-cas
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
apiVersion: kuttl.dev/v1beta1
3+
kind: TestStep
4+
commands:
5+
- script: sleep 310
6+
timeout: 320
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
---
2+
apiVersion: batch/v1
3+
kind: Job
4+
metadata:
5+
name: ca-expiry-consumer
6+
spec:
7+
template:
8+
spec:
9+
containers:
10+
- name: consumer
11+
image: oci.stackable.tech/sdp/testing-tools:0.2.0-stackable0.0.0-dev
12+
command:
13+
- bash
14+
args:
15+
- -c
16+
- |
17+
set -euo pipefail
18+
19+
echo ""
20+
echo "Testing volume with short threshold (should filter out expired CA)..."
21+
if [ -f "/stackable/tls-short-with-threshold/ca.crt" ]; then
22+
CA_COUNT_WITH_THRESHOLD=$(grep -c "BEGIN CERTIFICATE" /stackable/tls-short-with-threshold/ca.crt)
23+
echo "Number of CAs in volume with threshold: $CA_COUNT_WITH_THRESHOLD"
24+
25+
if [ "$CA_COUNT_WITH_THRESHOLD" -ne 1 ]; then
26+
echo "ERROR: Expected exactly one CA in volume with threshold!"
27+
exit 1
28+
fi
29+
30+
# Check that CA is valid for at least 1 minute
31+
if cat /stackable/tls-short-with-threshold/ca.crt | openssl x509 -noout -checkend 60; then
32+
echo "CA in volume with threshold is valid as expected"
33+
else
34+
echo "ERROR: CA in volume with threshold should be valid for at least 1 minute!"
35+
exit 1
36+
fi
37+
else
38+
echo "ERROR: No ca.crt file found in volume with threshold!"
39+
exit 1
40+
fi
41+
42+
# Check that the cert was signed by the CA and is valid
43+
if [ -f "/stackable/tls-short-with-threshold/tls.crt" ]; then
44+
if openssl verify -CAfile /stackable/tls-short-with-threshold/ca.crt /stackable/tls-short-with-threshold/tls.crt; then
45+
echo "TLS certificate is valid and signed by the CA"
46+
else
47+
echo "ERROR: TLS certificate verification failed!"
48+
exit 1
49+
fi
50+
else
51+
echo "ERROR: No tls.crt file found in volume with threshold!"
52+
exit 1
53+
fi
54+
55+
echo ""
56+
echo "Testing volume without threshold (should contain CA even if expired)..."
57+
if [ -f "/stackable/tls-short-without-threshold/ca.crt" ]; then
58+
CA_COUNT_WITHOUT_THRESHOLD=$(grep -c "BEGIN CERTIFICATE" /stackable/tls-short-without-threshold/ca.crt)
59+
echo "Number of CAs in volume without threshold: $CA_COUNT_WITHOUT_THRESHOLD"
60+
61+
if [ "$CA_COUNT_WITHOUT_THRESHOLD" -lt 2 ]; then
62+
echo "ERROR: Expected at least two CAs in volume without threshold!"
63+
exit 1
64+
fi
65+
else
66+
echo "ERROR: No ca.crt file found in volume without threshold!"
67+
exit 1
68+
fi
69+
70+
echo ""
71+
echo "Testing normal CA volume with threshold (should contain valid CA)..."
72+
if [ -f "/stackable/tls-normal-with-threshold/ca.crt" ]; then
73+
CA_COUNT_NORMAL=$(grep -c "BEGIN CERTIFICATE" /stackable/tls-normal-with-threshold/ca.crt)
74+
echo "Number of CAs in normal volume: $CA_COUNT_NORMAL"
75+
76+
if [ "$CA_COUNT_NORMAL" -lt 1 ]; then
77+
echo "ERROR: Expected at least one CA in normal volume!"
78+
exit 1
79+
fi
80+
81+
# Check that CA is valid for well beyond 1 hour
82+
cat /stackable/tls-normal-with-threshold/ca.crt | openssl x509 -noout -checkend 86400 || {
83+
echo "ERROR: Normal CA should be valid for at least 24 hours!"
84+
exit 1
85+
}
86+
87+
echo "Normal CA is valid and passes threshold check"
88+
else
89+
echo "ERROR: No ca.crt file found in normal volume!"
90+
exit 1
91+
fi
92+
93+
echo ""
94+
echo "Testing TrustStore ConfigMaps content..."
95+
96+
# Test TrustStore without threshold (should contain expired CA)
97+
echo "Testing truststore-all-cas ConfigMap (should contain expired CA)..."
98+
TRUSTSTORE_ALL_DATA=$(kubectl get configmap truststore-all-cas -o jsonpath='{.data.ca\.crt}')
99+
if [ -z "$TRUSTSTORE_ALL_DATA" ]; then
100+
echo "ERROR: truststore-all-cas ConfigMap has no ca.crt data!"
101+
exit 1
102+
fi
103+
104+
TRUSTSTORE_ALL_COUNT=$(echo "$TRUSTSTORE_ALL_DATA" | grep -c "BEGIN CERTIFICATE")
105+
echo "Number of CAs in truststore-all-cas: $TRUSTSTORE_ALL_COUNT"
106+
107+
if [ "$TRUSTSTORE_ALL_COUNT" -lt 1 ]; then
108+
echo "ERROR: Expected at least one CA in truststore-all-cas!"
109+
exit 1
110+
fi
111+
112+
# Check if at least one CA is expired (it should be)
113+
if ! echo "$TRUSTSTORE_ALL_DATA" | openssl x509 -noout -checkend 0; then
114+
echo "At least one CA in truststore-all-cas is expired, as expected"
115+
else
116+
echo "ERROR: At least one CA in truststore-all-cas should be expired!"
117+
exit 1
118+
fi
119+
120+
# Test TrustStore with threshold (should contain only valid CAs)
121+
echo ""
122+
echo "Testing truststore-filtered-cas ConfigMap (should filter out expired CA)..."
123+
TRUSTSTORE_FILTERED_DATA=$(kubectl get configmap truststore-filtered-cas -o jsonpath='{.data.ca\.crt}' || echo "")
124+
125+
if [ -z "$TRUSTSTORE_FILTERED_DATA" ]; then
126+
echo "truststore-filtered-cas ConfigMap has no ca.crt data (expected - expired CA was filtered)"
127+
else
128+
TRUSTSTORE_FILTERED_COUNT=$(echo "$TRUSTSTORE_FILTERED_DATA" | grep -c "BEGIN CERTIFICATE" || echo "0")
129+
echo "Number of CAs in truststore-filtered-cas: $TRUSTSTORE_FILTERED_COUNT"
130+
131+
# If there are any CAs, they should be valid
132+
if [ "$TRUSTSTORE_FILTERED_COUNT" -gt 0 ]; then
133+
if echo "$TRUSTSTORE_FILTERED_DATA" | openssl x509 -noout -checkend 3600; then
134+
echo "CA in truststore-filtered-cas is valid"
135+
else
136+
echo "ERROR: CA in truststore-filtered-cas should be valid if present!"
137+
exit 1
138+
fi
139+
fi
140+
fi
141+
142+
# Test TrustStore with normal CA (should contain valid CA)
143+
echo ""
144+
echo "Testing truststore-normal-cas ConfigMap (should contain valid CA)..."
145+
TRUSTSTORE_NORMAL_DATA=$(kubectl get configmap truststore-normal-cas -o jsonpath='{.data.ca\.crt}')
146+
if [ -z "$TRUSTSTORE_NORMAL_DATA" ]; then
147+
echo "ERROR: truststore-normal-cas ConfigMap has no ca.crt data!"
148+
exit 1
149+
fi
150+
151+
TRUSTSTORE_NORMAL_COUNT=$(echo "$TRUSTSTORE_NORMAL_DATA" | grep -c "BEGIN CERTIFICATE")
152+
echo "Number of CAs in truststore-normal-cas: $TRUSTSTORE_NORMAL_COUNT"
153+
154+
if [ "$TRUSTSTORE_NORMAL_COUNT" -lt 1 ]; then
155+
echo "ERROR: Expected at least one CA in truststore-normal-cas!"
156+
exit 1
157+
fi
158+
159+
# Check that the CA is valid for well beyond the threshold
160+
if echo "$TRUSTSTORE_NORMAL_DATA" | openssl x509 -noout -checkend 86400; then
161+
echo "CA in truststore-normal-cas is valid and passes threshold check"
162+
else
163+
echo "ERROR: CA in truststore-normal-cas should be valid for at least 24 hours!"
164+
exit 1
165+
fi
166+
167+
volumeMounts:
168+
- mountPath: /stackable/tls-short-with-threshold
169+
name: tls-short-with-threshold
170+
- mountPath: /stackable/tls-short-without-threshold
171+
name: tls-short-without-threshold
172+
- mountPath: /stackable/tls-normal-with-threshold
173+
name: tls-normal-with-threshold
174+
volumes:
175+
- name: tls-short-with-threshold
176+
ephemeral:
177+
volumeClaimTemplate:
178+
metadata:
179+
annotations:
180+
secrets.stackable.tech/class: tls-short-ca
181+
secrets.stackable.tech/scope: node,pod
182+
secrets.stackable.tech/backend.autotls.ca.expiry-threshold: 1m
183+
secrets.stackable.tech/backend.autotls.cert.restart-buffer: 1s
184+
secrets.stackable.tech/backend.autotls.cert.lifetime: 1m
185+
spec:
186+
storageClassName: secrets.stackable.tech
187+
accessModes:
188+
- ReadWriteOnce
189+
resources:
190+
requests:
191+
storage: "1"
192+
- name: tls-short-without-threshold
193+
ephemeral:
194+
volumeClaimTemplate:
195+
metadata:
196+
annotations:
197+
secrets.stackable.tech/class: tls-short-ca
198+
secrets.stackable.tech/scope: node,pod
199+
secrets.stackable.tech/backend.autotls.cert.restart-buffer: 1s
200+
secrets.stackable.tech/backend.autotls.cert.lifetime: 1m
201+
spec:
202+
storageClassName: secrets.stackable.tech
203+
accessModes:
204+
- ReadWriteOnce
205+
resources:
206+
requests:
207+
storage: "1"
208+
- name: tls-normal-with-threshold
209+
ephemeral:
210+
volumeClaimTemplate:
211+
metadata:
212+
annotations:
213+
secrets.stackable.tech/class: tls-normal-ca
214+
secrets.stackable.tech/scope: node,pod
215+
secrets.stackable.tech/backend.autotls.ca.expiry-threshold: 1d
216+
spec:
217+
storageClassName: secrets.stackable.tech
218+
accessModes:
219+
- ReadWriteOnce
220+
resources:
221+
requests:
222+
storage: "1"
223+
securityContext:
224+
runAsUser: 1000
225+
runAsGroup: 1000
226+
fsGroup: 1000
227+
restartPolicy: Never
228+
terminationGracePeriodSeconds: 0
229+
serviceAccount: integration-tests-sa
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
apiVersion: kuttl.dev/v1beta1
3+
kind: TestAssert
4+
timeout: 60
5+
---
6+
apiVersion: batch/v1
7+
kind: Job
8+
metadata:
9+
name: ca-expiry-consumer
10+
status:
11+
conditions:
12+
- type: SuccessCriteriaMet
13+
status: "True"
14+
- type: Complete
15+
status: "True"

0 commit comments

Comments
 (0)