From 923938ab26775e026ae4fec2280f9df09ebabbc1 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 14 Apr 2021 17:26:12 -0700 Subject: [PATCH] Avoid multi-line integration test env vars Avoid them because they can't be used in GoLand for running integration tests in the UI, like running in the debugger. Also adds optional PINNIPED_TEST_TOOLS_NAMESPACE because we need it on the LDAP feature branch where we are developing the upcoming LDAP support for the Supervisor. --- hack/integration-test-env-goland.sh | 22 ++++++++++++++++++++++ hack/prepare-for-integration-tests.sh | 26 +++++++++++++++----------- test/library/env.go | 21 ++++++++++++++++++--- 3 files changed, 55 insertions(+), 14 deletions(-) create mode 100755 hack/integration-test-env-goland.sh diff --git a/hack/integration-test-env-goland.sh b/hack/integration-test-env-goland.sh new file mode 100755 index 00000000..89885e2f --- /dev/null +++ b/hack/integration-test-env-goland.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +# Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +# +# Print the PINNIPED_TEST_* env vars from /tmp/integration-test-env in a format that can be used in GoLand. +# + +set -euo pipefail + +ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" + +source /tmp/integration-test-env + +printenv | grep PINNIPED_TEST_ | sed 's/=.*//g' | grep -v CLUSTER_CAPABILITY_YAML | while read -r var ; do + echo -n "${var}=" + echo -n "${!var}" | tr -d '\n' + echo -n ";" +done + +echo -n "PINNIPED_TEST_CLUSTER_CAPABILITY_FILE=${ROOT}/test/cluster_capabilities/kind.yaml" diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index c52e7776..b697d7ce 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -296,13 +296,18 @@ popd >/dev/null test_ca_bundle_pem="$(kubectl get secrets -n tools certs -o go-template='{{index .data "ca.pem" | base64decode}}')" # -# Create the environment file +# Create the environment file. +# +# Note that all values should not contains newlines, except for PINNIPED_TEST_CLUSTER_CAPABILITY_YAML, +# so that the environment can also be used in tools like GoLand. Therefore, multi-line values, +# such as PEM-formatted certificates, should be base64 encoded. # kind_capabilities_file="$pinniped_path/test/cluster_capabilities/kind.yaml" pinniped_cluster_capability_file_content=$(cat "$kind_capabilities_file") cat </tmp/integration-test-env # The following env vars should be set before running 'go test -v -count 1 -timeout 0 ./test/integration' +export PINNIPED_TEST_TOOLS_NAMESPACE="tools" export PINNIPED_TEST_CONCIERGE_NAMESPACE=${concierge_namespace} export PINNIPED_TEST_CONCIERGE_APP_NAME=${concierge_app_name} export PINNIPED_TEST_CONCIERGE_CUSTOM_LABELS='${concierge_custom_labels}' @@ -317,9 +322,8 @@ export PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS='${supervisor_custom_labels}' export PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS="127.0.0.1:12345" export PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS="localhost:12344" export PINNIPED_TEST_PROXY=http://127.0.0.1:12346 -export PINNIPED_TEST_LDAP_LDAP_URL=ldap://ldap.tools.svc.cluster.local -export PINNIPED_TEST_LDAP_LDAPS_URL=ldaps://ldap.tools.svc.cluster.local -export PINNIPED_TEST_LDAP_LDAPS_CA_BUNDLE="${test_ca_bundle_pem}" +export PINNIPED_TEST_LDAP_HOST=ldap.tools.svc.cluster.local +export PINNIPED_TEST_LDAP_LDAPS_CA_BUNDLE=$(echo "${test_ca_bundle_pem}" | base64 ) export PINNIPED_TEST_LDAP_BIND_ACCOUNT_USERNAME="cn=admin,dc=pinniped,dc=dev" export PINNIPED_TEST_LDAP_BIND_ACCOUNT_PASSWORD=password export PINNIPED_TEST_LDAP_USERS_SEARCH_BASE="ou=users,dc=pinniped,dc=dev" @@ -327,6 +331,8 @@ export PINNIPED_TEST_LDAP_GROUPS_SEARCH_BASE="ou=groups,dc=pinniped,dc=dev" export PINNIPED_TEST_LDAP_USER_DN="cn=pinny,ou=users,dc=pinniped,dc=dev" export PINNIPED_TEST_LDAP_USER_CN="pinny" export PINNIPED_TEST_LDAP_USER_PASSWORD=${ldap_test_password} +export PINNIPED_TEST_LDAP_USER_UNIQUE_ID_ATTRIBUTE_NAME="uidNumber" +export PINNIPED_TEST_LDAP_USER_UNIQUE_ID_ATTRIBUTE_VALUE="1000" export PINNIPED_TEST_LDAP_USER_EMAIL_ATTRIBUTE_NAME="mail" export PINNIPED_TEST_LDAP_USER_EMAIL_ATTRIBUTE_VALUE="pinny.ldap@example.com" export PINNIPED_TEST_LDAP_EXPECTED_DIRECT_GROUPS_DN="cn=ball-game-players,ou=beach-groups,ou=groups,dc=pinniped,dc=dev;cn=seals,ou=groups,dc=pinniped,dc=dev" @@ -334,13 +340,13 @@ export PINNIPED_TEST_LDAP_EXPECTED_INDIRECT_GROUPS_DN="cn=pinnipeds,ou=groups,dc export PINNIPED_TEST_LDAP_EXPECTED_DIRECT_GROUPS_CN="ball-game-players;seals" export PINNIPED_TEST_LDAP_EXPECTED_INDIRECT_GROUPS_CN="pinnipeds;mammals" export PINNIPED_TEST_CLI_OIDC_ISSUER=https://dex.tools.svc.cluster.local/dex -export PINNIPED_TEST_CLI_OIDC_ISSUER_CA_BUNDLE="${test_ca_bundle_pem}" +export PINNIPED_TEST_CLI_OIDC_ISSUER_CA_BUNDLE=$(echo "${test_ca_bundle_pem}" | base64 ) export PINNIPED_TEST_CLI_OIDC_CLIENT_ID=pinniped-cli export PINNIPED_TEST_CLI_OIDC_CALLBACK_URL=http://127.0.0.1:48095/callback export PINNIPED_TEST_CLI_OIDC_USERNAME=pinny@example.com export PINNIPED_TEST_CLI_OIDC_PASSWORD=${dex_test_password} export PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_ISSUER=https://dex.tools.svc.cluster.local/dex -export PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_ISSUER_CA_BUNDLE="${test_ca_bundle_pem}" +export PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_ISSUER_CA_BUNDLE=$(echo "${test_ca_bundle_pem}" | base64 ) export PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_ADDITIONAL_SCOPES=email export PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_USERNAME_CLAIM=email export PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_GROUPS_CLAIM=groups @@ -360,17 +366,15 @@ export PINNIPED_TEST_CLUSTER_CAPABILITY_YAML EOF # -# Print instructions for next steps +# Print instructions for next steps. # -goland_vars=$(grep -v '^#' /tmp/integration-test-env | grep -E '^export .+=' | sed 's/export //g' | tr '\n' ';') - log_note log_note "🚀 Ready to run integration tests! For example..." log_note " cd $pinniped_path" log_note ' source /tmp/integration-test-env && go test -v -race -count 1 -timeout 0 ./test/integration' log_note -log_note 'Want to run integration tests in GoLand? Copy/paste this "Environment" value for GoLand run configurations:' -log_note " ${goland_vars}PINNIPED_TEST_CLUSTER_CAPABILITY_FILE=${kind_capabilities_file}" +log_note "Using GoLand? Paste the result of this command into GoLand's run configuration \"Environment\"." +log_note " hack/integration-test-env-goland.sh | pbcopy" log_note log_note "You can rerun this script to redeploy local production code changes while you are working." log_note diff --git a/test/library/env.go b/test/library/env.go index a19aaa2e..a806d5ff 100644 --- a/test/library/env.go +++ b/test/library/env.go @@ -4,6 +4,7 @@ package library import ( + "encoding/base64" "io/ioutil" "os" "strings" @@ -28,6 +29,7 @@ const ( type TestEnv struct { t *testing.T + ToolsNamespace string `json:"toolsNamespace"` ConciergeNamespace string `json:"conciergeNamespace"` SupervisorNamespace string `json:"supervisorNamespace"` ConciergeAppName string `json:"conciergeAppName"` @@ -122,6 +124,16 @@ func needEnv(t *testing.T, key string) string { return value } +func base64Decoded(t *testing.T, s string) string { + t.Helper() + if len(s) == 0 { + return s + } + bytes, err := base64.StdEncoding.DecodeString(s) + require.NoError(t, err) + return string(bytes) +} + func wantEnv(key, dephault string) string { value, ok := os.LookupEnv(key) if !ok { @@ -143,6 +155,8 @@ func filterEmpty(ss []string) []string { func loadEnvVars(t *testing.T, result *TestEnv) { t.Helper() + result.ToolsNamespace = os.Getenv("PINNIPED_TEST_TOOLS_NAMESPACE") + result.ConciergeNamespace = needEnv(t, "PINNIPED_TEST_CONCIERGE_NAMESPACE") result.ConciergeAppName = needEnv(t, "PINNIPED_TEST_CONCIERGE_APP_NAME") result.TestUser.ExpectedUsername = needEnv(t, "PINNIPED_TEST_USER_USERNAME") @@ -155,7 +169,6 @@ func loadEnvVars(t *testing.T, result *TestEnv) { result.SupervisorHTTPAddress = os.Getenv("PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS") result.SupervisorHTTPSIngressAddress = os.Getenv("PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_ADDRESS") - result.SupervisorHTTPSIngressCABundle = os.Getenv("PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_CA_BUNDLE") // optional require.NotEmptyf(t, result.SupervisorHTTPAddress+result.SupervisorHTTPSIngressAddress, "must specify either PINNIPED_TEST_SUPERVISOR_HTTP_ADDRESS or PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_ADDRESS env var (or both) for integration tests", @@ -164,6 +177,7 @@ func loadEnvVars(t *testing.T, result *TestEnv) { require.NotRegexp(t, "^[0-9]", result.SupervisorHTTPSAddress, "PINNIPED_TEST_SUPERVISOR_HTTPS_ADDRESS must be a hostname with an optional port and cannot be an IP address", ) + result.SupervisorHTTPSIngressCABundle = base64Decoded(t, os.Getenv("PINNIPED_TEST_SUPERVISOR_HTTPS_INGRESS_CA_BUNDLE")) conciergeCustomLabelsYAML := needEnv(t, "PINNIPED_TEST_CONCIERGE_CUSTOM_LABELS") var conciergeCustomLabels map[string]string @@ -177,12 +191,13 @@ func loadEnvVars(t *testing.T, result *TestEnv) { require.NoErrorf(t, err, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS must be a YAML map of string to string") result.SupervisorCustomLabels = supervisorCustomLabels require.NotEmpty(t, result.SupervisorCustomLabels, "PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS cannot be empty") + result.Proxy = os.Getenv("PINNIPED_TEST_PROXY") result.APIGroupSuffix = wantEnv("PINNIPED_TEST_API_GROUP_SUFFIX", "pinniped.dev") result.CLITestUpstream = TestOIDCUpstream{ Issuer: needEnv(t, "PINNIPED_TEST_CLI_OIDC_ISSUER"), - CABundle: os.Getenv("PINNIPED_TEST_CLI_OIDC_ISSUER_CA_BUNDLE"), + CABundle: base64Decoded(t, os.Getenv("PINNIPED_TEST_CLI_OIDC_ISSUER_CA_BUNDLE")), ClientID: needEnv(t, "PINNIPED_TEST_CLI_OIDC_CLIENT_ID"), CallbackURL: needEnv(t, "PINNIPED_TEST_CLI_OIDC_CALLBACK_URL"), Username: needEnv(t, "PINNIPED_TEST_CLI_OIDC_USERNAME"), @@ -191,7 +206,7 @@ func loadEnvVars(t *testing.T, result *TestEnv) { result.SupervisorTestUpstream = TestOIDCUpstream{ Issuer: needEnv(t, "PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_ISSUER"), - CABundle: os.Getenv("PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_ISSUER_CA_BUNDLE"), + CABundle: base64Decoded(t, os.Getenv("PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_ISSUER_CA_BUNDLE")), AdditionalScopes: strings.Fields(os.Getenv("PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_ADDITIONAL_SCOPES")), UsernameClaim: os.Getenv("PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_USERNAME_CLAIM"), GroupsClaim: os.Getenv("PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_GROUPS_CLAIM"),