Skip to content

Commit da61a87

Browse files
authored
Allow extra manually added pull secrets to managed SA (#418)
* feat: add annotation on SA to keep track of pull secrets Add an annotation to keep track of managed pullsecrets on the created service account * feat: use actual pull secret comparision instead of annotations * feat: tidy current e2e tests and add cleanups * fix: add banner * feat: add e2e service account tests * fix: yq syntax fix * fix: yq eval environment variable * fix: e2e scripts base_dir reference * Revert "fix: e2e scripts base_dir reference" This reverts commit e070403. * fix: copy missing tests folder into e2e container * feat: bump rok8s to @13 and ci-images to v13
1 parent 5944588 commit da61a87

File tree

15 files changed

+300
-46
lines changed

15 files changed

+300
-46
lines changed

Diff for: .circleci/config.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 2.1
22

33
orbs:
4-
rok8s: fairwinds/rok8s-scripts@11
4+
rok8s: fairwinds/rok8s-scripts@13
55
oss-docs: fairwinds/oss-docs@0
66

77
references:
@@ -18,7 +18,7 @@ references:
1818
e2e_configuration: &e2e_configuration
1919
pre_script: e2e/pre.sh
2020
script: e2e/test.sh
21-
command_runner_image: quay.io/reactiveops/ci-images:v12-buster
21+
command_runner_image: quay.io/reactiveops/ci-images:v13-buster
2222
enable_docker_layer_caching: true
2323
attach-workspace: true
2424
requires:

Diff for: e2e/pre.sh

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
set -e
44

5-
wget -O /usr/local/bin/yq "https://github.com/mikefarah/yq/releases/download/2.4.0/yq_linux_amd64"
5+
wget -O /usr/local/bin/yq "https://github.com/mikefarah/yq/releases/download/v4.35.1/yq_linux_amd64"
66
chmod +x /usr/local/bin/yq
77

88
if [ -z "$CI_SHA1" ]; then
@@ -26,8 +26,10 @@ echo "** END LOADING IMAGE **"
2626
echo "********************************************************************"
2727
printf "\n\n"
2828

29-
yq w -i deploy/3_deployment.yaml 'spec.template.spec.containers[0].image' "quay.io/reactiveops/rbac-manager:${CI_SHA1}-amd64"
30-
yq w -i deploy/3_deployment.yaml 'spec.template.spec.containers[0].imagePullPolicy' "IfNotPresent"
29+
export newImage=quay.io/reactiveops/rbac-manager:${CI_SHA1}-amd64
30+
yq -i '.spec.template.spec.containers[0].image = env(newImage)' deploy/3_deployment.yaml
31+
yq -i '.spec.template.spec.containers[0].imagePullPolicy = "IfNotPresent"' deploy/3_deployment.yaml
3132
cat deploy/3_deployment.yaml
3233

3334
docker cp deploy e2e-command-runner:/
35+
docker cp e2e/rbacdefinition e2e-command-runner:/

Diff for: e2e/rbacdefinition/cluterrolebindings/cleanup.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
kubectl delete clusterrole test-rbac-manager --ignore-not-found
2+
kubectl delete RBACDefinition rbac-manager-definition --ignore-not-found

Diff for: e2e/rbacdefinition/cluterrolebindings/main.sh

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
BASE_DIR=$(dirname $BASH_SOURCE)
2+
3+
printf "\n\n"
4+
echo "********************************************************************"
5+
echo "** Test clusterrolebindings **"
6+
echo "********************************************************************"
7+
printf "\n\n"
8+
9+
# Execute the setup, then execute the tests just if the setup contains no errors.
10+
# Finally always execute the cleanup and return the whole error of the steps
11+
error=$((0))
12+
bash "$BASE_DIR/setup.sh"
13+
error=$(( error | $? ))
14+
15+
if [ $error -eq 0 ]; then
16+
bash "$BASE_DIR/tests.sh"
17+
error=$(( error | $? ))
18+
fi
19+
20+
bash "$BASE_DIR/cleanup.sh"
21+
exit $(( error | $? ))

Diff for: e2e/rbacdefinition/cluterrolebindings/setup.sh

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
kubectl create clusterrole test-rbac-manager --verb="create" --resource=deployment
2+
3+
cat <<EOF | kubectl create -f -
4+
apiVersion: rbacmanager.reactiveops.io/v1beta1
5+
kind: RBACDefinition
6+
metadata:
7+
name: rbac-manager-definition
8+
rbacBindings:
9+
- name: admins
10+
subjects:
11+
- kind: ServiceAccount
12+
name: test-rbac-manager
13+
namespace: rbac-manager
14+
clusterRoleBindings:
15+
- clusterRole: test-rbac-manager
16+
EOF

Diff for: e2e/rbacdefinition/cluterrolebindings/tests.sh

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# wait up to 2 minutes for rbac-manager to create the binding
2+
counter=0
3+
until kubectl get clusterrolebinding/rbac-manager-definition-admins-test-rbac-manager; do
4+
let "counter=counter+1"
5+
sleep 10
6+
if [ $counter -gt 11 ]; then
7+
break
8+
fi
9+
done
10+
kubectl auth can-i create deployments --as=system:serviceaccount:rbac-manager:test-rbac-manager

Diff for: e2e/rbacdefinition/run.sh

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
BASE_DIR=$(dirname $BASH_SOURCE)
2+
3+
printf "\n\n"
4+
echo "********************************************************************"
5+
echo "** Test rbacDefinition **"
6+
echo "********************************************************************"
7+
printf "\n\n"
8+
9+
10+
bash "$BASE_DIR/cluterrolebindings/main.sh"
11+
if [ $? -ne 0 ]; then
12+
exit 1
13+
fi
14+
15+
bash "$BASE_DIR/serviceaccounts/main.sh"
16+
if [ $? -ne 0 ]; then
17+
exit 1
18+
fi

Diff for: e2e/rbacdefinition/serviceaccounts/cleanup.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
kubectl delete clusterrole test-rbac-manager --ignore-not-found
2+
kubectl delete RBACDefinition rbac-manager-definition-1 --ignore-not-found

Diff for: e2e/rbacdefinition/serviceaccounts/main.sh

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
BASE_DIR=$(dirname $BASH_SOURCE)
2+
3+
printf "\n\n"
4+
echo "********************************************************************"
5+
echo "** Test serviceaccounts **"
6+
echo "********************************************************************"
7+
printf "\n\n"
8+
9+
# Execute the setup, then execute the tests just if the setup contains no errors.
10+
# Finally always execute the cleanup and return the whole error of the steps
11+
error=$((0))
12+
bash "$BASE_DIR/setup.sh"
13+
error=$(( error | $? ))
14+
15+
if [ $error -eq 0 ]; then
16+
bash "$BASE_DIR/tests.sh"
17+
error=$(( error | $? ))
18+
fi
19+
20+
bash "$BASE_DIR/cleanup.sh"
21+
exit $(( error | $? ))

Diff for: e2e/rbacdefinition/serviceaccounts/setup.sh

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
kubectl create clusterrole test-rbac-manager --verb="create" --resource=deployment
2+
3+
cat <<EOF | kubectl create -f -
4+
apiVersion: rbacmanager.reactiveops.io/v1beta1
5+
kind: RBACDefinition
6+
metadata:
7+
name: rbac-manager-definition-1
8+
rbacBindings:
9+
- name: admins
10+
subjects:
11+
- kind: ServiceAccount
12+
name: test-rbac-manager
13+
namespace: rbac-manager
14+
imagePullSecrets:
15+
- robot-secret
16+
clusterRoleBindings:
17+
- clusterRole: test-rbac-manager
18+
EOF

Diff for: e2e/rbacdefinition/serviceaccounts/tests.sh

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# wait up to 2 minutes for rbac-manager to create the binding
2+
counter=0
3+
error=$((0))
4+
until kubectl get -n rbac-manager serviceaccount/test-rbac-manager; do
5+
let "counter=counter+1"
6+
sleep 10
7+
if [ $counter -gt 11 ]; then
8+
break
9+
fi
10+
done
11+
12+
kubectl get -n rbac-manager serviceaccount/test-rbac-manager
13+
error=$(( error | $? ))
14+
if [ "$error" -eq 1 ]; then
15+
>&2 echo "error: The Service account must exists"
16+
fi
17+
kubectl delete -n rbac-manager serviceaccount/test-rbac-manager
18+
kubectl get -n rbac-manager serviceaccount/test-rbac-manager
19+
error=$(( error | $? ))
20+
if [ "$error" -eq 1 ]; then
21+
>&2 echo "error: The Service account must be recreated"
22+
fi
23+
24+
# ImagePullSecret is created
25+
contents=$(kubectl get -n rbac-manager serviceaccount/test-rbac-manager -oyaml | yq 'select(.imagePullSecrets[] | .name == "robot-secret")')
26+
if [ -z "$contents" ]; then
27+
error=$(( error | 1 ))
28+
fi
29+
if [ "$error" -eq 1 ]; then
30+
>&2 echo "error: ImagePullSecret \"robot-secret\" must exists"
31+
fi
32+
33+
# ImagePullSecret is re-created if deleted
34+
cat <<EOF | kubectl patch -n rbac-manager serviceaccount/test-rbac-manager --type=merge -p "$(cat -)"
35+
{
36+
"imagePullSecrets": []
37+
}
38+
EOF
39+
contents=$(kubectl get -n rbac-manager serviceaccount/test-rbac-manager -oyaml | yq 'select(.imagePullSecrets[] | .name == "robot-secret")')
40+
if [ -z "$contents" ]; then
41+
error=$(( error | 1 ))
42+
fi
43+
if [ "$error" -eq 1 ]; then
44+
>&2 echo "error: ImagePullSecret \"robot-secret\" must be re-created"
45+
fi
46+
47+
# If ImagePullSecret is added it should not be removed
48+
49+
cat <<EOF | kubectl patch -n rbac-manager serviceaccount/test-rbac-manager --type=json -p "$(cat -)"
50+
[
51+
{
52+
"op": "add",
53+
"path": "/imagePullSecrets/-",
54+
"value": {
55+
"name": "new-secret-name"
56+
}
57+
}
58+
]
59+
EOF
60+
contents=$(kubectl get -n rbac-manager serviceaccount/test-rbac-manager -oyaml | yq 'select(.imagePullSecrets[] | .name == "new-secret-name")')
61+
if [ -z "$contents" ]; then
62+
error=$(( error | 1 ))
63+
fi
64+
if [ "$error" -eq 1 ]; then
65+
>&2 echo "error: ImagePullSecret \"new-secret-name\" must be kept"
66+
fi
67+
68+
exit $error

Diff for: e2e/test.sh

+5-34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
3+
BASE_DIR=$(dirname $BASH_SOURCE)
44

55
printf "\n\n"
66
echo "**************************"
@@ -20,36 +20,7 @@ printf "\n\n"
2020
kubectl apply -f deploy/
2121
kubectl -n rbac-manager wait deployment/rbac-manager --timeout=120s --for condition=available
2222

23-
24-
printf "\n\n"
25-
echo "********************************************************************"
26-
echo "** Test rbacDefinition **"
27-
echo "********************************************************************"
28-
printf "\n\n"
29-
kubectl create clusterrole test-rbac-manager --verb="create" --resource=deployment
30-
31-
cat <<EOF | kubectl create -f -
32-
apiVersion: rbacmanager.reactiveops.io/v1beta1
33-
kind: RBACDefinition
34-
metadata:
35-
name: rbac-manager-definition
36-
rbacBindings:
37-
- name: admins
38-
subjects:
39-
- kind: ServiceAccount
40-
name: test-rbac-manager
41-
namespace: rbac-manager
42-
clusterRoleBindings:
43-
- clusterRole: test-rbac-manager
44-
EOF
45-
46-
# wait up to 2 minutes for rbac-manager to create the binding
47-
counter=0
48-
until kubectl get clusterrolebinding/rbac-manager-definition-admins-test-rbac-manager; do
49-
let "counter=counter+1"
50-
sleep 10
51-
if [ $counter -gt 11 ]; then
52-
break
53-
fi
54-
done
55-
kubectl auth can-i create deployments --as=system:serviceaccount:rbac-manager:test-rbac-manager
23+
bash "$BASE_DIR/rbacdefinition/run.sh"
24+
if [ $? -ne 0 ]; then
25+
exit 1
26+
fi

Diff for: pkg/reconciler/matcher.go

+28-7
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package reconciler
1616

1717
import (
18-
"reflect"
19-
2018
v1 "k8s.io/api/core/v1"
2119
rbacv1 "k8s.io/api/rbac/v1"
2220
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -53,13 +51,36 @@ func rbMatches(existingRB *rbacv1.RoleBinding, requestedRB *rbacv1.RoleBinding)
5351
}
5452

5553
func saMatches(existingSA *v1.ServiceAccount, requestedSA *v1.ServiceAccount) bool {
56-
if metaMatches(&existingSA.ObjectMeta, &requestedSA.ObjectMeta) {
57-
if len(requestedSA.ImagePullSecrets) < 1 && existingSA.ImagePullSecrets == nil {
58-
return true
54+
if !metaMatches(&existingSA.ObjectMeta, &requestedSA.ObjectMeta) {
55+
return false
56+
}
57+
requestedSAManagedPullSecretsAnnotation, exists := requestedSA.Annotations[ManagedPullSecretsAnnotationKey]
58+
if !exists {
59+
return false
60+
}
61+
62+
existingSAManagedPullSecretsAnnotation, exists := existingSA.Annotations[ManagedPullSecretsAnnotationKey]
63+
if !exists {
64+
return false
65+
}
66+
67+
if requestedSAManagedPullSecretsAnnotation != existingSAManagedPullSecretsAnnotation {
68+
return false
69+
}
70+
71+
for _, requestedSAImagePullSecrets := range requestedSA.ImagePullSecrets {
72+
matches := false
73+
for _, existingSAPullSecret := range existingSA.ImagePullSecrets {
74+
if requestedSAImagePullSecrets.Name == existingSAPullSecret.Name {
75+
matches = true
76+
}
77+
}
78+
if !matches {
79+
return false
5980
}
60-
return reflect.DeepEqual(&existingSA.ImagePullSecrets, &requestedSA.ImagePullSecrets)
6181
}
62-
return false
82+
83+
return true
6384
}
6485

6586
func metaMatches(existingMeta *metav1.ObjectMeta, requestedMeta *metav1.ObjectMeta) bool {

0 commit comments

Comments
 (0)