-
Notifications
You must be signed in to change notification settings - Fork 176
test: EKS add-on support #601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d8dc3f6
337e6d1
7c7c822
efc75d6
24c4458
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,8 @@ | ||||||||||||||||||||||||||||||||||||
| secrets-store-csi-driver: | ||||||||||||||||||||||||||||||||||||
| enableSecretRotation: true | ||||||||||||||||||||||||||||||||||||
| rotationPollInterval: "15s" | ||||||||||||||||||||||||||||||||||||
| syncSecret: | ||||||||||||||||||||||||||||||||||||
| enabled: true | ||||||||||||||||||||||||||||||||||||
| tokenRequests: | ||||||||||||||||||||||||||||||||||||
| - audience: "sts.amazonaws.com" | ||||||||||||||||||||||||||||||||||||
| - audience: "pods.eks.amazonaws.com" | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+8
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Two things worth pinning down here. 1. Add
Suggested change
Related: EKS validates 2. Drift risk (follow-up, not this PR). All five settings now exist in two syntaxes with nothing linking them: this YAML and the The |
||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -232,7 +232,12 @@ def get_auth_setup(arch: str, auth_type: str) -> str: | |
| --approve \\ | ||
| --region $REGION""" | ||
|
|
||
| return f""" log "Creating EKS Pod Identity addon" | ||
| return f""" if [[ -z "${{POD_IDENTITY_ROLE_ARN}}" ]]; then | ||
| echo "Error: POD_IDENTITY_ROLE_ARN is not set" >&2 | ||
| return 1 | ||
| fi | ||
|
Comment on lines
+235
to
+238
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Good check, but it fires ~15-20 minutes and one EKS cluster too late. This lands at the So Since if [[ "{{AUTH_TYPE}}" == "pod-identity" && -z "${POD_IDENTITY_ROLE_ARN}" ]]; then
echo "Error: POD_IDENTITY_ROLE_ARN is not specified" >&2
return 1
fiThat also gets the shell out of the f-string (no |
||
|
|
||
| log "Creating EKS Pod Identity addon" | ||
| eksctl create addon --name eks-pod-identity-agent --cluster $CLUSTER_NAME --region $REGION | ||
|
|
||
| log "Creating Pod Identity association" | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -21,23 +21,25 @@ log() { | |||||||||
| echo -e "${{{LOG_COLOR}}}[$TIMESTAMP] [{{ARCH}}-{{AUTH_TYPE}}] $msg${NC}" >&3 | ||||||||||
| } | ||||||||||
|
|
||||||||||
| if [[ -z "${PRIVREPO}" ]]; then | ||||||||||
| echo "Error: PRIVREPO is not specified" >&2 | ||||||||||
| return 1 | ||||||||||
| fi | ||||||||||
|
|
||||||||||
| # GHCR pull credentials are only required when running inside GitHub Actions, | ||||||||||
| # where the provider image lives in a private GHCR repo. Local runs pull from | ||||||||||
| # whatever PRIVREPO points at and skip the GHCR pull-secret entirely. | ||||||||||
| if [[ "${GITHUB_ACTIONS}" == "true" ]]; then | ||||||||||
| if [[ -z "${GITHUB_ACTOR}" ]]; then | ||||||||||
| echo "Error: GITHUB_ACTOR is not specified" >&2 | ||||||||||
| if [[ "${INSTALL_METHOD}" != "addon" ]]; then | ||||||||||
| if [[ -z "${PRIVREPO}" ]]; then | ||||||||||
| echo "Error: PRIVREPO is not specified" >&2 | ||||||||||
| return 1 | ||||||||||
| fi | ||||||||||
|
|
||||||||||
| if [[ -z "${GITHUB_TOKEN}" ]]; then | ||||||||||
| echo "Error: GITHUB_TOKEN is not specified" >&2 | ||||||||||
| return 1 | ||||||||||
| # GHCR pull credentials are only required when running inside GitHub Actions, | ||||||||||
| # where the provider image lives in a private GHCR repo. Local runs pull from | ||||||||||
| # whatever PRIVREPO points at and skip the GHCR pull-secret entirely. | ||||||||||
| if [[ "${GITHUB_ACTIONS}" == "true" ]]; then | ||||||||||
| if [[ -z "${GITHUB_ACTOR}" ]]; then | ||||||||||
| echo "Error: GITHUB_ACTOR is not specified" >&2 | ||||||||||
| return 1 | ||||||||||
| fi | ||||||||||
|
|
||||||||||
| if [[ -z "${GITHUB_TOKEN}" ]]; then | ||||||||||
| echo "Error: GITHUB_TOKEN is not specified" >&2 | ||||||||||
| return 1 | ||||||||||
| fi | ||||||||||
| fi | ||||||||||
| fi | ||||||||||
|
|
||||||||||
|
|
@@ -66,17 +68,25 @@ setup_file() { | |||||||||
|
|
||||||||||
| {{AUTH_SETUP}} | ||||||||||
|
|
||||||||||
| if [[ "${GITHUB_ACTIONS}" == "true" ]]; then | ||||||||||
| log "Create GHCR secret" | ||||||||||
| KUBECONFIG=${{KUBECONFIG_VAR}} kubectl create secret docker-registry ghcr-secret --docker-server=ghcr.io --docker-username=$GITHUB_ACTOR --docker-password=$GITHUB_TOKEN -n $NAMESPACE | ||||||||||
| if [[ "${INSTALL_METHOD}" == "addon" ]]; then | ||||||||||
| log "Installing aws-secrets-store-csi-driver-provider as EKS addon" | ||||||||||
| aws eks create-addon --cluster-name $CLUSTER_NAME --addon-name aws-secrets-store-csi-driver-provider \ | ||||||||||
| --configuration-values file://addon_config_values.yaml ${ADDON_VERSION:+--addon-version $ADDON_VERSION} --region $REGION | ||||||||||
| aws eks wait addon-active --cluster-name $CLUSTER_NAME --addon-name aws-secrets-store-csi-driver-provider --region $REGION | ||||||||||
|
Comment on lines
+71
to
+75
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Three gaps in the addon install branch relative to the Helm branch it replaces. 1. Nothing installs or verifies the CSI driver. The 2. No readiness gate. The Helm path had kubectl --kubeconfig=${{KUBECONFIG_VAR}} -n $NAMESPACE rollout status daemonset -l app=secrets-store-csi-driver-provider-aws --timeout=120s3. Also note (not a defect, but worth stating in the README — see my comment there): |
||||||||||
| else | ||||||||||
| # GHCR pull-secret is only needed inside GitHub Actions (private GHCR repo). | ||||||||||
| if [[ "${GITHUB_ACTIONS}" == "true" ]]; then | ||||||||||
| log "Create GHCR secret" | ||||||||||
| KUBECONFIG=${{KUBECONFIG_VAR}} kubectl create secret docker-registry ghcr-secret --docker-server=ghcr.io --docker-username=$GITHUB_ACTOR --docker-password=$GITHUB_TOKEN -n $NAMESPACE | ||||||||||
| fi | ||||||||||
|
|
||||||||||
| log "Adding secrets-store-csi-driver Helm repository" | ||||||||||
| helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts | ||||||||||
|
|
||||||||||
| log "Installing secrets-store-csi-driver via Helm" | ||||||||||
| KUBECONFIG=${{KUBECONFIG_VAR}} helm --namespace=$NAMESPACE install --wait --wait-for-jobs --timeout=30s csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --set enableSecretRotation=true --set rotationPollInterval=15s --set syncSecret.enabled=true --set tokenRequests[0].audience=sts.amazonaws.com --set tokenRequests[1].audience=pods.eks.amazonaws.com | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, for a followup, (you don't have to do it in this PR, and you don't have to be the one to do it): We might as well install the provider here through the helm chart and install the driver as a Helm dependency instead of in two separate steps. We just have to pass the config options we're passing here to the underlying driver chart. That way the addon and the provider flows are more similar. |
||||||||||
| fi | ||||||||||
|
|
||||||||||
| log "Adding secrets-store-csi-driver Helm repository" | ||||||||||
| helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts | ||||||||||
|
|
||||||||||
| log "Installing secrets-store-csi-driver via Helm" | ||||||||||
| KUBECONFIG=${{KUBECONFIG_VAR}} helm --namespace=$NAMESPACE install --wait --wait-for-jobs --timeout=30s csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --set enableSecretRotation=true --set rotationPollInterval=15s --set syncSecret.enabled=true --set tokenRequests[0].audience=sts.amazonaws.com --set tokenRequests[1].audience=pods.eks.amazonaws.com | ||||||||||
|
|
||||||||||
| log "Cluster setup completed for $CLUSTER_NAME" | ||||||||||
| } | ||||||||||
|
|
||||||||||
|
|
@@ -121,6 +131,10 @@ validate_jmes_mount() { | |||||||||
| } | ||||||||||
|
|
||||||||||
| @test "Install aws provider" { | ||||||||||
| if [[ "${INSTALL_METHOD}" == "addon" ]]; then | ||||||||||
| skip "Provider installed as EKS addon" | ||||||||||
| fi | ||||||||||
|
Comment on lines
+134
to
+136
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Blocking: this is the only Helm-dependent test that got the guard — addon mode can't pass. Two other Helm-only blocks were missed (both outside the diff, so I can't anchor there):
In
Given the PR description says all tests passed under Rather than a third copy of the inline skip_if_addon() {
[[ "${INSTALL_METHOD}" == "addon" ]] && skip "provider installed as EKS addon"
}Alternatively, toggle Separately: skipping this test also drops the only assertion that the provider actually rolled out (L156-158) — see my comment on L71. |
||||||||||
|
|
||||||||||
| log "Installing AWS provider" | ||||||||||
|
|
||||||||||
| KUBECONFIG=${{KUBECONFIG_VAR}} helm package --dependency-update ../charts/secrets-store-csi-driver-provider-aws | ||||||||||
|
|
@@ -149,8 +163,11 @@ validate_jmes_mount() { | |||||||||
| @test "Verify serviceaccounts/token create permission is not granted to provider" { | ||||||||||
| log "Verifying provider ClusterRole does not grant serviceaccounts/token create permission" | ||||||||||
|
|
||||||||||
| # Find the provider ClusterRole (name varies between Helm and addon installs) | ||||||||||
| PROVIDER_CLUSTER_ROLE=$(kubectl --kubeconfig=${{KUBECONFIG_VAR}} get clusterrole -o json | jq -r '.items[].metadata.name | select(test("provider.*cluster-role"))' | head -1) | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor robustness: if the [[ -n "$PROVIDER_CLUSTER_ROLE" ]] || fail "Could not locate provider ClusterRole"
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor robustness: if the [[ -n "$PROVIDER_CLUSTER_ROLE" ]] || fail "Could not locate provider ClusterRole"
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 The lookup can silently make this security assertion vacuous. (Re-raising @simonmarty's Three failure modes, none of which report the real cause:
The chart already gives you a name-independent handle:
Suggested change
If you'd rather keep the regex, the Nit while you're here: the |
||||||||||
|
|
||||||||||
| # Check the provider's own ClusterRole for serviceaccounts/token create permission | ||||||||||
| run bash -c "kubectl --kubeconfig=${{KUBECONFIG_VAR}} -n $NAMESPACE get clusterrole csi-secrets-store-provider-aws-secrets-store-csi-driver-provide-cluster-role -o json | jq -e '[.rules[] | select((.resources[]? == \"serviceaccounts/token\") and (.verbs[]? == \"create\"))] | length == 0'" | ||||||||||
| run bash -c "kubectl --kubeconfig=${{KUBECONFIG_VAR}} -n $NAMESPACE get clusterrole $PROVIDER_CLUSTER_ROLE -o json | jq -e '[.rules[] | select((.resources[]? == \"serviceaccounts/token\") and (.verbs[]? == \"create\"))] | length == 0'" | ||||||||||
| assert_success | ||||||||||
|
|
||||||||||
| log "Verified: Provider ClusterRole does not grant serviceaccounts/token create permission" | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -38,6 +38,35 @@ delete_cluster() { | |||||||||||||||||||||||||
| eksctl delete cluster --name $1 --parallel 25 | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Parse --addon and --addon-version flags from any position | ||||||||||||||||||||||||||
| REMAINING_ARGS=() | ||||||||||||||||||||||||||
| while [[ $# -gt 0 ]]; do | ||||||||||||||||||||||||||
| case "$1" in | ||||||||||||||||||||||||||
| --addon) | ||||||||||||||||||||||||||
| export INSTALL_METHOD=addon | ||||||||||||||||||||||||||
| shift | ||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||
| --addon-version) | ||||||||||||||||||||||||||
|
ThirdEyeSqueegee marked this conversation as resolved.
|
||||||||||||||||||||||||||
| if [[ -z "$2" || "$2" == --* ]]; then | ||||||||||||||||||||||||||
| echo "Error: --addon-version requires a value" >&2 | ||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||
| export ADDON_VERSION="$2" | ||||||||||||||||||||||||||
| shift 2 | ||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||
| *) | ||||||||||||||||||||||||||
| REMAINING_ARGS+=("$1") | ||||||||||||||||||||||||||
| shift | ||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||
|
Comment on lines
+57
to
+60
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The catch-all makes a typo'd flag a silent green run. Unrecognized flags fall into $ ./run-tests.sh --addon-verison v1 x64-irsa # or --addons, or --addon=true
Generating test files...
Test files generated successfully
Cleaning up...
$ echo $?
0In CI that's a green integration-tests check on a build where the suite never ran. The This state was unreachable before — adding flags is what makes it easy to hit. Rejecting unknown options here is half the fix:
Suggested change
The other half is an |
||||||||||||||||||||||||||
| esac | ||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||
| set -- "${REMAINING_ARGS[@]}" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if [[ -n "$ADDON_VERSION" && "$INSTALL_METHOD" != "addon" ]]; then | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 This correctly resolves @simonmarty's earlier note — flags are now parsed from any position and One small note: |
||||||||||||||||||||||||||
| echo "Error: --addon-version requires --addon" >&2 | ||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||
|
Comment on lines
+65
to
+68
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 This reads the ambient environment, not just the flags parsed above. Neither variable is initialized before the loop, so inherited values are indistinguishable from flags:
Fix is to parse into locals and export only what the flags actually set:
Suggested change
(with Minor, optional: |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if [[ "$1" == "clean" ]]; then | ||||||||||||||||||||||||||
| cleanup | ||||||||||||||||||||||||||
| echo "Cleaning up secrets and parameters for all configs..." | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Three doc accuracy issues.
"does not require
PRIVREPO" is not true as shipped —integration.bats.template:346-351(andteardown()at L396-401) still consume$PRIVREPO,$PRIVTAGandghcr-secretwith no addon guard. Someone following these instructions gets a failed run. Accurate once the guards from my comment on L134 are added.--addon x64-pod-identitystill needsPOD_IDENTITY_ROLE_ARN, and as of this PR that's a hard failure rather than a downstream error (generate-test-files.py:236). Worth saying so here, since the section reads as "addon mode needs fewer env vars".Worth stating what
--addondoes and doesn't validate.aws eks create-addonhas no image override, so this path exercises whatever provider image the published add-on ships — not the build from the branch under test. That makes it a release/packaging test, and it can't substitute for the Helm job. Without that caveat a reader could reasonably assume a green--addonrun validated their change.Also, the example pins
v2.2.2-eksbuild.2while the chart is at 3.1.2; a current version (or a note that--addon-versionis optional and defaults to whatever EKS resolves) would age better.