diff --git a/blackbox b/blackbox index 620c9a42..f7383c53 100644 --- a/blackbox +++ b/blackbox @@ -54,6 +54,8 @@ blackbox() { # shellcheck disable=SC2155 export BLACKBOX_VERSION="2404" + export BLACKBOX_ECR_TOKEN_DIR="${BLACKBOX_ECR_TOKEN_DIR:-/run/hackerrank/devops-ecr}" + export BLACKBOX_FLAG__DEBUG_MODE=${BLACKBOX_FLAG__DEBUG_MODE:-no} # shellcheck disable=SC2155 export BLACKBOX_FLAG__STEP_PROVISION=$(awk -v master="yes" -v user="${BLACKBOX_FLAG__STEP_PROVISION:-yes}" 'END { print ($0 == "blackbox") ? user : master }' <(findmnt -n --mountpoint="/blackbox" --output="SOURCE")) diff --git a/docs/framework/inventory.framework.md b/docs/framework/inventory.framework.md index 4aed472f..ee9d2718 100644 --- a/docs/framework/inventory.framework.md +++ b/docs/framework/inventory.framework.md @@ -18,6 +18,8 @@ Inventory handler * [blackbox.framework.inventory.snapshot.digest](#blackboxframeworkinventorysnapshotdigest) * [blackbox.framework.inventory.snapshot.verify](#blackboxframeworkinventorysnapshotverify) * [blackbox.framework.inventory.snapshot.__init](#blackboxframeworkinventorysnapshotinit) +* [blackbox.framework.inventory.ecr.token.read](#blackboxframeworkinventoryecrtokenread) +* [blackbox.framework.inventory.ecr.token.login](#blackboxframeworkinventoryecrtokenlogin) * [blackbox.framework.inventory.ecr.login](#blackboxframeworkinventoryecrlogin) * [blackbox.framework.inventory.ecr.logout](#blackboxframeworkinventoryecrlogout) * [blackbox.framework.inventory.provision](#blackboxframeworkinventoryprovision) @@ -187,6 +189,51 @@ _Function has no arguments._ ## blackbox.framework.inventory.ecr.* +### blackbox.framework.inventory.ecr.token.read + +#### Example + +```bash +# Read the private ECR password +blackbox.framework.inventory.ecr.token.read private-password +``` + +#### Arguments + +* **$1** (type=enum): Token file name + +#### Exit codes + +* **0**: If a non-empty token was read, which is printed to stdout +* **1**: If the token was missing or empty + +#### See also + +* [blackbox.framework.inventory.ecr.token.login](#blackboxframeworkinventoryecrtokenlogin) + +### blackbox.framework.inventory.ecr.token.login + +#### Example + +```bash +# Log in to the private registry +blackbox.framework.inventory.ecr.token.login 134148934511.dkr.ecr.us-east-1.amazonaws.com private-password +``` + +#### Arguments + +* **$1** (type=string): Registry +* **$2** (type=enum): Token file name + +#### Exit codes + +* **0**: If both the root and "$BLACKBOX_USER_NAME" logins succeeded +* **1**: If no token could be read, or either login failed + +#### See also + +* [blackbox.framework.inventory.ecr.token.read](#blackboxframeworkinventoryecrtokenread) + ### blackbox.framework.inventory.ecr.login #### Example @@ -198,6 +245,11 @@ blackbox.framework.inventory.ecr.login _Function has no arguments._ +#### Exit codes + +* **0**: If the private registry login succeeded +* **1**: If the private registry login failed + #### See also * [blackbox.framework.inventory.ecr.logout](#blackboxframeworkinventoryecrlogout) diff --git a/framework/inventory.framework b/framework/inventory.framework index 12cb63a7..cae09bed 100644 --- a/framework/inventory.framework +++ b/framework/inventory.framework @@ -249,10 +249,62 @@ blackbox.framework.inventory() { blackbox.framework.inventory.ecr() { # @section blackbox.framework.inventory.ecr.* + # Reads an ECR docker-login password from the host credential handoff published under "$BLACKBOX_ECR_TOKEN_DIR" + # + # @arg $1 type=enum Token file name + # + # @exitcode 0 If a non-empty token was read, which is printed to stdout + # @exitcode 1 If the token was missing or empty + # + # @example + # # Read the private ECR password + # blackbox.framework.inventory.ecr.token.read private-password + # + # @see blackbox.framework.inventory.ecr.token.login + function blackbox.framework.inventory.ecr.token.read() { + typeset -r name=$1 + typeset token + + if token=$(cat "${BLACKBOX_ECR_TOKEN_DIR}/${name}" 2>/dev/null) && [ -n "$token" ]; then + printf "%s" "$token" + return 0 + fi + + printf "error: *** ECR token '%s/%s' is not available\n" "$BLACKBOX_ECR_TOKEN_DIR" "$name" >&2 + return 1 + } + + # Logs in to a Docker registry, for both root and "$BLACKBOX_USER_NAME", with a password from the host credential handoff + # + # @arg $1 type=string Registry + # @arg $2 type=enum Token file name + # + # @exitcode 0 If both the root and "$BLACKBOX_USER_NAME" logins succeeded + # @exitcode 1 If no token could be read, or either login failed + # + # @example + # # Log in to the private registry + # blackbox.framework.inventory.ecr.token.login 134148934511.dkr.ecr.us-east-1.amazonaws.com private-password + # + # @see blackbox.framework.inventory.ecr.token.read + function blackbox.framework.inventory.ecr.token.login() { + typeset -r registry=$1 + typeset -r name=$2 + typeset token + + token=$(blackbox.framework.inventory.ecr.token.read "$name") || return 1 + + docker login --username AWS --password-stdin "$registry" <<<"$token" \ + && sudo -u "$BLACKBOX_USER_NAME" docker login --username AWS --password-stdin "$registry" <<<"$token" + } + # Logs in to Amazon ECR # # @noargs # + # @exitcode 0 If the private registry login succeeded + # @exitcode 1 If the private registry login failed + # # @example # # Logs in to Amazon ECR # blackbox.framework.inventory.ecr.login @@ -264,26 +316,15 @@ blackbox.framework.inventory() { } blackbox.framework.inventory.provision awscli - ( - export AWS_DEFAULT_REGION="us-east-1" - # shellcheck disable=SC2155 - export AWS_ACCESS_KEY_ID=$(base64 -d <(base64 -d <<<"UVV0SlFWSTJUemRIU2s1WVZGbEtOVFJNU1U4PQo=")) - # shellcheck disable=SC2155 - export AWS_SECRET_ACCESS_KEY=$(base64 -d <(base64 -d <<<"YVZWNlRtcExlWEpJWVhOeE5UUjVUR05QTlZSbFRraEhlVWxsYzJOMVkxRkJSazVqWTJJeFpRPT0K")) - - # shellcheck disable=SC2155 - local ECR_PASSWORD=$(/usr/local/aws-cli/v2/current/bin/aws ecr get-login-password --region "$AWS_DEFAULT_REGION") - docker login --username AWS --password-stdin 134148934511.dkr.ecr.us-east-1.amazonaws.com <<<"$ECR_PASSWORD" - sudo -u "$BLACKBOX_USER_NAME" docker login --username AWS --password-stdin 134148934511.dkr.ecr.us-east-1.amazonaws.com <<<"$ECR_PASSWORD" + ( + blackbox.framework.inventory.ecr.token.login 134148934511.dkr.ecr.us-east-1.amazonaws.com private-password || exit 1 { # TODO: for backwards compatibility with public ECR repositories, and should be removed when all questions are moved to private ECR repositories - # shellcheck disable=SC2155 - local ECR_PASSWORD_PUBLIC=$(/usr/local/aws-cli/v2/current/bin/aws ecr-public get-login-password --region "$AWS_DEFAULT_REGION") - - docker login --username AWS --password-stdin public.ecr.aws/b0k9n8x8 <<<"$ECR_PASSWORD_PUBLIC" - sudo -u "$BLACKBOX_USER_NAME" docker login --username AWS --password-stdin public.ecr.aws/b0k9n8x8 <<<"$ECR_PASSWORD_PUBLIC" + blackbox.framework.inventory.ecr.token.login public.ecr.aws/b0k9n8x8 public-password || { + printf "warn: *** public ECR login failed, questions hosted on public repositories will not pull\n" >&2 + } } ) 2>&1 # ¯\_(ツ)_/¯ } diff --git a/framework/module/abstract/check/provision.step b/framework/module/abstract/check/provision.step index 60e75236..5a200a68 100644 --- a/framework/module/abstract/check/provision.step +++ b/framework/module/abstract/check/provision.step @@ -43,9 +43,9 @@ blackbox.framework.module.abstract.check.provision() { fi if ( grep -q '^init$' <(ps -p 1 -o comm=) ); then - docker run -di --hostname="$BLACKBOX_SPAWN" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" + docker run -di --hostname="$BLACKBOX_SPAWN" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" --env="BLACKBOX_ECR_TOKEN_DIR=${BLACKBOX_ECR_TOKEN_DIR}" --volume="${BLACKBOX_ECR_TOKEN_DIR}:${BLACKBOX_ECR_TOKEN_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" else - docker run -di --hostname="$BLACKBOX_SPAWN" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_DIR}:${BLACKBOX_DIR}:ro" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" + docker run -di --hostname="$BLACKBOX_SPAWN" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_DIR}:${BLACKBOX_DIR}:ro" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" --env="BLACKBOX_ECR_TOKEN_DIR=${BLACKBOX_ECR_TOKEN_DIR}" --volume="${BLACKBOX_ECR_TOKEN_DIR}:${BLACKBOX_ECR_TOKEN_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" fi : <<< blackbox.module.*.check.provision diff --git a/module/ansible-aws/check/provision.step b/module/ansible-aws/check/provision.step index 762ce5e4..f784d919 100644 --- a/module/ansible-aws/check/provision.step +++ b/module/ansible-aws/check/provision.step @@ -31,9 +31,9 @@ blackbox.module.ansible-aws.check.provision() { } if ( grep -q '^init$' <(ps -p 1 -o comm=) ); then - docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" + docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" --env="BLACKBOX_ECR_TOKEN_DIR=${BLACKBOX_ECR_TOKEN_DIR}" --volume="${BLACKBOX_ECR_TOKEN_DIR}:${BLACKBOX_ECR_TOKEN_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" else - docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_DIR}:${BLACKBOX_DIR}:ro" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" + docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_DIR}:${BLACKBOX_DIR}:ro" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" --env="BLACKBOX_ECR_TOKEN_DIR=${BLACKBOX_ECR_TOKEN_DIR}" --volume="${BLACKBOX_ECR_TOKEN_DIR}:${BLACKBOX_ECR_TOKEN_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" fi if [ -n "$BLACKBOX_PROVISION_WITH_OPTS" ]; then diff --git a/module/aws/check/provision.step b/module/aws/check/provision.step index 1b1b3a10..644d8bb5 100644 --- a/module/aws/check/provision.step +++ b/module/aws/check/provision.step @@ -24,9 +24,9 @@ blackbox.module.aws.check.provision() { fi if ( grep -q '^init$' <(ps -p 1 -o comm=) ); then - docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --volume="/tmp:/tmp:rw" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" + docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --volume="/tmp:/tmp:rw" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" --env="BLACKBOX_ECR_TOKEN_DIR=${BLACKBOX_ECR_TOKEN_DIR}" --volume="${BLACKBOX_ECR_TOKEN_DIR}:${BLACKBOX_ECR_TOKEN_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" else - docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --volume="/tmp:/tmp:rw" --volume="${BLACKBOX_DIR}:${BLACKBOX_DIR}:ro" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" + docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --volume="/tmp:/tmp:rw" --volume="${BLACKBOX_DIR}:${BLACKBOX_DIR}:ro" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" --env="BLACKBOX_ECR_TOKEN_DIR=${BLACKBOX_ECR_TOKEN_DIR}" --volume="${BLACKBOX_ECR_TOKEN_DIR}:${BLACKBOX_ECR_TOKEN_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" fi if [ -n "$BLACKBOX_PROVISION_WITH_OPTS" ]; then diff --git a/module/terraform-aws/check/provision.step b/module/terraform-aws/check/provision.step index 0690f4dc..f538bdda 100644 --- a/module/terraform-aws/check/provision.step +++ b/module/terraform-aws/check/provision.step @@ -31,9 +31,9 @@ blackbox.module.terraform-aws.check.provision() { } if ( grep -q '^init$' <(ps -p 1 -o comm=) ); then - docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" + docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" --env="BLACKBOX_ECR_TOKEN_DIR=${BLACKBOX_ECR_TOKEN_DIR}" --volume="${BLACKBOX_ECR_TOKEN_DIR}:${BLACKBOX_ECR_TOKEN_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" else - docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_DIR}:${BLACKBOX_DIR}:ro" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" + docker run -di --hostname="$BLACKBOX_SPAWN" --network="host" --name="$BLACKBOX_SPAWN" --privileged --cgroupns=host --volume="${BLACKBOX_DIR}:${BLACKBOX_DIR}:ro" --volume="${BLACKBOX_USER_QUESTION_DIR}:${BLACKBOX_USER_QUESTION_DIR}:rw" --volume="${BLACKBOX_STORAGE_DIR}:${BLACKBOX_STORAGE_DIR}:ro" --env="BLACKBOX_ECR_TOKEN_DIR=${BLACKBOX_ECR_TOKEN_DIR}" --volume="${BLACKBOX_ECR_TOKEN_DIR}:${BLACKBOX_ECR_TOKEN_DIR}:ro" "134148934511.dkr.ecr.us-east-1.amazonaws.com/hr/blackbox_2404:${BLACKBOX_MODULE_NAME}" fi if [ -n "$BLACKBOX_PROVISION_WITH_OPTS" ]; then