Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions e2e-tests/functions
Original file line number Diff line number Diff line change
Expand Up @@ -1143,3 +1143,95 @@ wait_for_generation() {
fi
done
}

# Reads all environment variables from a pod (single kubectl exec call)
get_envs_from_pod() {
local namespace=$1
local pod=$2
local container=$3
Comment on lines +1149 to +1151
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[shfmt] reported by reviewdog 🐶

Suggested change
local namespace=$1
local pod=$2
local container=$3
local namespace=$1
local pod=$2
local container=$3


if [ -n "$container" ]; then
kubectl exec -n "$namespace" "$pod" -c "$container" -- printenv 2>/dev/null || true
else
kubectl exec -n "$namespace" "$pod" -- printenv 2>/dev/null || true
fi
Comment on lines +1153 to +1157
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[shfmt] reported by reviewdog 🐶

Suggested change
if [ -n "$container" ]; then
kubectl exec -n "$namespace" "$pod" -c "$container" -- printenv 2>/dev/null || true
else
kubectl exec -n "$namespace" "$pod" -- printenv 2>/dev/null || true
fi
if [ -n "$container" ]; then
kubectl exec -n "$namespace" "$pod" -c "$container" -- printenv 2>/dev/null || true
else
kubectl exec -n "$namespace" "$pod" -- printenv 2>/dev/null || true
fi

}

# Verifies a single variable in given env content
check_env_in_pod() {
local check_type=$1
local pod=$2
local var_name=$3
local expected_value=$4
local env_content=$5

local actual_value
actual_value=$(echo "$env_content" | grep -E "^${var_name}=" | cut -d'=' -f2- || true)

if [[ "$check_type" == "add" ]]; then
if [ "$actual_value" != "$expected_value" ]; then
echo "ERROR: $var_name in $pod — expected '$expected_value', got '${actual_value:-<missing>}'"
return 1
else
echo "OK: $var_name=$actual_value in $pod"
fi
elif [[ "$check_type" == "delete" ]]; then
if [ -n "$actual_value" ]; then
echo "ERROR: $var_name exists in $pod (should not exist)"
return 1
else
echo "OK: $var_name deleted in $pod"
fi
else
echo "ERROR: unknown check type '$check_type'"
return 1
fi
Comment on lines +1162 to +1188
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[shfmt] reported by reviewdog 🐶

Suggested change
local check_type=$1
local pod=$2
local var_name=$3
local expected_value=$4
local env_content=$5
local actual_value
actual_value=$(echo "$env_content" | grep -E "^${var_name}=" | cut -d'=' -f2- || true)
if [[ "$check_type" == "add" ]]; then
if [ "$actual_value" != "$expected_value" ]; then
echo "ERROR: $var_name in $pod — expected '$expected_value', got '${actual_value:-<missing>}'"
return 1
else
echo "OK: $var_name=$actual_value in $pod"
fi
elif [[ "$check_type" == "delete" ]]; then
if [ -n "$actual_value" ]; then
echo "ERROR: $var_name exists in $pod (should not exist)"
return 1
else
echo "OK: $var_name deleted in $pod"
fi
else
echo "ERROR: unknown check type '$check_type'"
return 1
fi
local check_type=$1
local pod=$2
local var_name=$3
local expected_value=$4
local env_content=$5
local actual_value
actual_value=$(echo "$env_content" | grep -E "^${var_name}=" | cut -d'=' -f2- || true)
if [[ $check_type == "add" ]]; then
if [ "$actual_value" != "$expected_value" ]; then
echo "ERROR: $var_name in $pod — expected '$expected_value', got '${actual_value:-<missing>}'"
return 1
else
echo "OK: $var_name=$actual_value in $pod"
fi
elif [[ $check_type == "delete" ]]; then
if [ -n "$actual_value" ]; then
echo "ERROR: $var_name exists in $pod (should not exist)"
return 1
else
echo "OK: $var_name deleted in $pod"
fi
else
echo "ERROR: unknown check type '$check_type'"
return 1
fi

}

# Checks multiple env vars in one or more components
check_envs_for_component() {
local check_type=$1 # add | delete
local component=$2 # instance | pgbouncer | repohost
local vars=("${@:3}") # everything after the 2nd argument

case "$component" in
instance)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/instance-set=instance1 -o 'jsonpath={.items[0].metadata.name}')
CONTAINER=""
;;
pgbouncer)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/role=pgbouncer -o 'jsonpath={.items[0].metadata.name}')
CONTAINER="pgbouncer"
;;
repohost)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/data=pgbackrest -o 'jsonpath={.items[0].metadata.name}')
CONTAINER="pgbackrest"
;;
*)
echo "ERROR: unknown component '$component'"
return 1
;;
esac

echo "Fetching environment variables for $component pod $POD..."
local env_content
env_content=$(get_envs_from_pod "${NAMESPACE}" "$POD" "$CONTAINER")

local errors=0
for var_entry in "${vars[@]}"; do
if [[ "$check_type" == "add" ]]; then
local var_name="${var_entry%%=*}"
local var_expected="${var_entry#*=}"
check_env_in_pod add "$POD" "$var_name" "$var_expected" "$env_content" || errors=$((errors+1))
else
check_env_in_pod delete "$POD" "$var_entry" "" "$env_content" || errors=$((errors+1))
fi
done

if (( errors > 0 )); then
echo "$errors environment check(s) failed for component '$component'"
return 1
else
echo "All environment checks passed for component '$component'"
fi
}
Comment on lines +1193 to +1237
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[shfmt] reported by reviewdog 🐶

Suggested change
local check_type=$1 # add | delete
local component=$2 # instance | pgbouncer | repohost
local vars=("${@:3}") # everything after the 2nd argument
case "$component" in
instance)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/instance-set=instance1 -o 'jsonpath={.items[0].metadata.name}')
CONTAINER=""
;;
pgbouncer)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/role=pgbouncer -o 'jsonpath={.items[0].metadata.name}')
CONTAINER="pgbouncer"
;;
repohost)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/data=pgbackrest -o 'jsonpath={.items[0].metadata.name}')
CONTAINER="pgbackrest"
;;
*)
echo "ERROR: unknown component '$component'"
return 1
;;
esac
echo "Fetching environment variables for $component pod $POD..."
local env_content
env_content=$(get_envs_from_pod "${NAMESPACE}" "$POD" "$CONTAINER")
local errors=0
for var_entry in "${vars[@]}"; do
if [[ "$check_type" == "add" ]]; then
local var_name="${var_entry%%=*}"
local var_expected="${var_entry#*=}"
check_env_in_pod add "$POD" "$var_name" "$var_expected" "$env_content" || errors=$((errors+1))
else
check_env_in_pod delete "$POD" "$var_entry" "" "$env_content" || errors=$((errors+1))
fi
done
if (( errors > 0 )); then
echo "$errors environment check(s) failed for component '$component'"
return 1
else
echo "All environment checks passed for component '$component'"
fi
}
local check_type=$1 # add | delete
local component=$2 # instance | pgbouncer | repohost
local vars=("${@:3}") # everything after the 2nd argument
case "$component" in
instance)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/instance-set=instance1 -o 'jsonpath={.items[0].metadata.name}')
CONTAINER=""
;;
pgbouncer)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/role=pgbouncer -o 'jsonpath={.items[0].metadata.name}')
CONTAINER="pgbouncer"
;;
repohost)
POD=$(kubectl get -n "${NAMESPACE}" pod -l postgres-operator.crunchydata.com/data=pgbackrest -o 'jsonpath={.items[0].metadata.name}')
CONTAINER="pgbackrest"
;;
*)
echo "ERROR: unknown component '$component'"
return 1
;;
esac
echo "Fetching environment variables for $component pod $POD..."
local env_content
env_content=$(get_envs_from_pod "${NAMESPACE}" "$POD" "$CONTAINER")
local errors=0
for var_entry in "${vars[@]}"; do
if [[ $check_type == "add" ]]; then
local var_name="${var_entry%%=*}"
local var_expected="${var_entry#*=}"
check_env_in_pod add "$POD" "$var_name" "$var_expected" "$env_content" || errors=$((errors + 1))
else
check_env_in_pod delete "$POD" "$var_entry" "" "$env_content" || errors=$((errors + 1))
fi
done
if ((errors > 0)); then
echo "$errors environment check(s) failed for component '$component'"
return 1
else
echo "All environment checks passed for component '$component'"
fi
}

1 change: 1 addition & 0 deletions e2e-tests/run-pr.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
backup-enable-disable
custom-envs
custom-extensions
custom-tls
database-init-sql
Expand Down
1 change: 1 addition & 0 deletions e2e-tests/run-release.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
backup-enable-disable
custom-envs
custom-extensions
custom-tls
database-init-sql
Expand Down
24 changes: 24 additions & 0 deletions e2e-tests/tests/custom-envs/00-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 120
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: perconapgclusters.pgv2.percona.com
spec:
group: pgv2.percona.com
names:
kind: PerconaPGCluster
listKind: PerconaPGClusterList
plural: perconapgclusters
singular: perconapgcluster
scope: Namespaced
---
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
metadata:
name: check-operator-deploy-status
timeout: 120
commands:
- script: kubectl assert exist-enhanced deployment percona-postgresql-operator -n ${OPERATOR_NS:-$NAMESPACE} --field-selector status.readyReplicas=1
14 changes: 14 additions & 0 deletions e2e-tests/tests/custom-envs/00-deploy-operator.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
timeout: 10
commands:
- script: |-
set -o errexit
set -o xtrace

source ../../functions
init_temp_dir # do this only in the first TestStep

deploy_operator
deploy_client
deploy_s3_secrets
106 changes: 106 additions & 0 deletions e2e-tests/tests/custom-envs/01-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 120
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
labels:
postgres-operator.crunchydata.com/cluster: custom-envs
postgres-operator.crunchydata.com/data: postgres
postgres-operator.crunchydata.com/instance-set: instance1
ownerReferences:
- apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
name: custom-envs
controller: true
blockOwnerDeletion: true
status:
observedGeneration: 1
replicas: 1
readyReplicas: 1
currentReplicas: 1
updatedReplicas: 1
collisionCount: 0
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: custom-envs-pgbouncer
labels:
postgres-operator.crunchydata.com/cluster: custom-envs
postgres-operator.crunchydata.com/role: pgbouncer
annotations:
deployment.kubernetes.io/revision: '1'
ownerReferences:
- apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
name: custom-envs
controller: true
blockOwnerDeletion: true
status:
observedGeneration: 1
replicas: 1
updatedReplicas: 1
readyReplicas: 1
---
kind: Job
apiVersion: batch/v1
metadata:
labels:
postgres-operator.crunchydata.com/cluster: custom-envs
postgres-operator.crunchydata.com/pgbackrest: ''
postgres-operator.crunchydata.com/pgbackrest-backup: replica-create
postgres-operator.crunchydata.com/pgbackrest-repo: repo1
ownerReferences:
- apiVersion: pgv2.percona.com/v2
kind: PerconaPGBackup
controller: true
blockOwnerDeletion: true
status:
succeeded: 1
---
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: custom-envs
ownerReferences:
- apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
name: custom-envs
controller: true
blockOwnerDeletion: true
finalizers:
- postgres-operator.crunchydata.com/finalizer
status:
instances:
- name: instance1
readyReplicas: 1
replicas: 1
updatedReplicas: 1
observedGeneration: 1
pgbackrest:
repos:
- name: repo1
stanzaCreated: true
proxy:
pgBouncer:
readyReplicas: 1
replicas: 1
---
apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
name: custom-envs
status:
pgbouncer:
ready: 1
size: 1
postgres:
instances:
- name: instance1
ready: 1
size: 1
ready: 1
size: 1
state: ready
15 changes: 15 additions & 0 deletions e2e-tests/tests/custom-envs/01-create-cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
timeout: 20
commands:
- script: |-
set -o errexit
set -o xtrace

source ../../functions

get_cr \
| yq eval '
.spec.proxy.pgBouncer.replicas=1 |
.spec.instances[].replicas=1' - \
| kubectl -n "${NAMESPACE}" apply -f -
21 changes: 21 additions & 0 deletions e2e-tests/tests/custom-envs/02-add-env-to-instance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
timeout: 10
commands:
- script: |-
set -o errexit
set -o xtrace

source ../../functions
get_cr | yq eval '
.spec.proxy.pgBouncer.replicas = 1 |
.spec.instances[].replicas = 1 |
.spec.instances[].env = ((.spec.instances[].env // []) + [{"name": "FIRST_ENV", "value": "1000"}, {"name": "SECOND_ENV", "value": "2000"}] | unique_by(.name))
' - | kubectl -n "${NAMESPACE}" apply -f -


sleep 10
wait_cluster_consistency custom-envs

check_envs_for_component add instance FIRST_ENV=1000 SECOND_ENV=2000

48 changes: 48 additions & 0 deletions e2e-tests/tests/custom-envs/02-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 120
---
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: custom-envs
ownerReferences:
- apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
name: custom-envs
controller: true
blockOwnerDeletion: true
finalizers:
- postgres-operator.crunchydata.com/finalizer
status:
instances:
- name: instance1
readyReplicas: 1
replicas: 1
updatedReplicas: 1
observedGeneration: 2
pgbackrest:
repos:
- name: repo1
stanzaCreated: true
proxy:
pgBouncer:
readyReplicas: 1
replicas: 1
---
apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
name: custom-envs
status:
pgbouncer:
ready: 1
size: 1
postgres:
instances:
- name: instance1
ready: 1
size: 1
ready: 1
size: 1
state: ready
48 changes: 48 additions & 0 deletions e2e-tests/tests/custom-envs/03-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 120
---
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: custom-envs
ownerReferences:
- apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
name: custom-envs
controller: true
blockOwnerDeletion: true
finalizers:
- postgres-operator.crunchydata.com/finalizer
status:
instances:
- name: instance1
readyReplicas: 1
replicas: 1
updatedReplicas: 1
observedGeneration: 3
pgbackrest:
repos:
- name: repo1
stanzaCreated: true
proxy:
pgBouncer:
readyReplicas: 1
replicas: 1
---
apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
name: custom-envs
status:
pgbouncer:
ready: 1
size: 1
postgres:
instances:
- name: instance1
ready: 1
size: 1
ready: 1
size: 1
state: ready
Loading
Loading