Skip to content

Commit

Permalink
add dockerconfigjson basicauth
Browse files Browse the repository at this point in the history
  • Loading branch information
rohit010pa committed May 29, 2024
1 parent 5f6daa0 commit 00011ce
Show file tree
Hide file tree
Showing 5 changed files with 286 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
kind: Pod
apiVersion: v1
metadata:
name: secrets-store-inline-basicauth-sync-rotate
spec:
containers:
- image: registry.k8s.io/e2e-test-images/busybox:1.29-4
name: busybox
imagePullPolicy: IfNotPresent
command:
- "/bin/sleep"
- "10000"
env:
- name: SECRET_BASICAUTH
valueFrom:
secretKeyRef:
name: basicauthsecret
key: username
name: basicauthsecret
key: password
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "vault-basicauth-sync-rotate"
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
kind: Pod
apiVersion: v1
metadata:
name: secrets-store-inline-dockerconfigjson-sync-rotate
spec:
containers:
- image: registry.k8s.io/e2e-test-images/busybox:1.29-4
name: busybox
imagePullPolicy: IfNotPresent
command:
- "/bin/sleep"
- "10000"
env:
- name: SECRET_DOCKERCONFIGJSON
valueFrom:
secretKeyRef:
name: dockerconfigjsonsecret
key: .dockerconfigjson
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "vault-dockerconfigjson-sync-rotate"
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: vault-basicauth-sync-rotate
spec:
provider: vault
secretObjects:
- secretName: basicauthsecret
type: kubernetes.io/basic-auth
labels:
environment: "test"
annotations:
kubed.appscode.com/sync: "app=test"
data:
- key: username
objectName: db-basicauth-username
- key: password
objectName: db-basicauth-password
parameters:
vaultAddress: "http://vault.vault:8200"
roleName: "csi"
objects: |
- objectName: db-basicauth-username
secretPath: secret/data/db-basicauth
secretKey: username
- objectName: db-basicauth-password
secretPath: secret/data/db-basicauth
secretKey: password
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: vault-dockerconfigjson-sync-rotate
spec:
provider: vault
secretObjects:
- secretName: dockerconfigjsonsecret
type: kubernetes.io/dockerconfigjson
labels:
environment: "test"
annotations:
kubed.appscode.com/sync: "app=test"
data:
- objectName: dockerconfigjson
key: .dockerconfigjson
parameters:
vaultAddress: "http://vault.vault:8200"
roleName: "csi"
objects: |
- objectName: dockerconfigjson
secretPath: secret/data/db-dockerconfigjson
secretKey: .dockerconfigjson
178 changes: 175 additions & 3 deletions test/bats/vault.bats
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ SLEEP_TIME=1
export LABEL_VALUE=${LABEL_VALUE:-"test"}
export ANNOTATION_VALUE=${ANNOTATION_VALUE:-"app=test"}

export CSI_DRIVER_INSTANNED_NAMESPACE=${CSI_DRIVER_INSTANNED_NAMESPACE:-"kube-system"}
export LABEL_NAMESPACE={LABEL_NAMESPACE:-"app=secrets-store-csi-driver"}
export CSI_DRIVER_CONTAINER_NAME=${CSI_DRIVER_CONTAINER_NAME:-"secret-store"}

dockerexpectedvalue="{\"auths\": {\"https://index.docker.io/v1/\": {\"username\": \"tiger\",\"password\": \"pass1234\",\"email\": \"[email protected]\",\"auth\": \"dGlnZXI6cGFzczEyMzQ=\"}}}"

@test "install vault provider" {
# create the ns vault
kubectl create ns vault
Expand All @@ -29,6 +35,8 @@ export ANNOTATION_VALUE=${ANNOTATION_VALUE:-"app=test"}
# create the kv pair in vault
kubectl exec vault-0 --namespace=vault -- vault kv put secret/foo bar=hello
kubectl exec vault-0 --namespace=vault -- vault kv put secret/foo1 bar1=hello1
kubectl exec vault-0 --namespace=vault -- vault kv put secret/db-basicauth username="db-secret-username" password="db-secret-password"
kubectl exec vault-0 --namespace=vault -- vault kv put secret/db-dockerconfigjson .dockerconfigjson="$dockerexpectedvalue"

# enable authentication
kubectl exec vault-0 --namespace=vault -- vault auth enable kubernetes
Expand Down Expand Up @@ -100,7 +108,7 @@ EOF
# update the secret value
kubectl exec vault-0 --namespace=vault -- vault kv put secret/rotation foo=rotated

sleep 60
sleep 90

# verify rotated value
result=$(kubectl exec secrets-store-rotation -- cat /mnt/secrets-store/foo)
Expand All @@ -125,7 +133,7 @@ EOF
# On Windows, the failed unmount calls from: https://github.com/kubernetes-sigs/secrets-store-csi-driver/pull/545
# do not prevent the pod from being deleted. Search through the driver logs
# for the error.
run bash -c "kubectl logs -l app=secrets-store-csi-driver --tail -1 -c secrets-store -n kube-system | grep '^E.*failed to clean and unmount target path.*$'"
run bash -c "kubectl logs -l $LABEL_NAMESPACE --tail -1 -c $CSI_DRIVER_CONTAINER_NAME -n $CSI_DRIVER_INSTANNED_NAMESPACE | grep '^E.*failed to clean and unmount target path.*$'"
assert_failure
}

Expand Down Expand Up @@ -304,9 +312,173 @@ EOF
[[ "$result" == "hello1" ]]

run wait_for_process $WAIT_TIME $SLEEP_TIME "compare_owner_count foosecret-1 default 1"
assert_success
}

@test "Sync,rotate with basicauth K8s secrets - create deployment" {
kubectl apply -f $BATS_TESTS_DIR/vault_v1_secretproviderclass_basicauth_sync_rotate.yaml
kubectl wait --for condition=established --timeout=60s crd/secretproviderclasses.secrets-store.csi.x-k8s.io

cmd="kubectl get secretproviderclasses.secrets-store.csi.x-k8s.io/vault-basicauth-sync-rotate -o yaml | grep vault"
wait_for_process $WAIT_TIME $SLEEP_TIME "$cmd"

kubectl apply -f $BATS_TESTS_DIR/pod-vault-inline-volume-secretproviderclass-basicauth-sync-rotate.yaml
# wait for pod to be running
kubectl wait --for=condition=Ready --timeout=60s pod/secrets-store-inline-basicauth-sync-rotate

run kubectl get pod/secrets-store-inline-basicauth-sync-rotate
assert_success
}

@test "Sync with basicauth K8s secrets - read vault secret from pod and basicauth secret" {
username=$(kubectl exec secrets-store-inline-basicauth-sync-rotate -- cat /mnt/secrets-store/db-basicauth-username )
[[ "$username" == "db-secret-username" ]]

password=$(kubectl exec secrets-store-inline-basicauth-sync-rotate -- cat /mnt/secrets-store/db-basicauth-password )
[[ "$password" == "db-secret-password" ]]

username=$(kubectl get secrets/basicauthsecret -o=jsonpath="{.data.username}" | base64 -d)
[[ "$username" == "db-secret-username" ]]

password=$(kubectl get secrets/basicauthsecret -o=jsonpath="{.data.password}" | base64 -d)
[[ "$password" == "db-secret-password" ]]

result=$(kubectl exec secrets-store-inline-basicauth-sync-rotate -- printenv | grep SECRET_BASICAUTH | awk -F"=" '{ print $2 }' | tr -d '\r\n')
[[ "$result" == "db-secret-password" ]]

result=$(kubectl get secret basicauthsecret -o jsonpath="{.metadata.labels.environment}")
[[ "${result//$'\r'}" == "${LABEL_VALUE}" ]]

result=$(kubectl get secret basicauthsecret -o jsonpath="{.metadata.annotations.kubed\.appscode\.com\/sync}")
[[ "${result//$'\r'}" == "${ANNOTATION_VALUE}" ]]

result=$(kubectl get secret basicauthsecret -o jsonpath="{.metadata.labels.secrets-store\.csi\.k8s\.io/managed}")
[[ "${result//$'\r'}" == "true" ]]

run wait_for_process $WAIT_TIME $SLEEP_TIME "compare_owner_count basicauthsecret default 1"
assert_success
}

@test "Rotate with basicauth K8s secrets - read vault secret from pod and basicauth secret" {
# update the secret value
kubectl exec vault-0 --namespace=vault -- vault kv put secret/db-basicauth username="db-secret-username-rotated" password="db-secret-password-rotated"

sleep 120

# verify rotated value
username=$(kubectl get secrets/basicauthsecret -o=jsonpath="{.data.username}" | base64 -d)
[[ "$username" == "db-secret-username-rotated" ]]

password=$(kubectl get secrets/basicauthsecret -o=jsonpath="{.data.password}" | base64 -d)
[[ "$password" == "db-secret-password-rotated" ]]

username=$(kubectl exec secrets-store-inline-basicauth-sync-rotate -- cat /mnt/secrets-store/db-basicauth-username )
[[ "$username" == "db-secret-username-rotated" ]]

password=$(kubectl exec secrets-store-inline-basicauth-sync-rotate -- cat /mnt/secrets-store/db-basicauth-password )
[[ "$password" == "db-secret-password-rotated" ]]
}

@test "Sync,rotate with basicauth K8s secrets - unmount succeeds, secret gets deleted" {
run kubectl delete pod secrets-store-inline-basicauth-sync-rotate
assert_success

run kubectl wait --for=delete --timeout=${WAIT_TIME}s pod/secrets-store-inline-basicauth-sync-rotate
assert_success

# Sleep to allow time for logs to propagate.
sleep 10

# save debug information to archive in case of failure
archive_info

run bash -c "kubectl logs -l $LABEL_NAMESPACE --tail 50 -c $CSI_DRIVER_CONTAINER_NAME -n $CSI_DRIVER_INSTANNED_NAMESPACE | grep '^E.*failed to clean and unmount target path.*$'"
assert_failure

run kubectl delete -f $BATS_TESTS_DIR/vault_v1_secretproviderclass_basicauth_sync_rotate.yaml
assert_success

run wait_for_process $WAIT_TIME $SLEEP_TIME "check_secret_deleted basicauthsecret"
assert_success
}

@test "Sync,rotate with dockerconfigjson K8s secrets - create deployment" {
kubectl apply -f $BATS_TESTS_DIR/vault_v1_secretproviderclass_dockerconfigjson_sync_rotate.yaml
kubectl wait --for condition=established --timeout=60s crd/secretproviderclasses.secrets-store.csi.x-k8s.io

cmd="kubectl get secretproviderclasses.secrets-store.csi.x-k8s.io/vault-dockerconfigjson-sync-rotate -o yaml | grep vault"
wait_for_process $WAIT_TIME $SLEEP_TIME "$cmd"

kubectl apply -f $BATS_TESTS_DIR/pod-vault-inline-volume-secretproviderclass-dockerconfigjson-sync-rotate.yaml
# wait for pod to be running
kubectl wait --for=condition=Ready --timeout=60s pod/secrets-store-inline-dockerconfigjson-sync-rotate

run kubectl get pod/secrets-store-inline-dockerconfigjson-sync-rotate
assert_success
}

@test "Sync with dockerconfigjson K8s secrets - read vault secret from pod and dockerconfigjson secret" {
dockeroutputvalue=$(kubectl exec secrets-store-inline-dockerconfigjson-sync-rotate -- cat /mnt/secrets-store/dockerconfigjson)
[[ "$dockeroutputvalue" == "$dockerexpectedvalue" ]]

dockeroutputvalue=$(kubectl get secrets/dockerconfigjsonsecret -o=jsonpath="{.data.\.dockerconfigjson}" | base64 -d)
[[ "$dockeroutputvalue" == "$dockerexpectedvalue" ]]

result=$(kubectl exec secrets-store-inline-dockerconfigjson-sync-rotate -- printenv | grep SECRET_DOCKERCONFIGJSON | awk -F"=" '{ print $2 }' | grep "username" )
[[ "$result" != "" ]]

result=$(kubectl get secret dockerconfigjsonsecret -o jsonpath="{.metadata.labels.environment}")
[[ "${result//$'\r'}" == "${LABEL_VALUE}" ]]

result=$(kubectl get secret dockerconfigjsonsecret -o jsonpath="{.metadata.annotations.kubed\.appscode\.com\/sync}")
[[ "${result//$'\r'}" == "${ANNOTATION_VALUE}" ]]

result=$(kubectl get secret dockerconfigjsonsecret -o jsonpath="{.metadata.labels.secrets-store\.csi\.k8s\.io/managed}")
[[ "${result//$'\r'}" == "true" ]]

run wait_for_process $WAIT_TIME $SLEEP_TIME "compare_owner_count dockerconfigjsonsecret default 1"
assert_success
}

@test "Rotate with dockerconfigjson K8s secrets - read vault secret from pod and dockerconfigjson secret" {
dockerrotateexpectedvalue="{\"auths\": {\"https://index.docker.io/v1/\": {\"username\": \"tiger-rotated\",\"password\": \"pass1234-rotated\",\"email\": \"[email protected]\",\"auth\": \"dGlnZXI6cGFzczEyMzQ=\"}}}"

# update the secret value
kubectl exec vault-0 --namespace=vault -- vault kv put secret/db-dockerconfigjson .dockerconfigjson="{\"auths\": {\"https://index.docker.io/v1/\": {\"username\": \"tiger-rotated\",\"password\": \"pass1234-rotated\",\"email\": \"[email protected]\",\"auth\": \"dGlnZXI6cGFzczEyMzQ=\"}}}"

sleep 120

# verify rotated value
dockeroutputvalue=$(kubectl get secrets/dockerconfigjsonsecret -o=jsonpath="{.data.\.dockerconfigjson}" | base64 -d)
[[ "$dockeroutputvalue" == "$dockerrotateexpectedvalue" ]]

dockeroutputvalue=$(kubectl exec secrets-store-inline-dockerconfigjson-sync-rotate -- cat /mnt/secrets-store/dockerconfigjson)
[[ "$dockeroutputvalue" == "$dockerrotateexpectedvalue" ]]
}

@test "Sync,rotate with dockerconfigjson K8s secrets - unmount succeeds, secret gets deleted" {
run kubectl delete pod secrets-store-inline-dockerconfigjson-sync-rotate
assert_success

run kubectl wait --for=delete --timeout=${WAIT_TIME}s pod/secrets-store-inline-dockerconfigjson-sync-rotate
assert_success

# Sleep to allow time for logs to propagate.
sleep 10

# save debug information to archive in case of failure
archive_info

run bash -c "kubectl logs -l $LABEL_NAMESPACE --tail 50 -c $CSI_DRIVER_CONTAINER_NAME -n $CSI_DRIVER_INSTANNED_NAMESPACE | grep '^E.*failed to clean and unmount target path.*$'"
assert_failure

run kubectl delete -f $BATS_TESTS_DIR/vault_v1_secretproviderclass_dockerconfigjson_sync_rotate.yaml
assert_success

run wait_for_process $WAIT_TIME $SLEEP_TIME "check_secret_deleted dockerconfigjsonsecret"
assert_success
}

teardown_file() {
archive_info || true
}
}

0 comments on commit 00011ce

Please sign in to comment.