Initial commit
This commit is contained in:
140
test/bats/helpers.bash
Normal file
140
test/bats/helpers.bash
Normal file
@@ -0,0 +1,140 @@
|
||||
#!/bin/bash
|
||||
|
||||
assert_success() {
|
||||
if [[ "$status" != 0 ]]; then
|
||||
echo "expected: 0"
|
||||
echo "actual: $status"
|
||||
echo "output: $output"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_failure() {
|
||||
if [[ "$status" == 0 ]]; then
|
||||
echo "expected: non-zero exit code"
|
||||
echo "actual: $status"
|
||||
echo "output: $output"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_equal() {
|
||||
if [[ "$1" != "$2" ]]; then
|
||||
echo "expected: $1"
|
||||
echo "actual: $2"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_not_equal() {
|
||||
if [[ "$1" == "$2" ]]; then
|
||||
echo "unexpected: $1"
|
||||
echo "actual: $2"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_match() {
|
||||
if [[ ! "$2" =~ $1 ]]; then
|
||||
echo "expected: $1"
|
||||
echo "actual: $2"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_not_match() {
|
||||
if [[ "$2" =~ $1 ]]; then
|
||||
echo "expected: $1"
|
||||
echo "actual: $2"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_len() {
|
||||
if [[ "$1" != "${#2}" ]]; then
|
||||
echo "expected len: $1"
|
||||
echo "actual len: ${#2} ($2)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_process() {
|
||||
wait_time="$1"
|
||||
sleep_time="$2"
|
||||
cmd="$3"
|
||||
while [ "$wait_time" -gt 0 ]; do
|
||||
if eval "$cmd"; then
|
||||
return 0
|
||||
else
|
||||
sleep "$sleep_time"
|
||||
wait_time=$((wait_time - sleep_time))
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
get_ca_cert() {
|
||||
destination="$1"
|
||||
if [ $(kubectl get secret -n ${GATEKEEPER_NAMESPACE} gatekeeper-webhook-server-cert -o jsonpath='{.data.ca\.crt}' | wc -w) -eq 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
kubectl get secret -n ${GATEKEEPER_NAMESPACE} gatekeeper-webhook-server-cert -o jsonpath='{.data.ca\.crt}' | base64 -d >$destination
|
||||
}
|
||||
|
||||
constraint_enforced() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
local pod_list="$(kubectl -n ${GATEKEEPER_NAMESPACE} get pod -l gatekeeper.sh/operation=webhook -o json)"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error gathering pods"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# ensure pod_count is at least one
|
||||
local pod_count=$(echo "${pod_list}" | jq '.items | length')
|
||||
if [[ ${pod_count} -lt 1 ]]; then
|
||||
echo "Gatekeeper pod count is < 1"
|
||||
return 2
|
||||
fi
|
||||
|
||||
local cstr="$(kubectl get ${kind} ${name} -ojson)"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Error gathering constraint ${kind} ${name}"
|
||||
return 3
|
||||
fi
|
||||
|
||||
echo "checking constraint ${cstr}"
|
||||
|
||||
local ready_count=$(echo "${cstr}" | jq '.metadata.generation as $generation | [.status.byPod[] | select( .operations[] == "webhook" and .observedGeneration == $generation)] | length')
|
||||
echo "ready: ${ready_count}, expected: ${pod_count}"
|
||||
[[ "${ready_count}" -eq "${pod_count}" ]]
|
||||
}
|
||||
|
||||
mutator_enforced() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
local pod_list="$(kubectl -n ${GATEKEEPER_NAMESPACE} get pod -l gatekeeper.sh/operation=webhook -o json)"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error gathering pods"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# ensure pod_count is at least one
|
||||
local pod_count=$(echo "${pod_list}" | jq '.items | length')
|
||||
if [[ ${pod_count} -lt 1 ]]; then
|
||||
echo "Gatekeeper pod count is < 1"
|
||||
return 2
|
||||
fi
|
||||
|
||||
local cstr="$(kubectl get ${kind} ${name} -ojson)"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "Error gathering mutator ${kind} ${name}"
|
||||
return 3
|
||||
fi
|
||||
|
||||
echo "checking mutator ${cstr}"
|
||||
|
||||
local ready_count=$(echo "${cstr}" | jq '.metadata.generation as $generation | [.status.byPod[] | select( .operations[] == "mutation-webhook" and .observedGeneration == $generation)] | length')
|
||||
echo "ready: ${ready_count}, expected: ${pod_count}"
|
||||
[[ "${ready_count}" -eq "${pod_count}" ]]
|
||||
}
|
||||
51
test/bats/test.bats
Normal file
51
test/bats/test.bats
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load helpers
|
||||
|
||||
WAIT_TIME=120
|
||||
SLEEP_TIME=1
|
||||
GATEKEEPER_NAMESPACE=${GATEKEEPER_NAMESPACE:-gatekeeper-system}
|
||||
|
||||
teardown_file() {
|
||||
kubectl delete -f validation/
|
||||
kubectl delete -f mutation/
|
||||
}
|
||||
|
||||
@test "gatekeeper-controller-manager is running" {
|
||||
wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl -n ${GATEKEEPER_NAMESPACE} wait --for=condition=Ready --timeout=60s pod -l control-plane=controller-manager"
|
||||
}
|
||||
|
||||
@test "gatekeeper-audit is running" {
|
||||
wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl -n ${GATEKEEPER_NAMESPACE} wait --for=condition=Ready --timeout=60s pod -l control-plane=audit-controller"
|
||||
}
|
||||
|
||||
@test "external-data-provider is running" {
|
||||
wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl -n ${GATEKEEPER_NAMESPACE} wait --for=condition=Ready --timeout=60s pod -l run=external-data-provider"
|
||||
}
|
||||
|
||||
@test "external data validation" {
|
||||
run kubectl apply -f validation/external-data-provider-constraint-template.yaml
|
||||
assert_success
|
||||
wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced constrainttemplate k8sexternaldatavalidation"
|
||||
|
||||
run kubectl apply -f validation/external-data-provider-constraint.yaml
|
||||
assert_success
|
||||
wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8sexternaldatavalidation deny-images-with-invalid-suffix"
|
||||
|
||||
run kubectl run nginx --image=error_nginx --dry-run=server
|
||||
# should deny pod admission if the image name has an "error_" prefix
|
||||
assert_failure
|
||||
assert_match 'error_nginx' "${output}"
|
||||
assert_match 'error_nginx_invalid' "${output}"
|
||||
}
|
||||
|
||||
@test "external data mutation" {
|
||||
run kubectl apply -f mutation/external-data-provider-mutation.yaml
|
||||
assert_success
|
||||
wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "mutator_enforced Assign append-valid-suffix-to-image"
|
||||
|
||||
run kubectl run nginx --image=nginx --dry-run=server --output json
|
||||
assert_success
|
||||
# should mutate the image field by appending "_valid" suffix
|
||||
assert_match "nginx_valid" "$(jq -r '.spec.containers[0].image' <<< ${output})"
|
||||
}
|
||||
Reference in New Issue
Block a user