From 8427ad40f002809cf7980bcff70444cebafad28b Mon Sep 17 00:00:00 2001 From: yage Date: Wed, 6 Mar 2024 10:46:09 -0700 Subject: [PATCH] v4.1.0 ===================================================================== Reminder of the deprecation notices for FZF_(HEAD|TAIL) and v3 runstrings! These will be removed in 4.2 (the next minor release!) --- Changes ------------------------------ - removed executable "run" in favor of single "scwrypts" entrypoint (this used to make more sense when running from the executable in the repository directly, but now scwrypts is primarily interfaced through the application itself) - EKS commands will now attempt cluster login if the kubectl context is not detected on your machine - improved warning messages for when scwrypts is out-of-date in API / CI contexts --- Bug Fixes ---------------------------- - zsh/utils/io print functions will now always print if no SCWRYPTS_LOG_LEVEL is defined --- run | 388 ------------------------------ scwrypts | 396 ++++++++++++++++++++++++++++++- zsh/lib/cloud/aws/eks.module.zsh | 4 + zsh/lib/scwrypts/meta.module.zsh | 2 +- zsh/lib/utils/io.zsh | 7 + 5 files changed, 407 insertions(+), 390 deletions(-) delete mode 100755 run diff --git a/run b/run deleted file mode 100755 index 7008a4e..0000000 --- a/run +++ /dev/null @@ -1,388 +0,0 @@ -#!/bin/zsh -export EXECUTION_DIR=$(pwd) -source "${0:a:h}/zsh/lib/import.driver.zsh" || exit 42 -##################################################################### -() { - cd "$SCWRYPTS_ROOT__scwrypts" - GIT_SCWRYPTS() { git -C "$SCWRYPTS_ROOT__scwrypts" $@; } - local ERRORS=0 - local USAGE=' - usage: scwrypts [...options...] [...patterns...] -- [...script options...] - - options: - selection - -m, --name only run the script if there is an exact match - (requires type and group) - -g, --group only use scripts from the indicated group - -t, --type only use scripts of the indicated type - - runtime - -y, --yes auto-accept all [yn] prompts through current scwrypt - -e, --env set environment; overwrites SCWRYPTS_ENV - -n shorthand for "--log-level 0" - -v, --log-level [0-4] set scwrypts log level to one of the following: - 0 : only command output and critical failures; skips logfile - 1 : add success / failure messages - 2 : (default) include status update messages - 3 : (CI default) include warning messages - 4 : include debug messages - - alternate commands - -h, --help display this message and exit - -l, --list print out command list and exit - --list-envs print out environment list and exit - --update update scwrypts library to latest version - --version print out scwrypts version and exit - - patterns: - - a list of glob patterns to loose-match a scwrypt by name - - script options: - - everything after "--" is forwarded to the scwrypt you run - ("-- --help" will provide more information) - ' - - ##################################################################### - ### cli argument parsing and global configuration ################### - ##################################################################### - - local ENV_NAME="$SCWRYPTS_ENV" - local SEARCH_PATTERNS=() - - local VARSPLIT SEARCH_GROUP SEARCH_TYPE SEARCH_NAME - - [ ! $SCWRYPTS_LOG_LEVEL ] && { - local SCWRYPTS_LOG_LEVEL - [ $CI ] && SCWRYPTS_LOG_LEVEL=3 || SCWRYPTS_LOG_LEVEL=2 - } - - while [[ $# -gt 0 ]] - do - case $1 in - -[a-z][a-z]* ) - VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/') - set -- $(echo " $VARSPLIT ") ${@:2} - ;; - - ### alternate commands ################### - - -h | --help ) - USAGE - return 0 - ;; - - -l | --list ) - SCWRYPTS__GET_AVAILABLE_SCWRYPTS - return 0 - ;; - - --list-envs ) - SCWRYPTS__GET_ENV_NAMES - return 0 - ;; - - --version ) - echo scwrypts $(GIT_SCWRYPTS describe --tags) - return 0 - ;; - - --update ) - GIT_SCWRYPTS fetch --quiet origin main - GIT_SCWRYPTS fetch --quiet origin main --tags - local SYNC_STATUS=$? - - GIT_SCWRYPTS diff --exit-code origin/main -- . >/dev/null 2>&1 - local DIFF_STATUS=$? - - [[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && { - SUCCESS 'already up-to-date with origin/main' - } || { - GIT_SCWRYPTS rebase --autostash origin/main \ - && SUCCESS 'up-to-date with origin/main' \ - && GIT_SCWRYPTS log -n1 \ - || { - GIT_SCWRYPTS rebase --abort - ERROR 'unable to update scwrypts; please try manual upgrade' - REMINDER "installation in '$(pwd)'" - } - } - return 0 - ;; - - ### scwrypts filters ##################### - - -m | --name ) - [ $2 ] || { ERROR "missing value for argument $1"; break; } - SEARCH_NAME=$2 - shift 1 - ;; - - -g | --group ) - [ $2 ] || { ERROR "missing value for argument $1"; break; } - SEARCH_GROUP=$2 - shift 1 - ;; - - -t | --type ) - [ $2 ] || { ERROR "missing value for argument $1"; break; } - SEARCH_TYPE=$2 - shift 1 - ;; - - ### runtime settings ##################### - - -y | --yes ) export __SCWRYPTS_YES=1 ;; - - -n | --no-log ) - SCWRYPTS_LOG_LEVEL=0 - [[ $1 =~ ^--no-log$ ]] && WARNING 'the --no-log flag is deprecated and will be removed in scwrypts v4.2' - ;; - - -v | --log-level ) - [[ $2 =~ ^[0-4]$ ]] || ERROR "invalid setting for log-level '$2'" - SCWRYPTS_LOG_LEVEL=$2 - shift 1 - ;; - - -e | --env ) - [ $2 ] || { ERROR "missing value for argument $1"; break; } - - [ $ENV_NAME ] && DEBUG 'overwriting session environment' - - ENV_NAME="$2" - STATUS "using CLI environment '$ENV_NAME'" - shift 1 - ;; - - ########################################## - - -- ) shift 1; break ;; # pass arguments after '--' to the scwrypt - --* ) ERROR "unrecognized argument '$1'" ;; - * ) SEARCH_PATTERNS+=($1) ;; - esac - shift 1 - done - - [ $SEARCH_NAME ] && { - [ $SEARCH_TYPE ] || ERROR '--name requires --type argument' - [ $SEARCH_GROUP ] || ERROR '--name requires --group argument' - } - - CHECK_ERRORS - - ##################################################################### - ### scwrypts selection / filtering ################################## - ##################################################################### - - local SCWRYPTS_AVAILABLE - SCWRYPTS_AVAILABLE=$(SCWRYPTS__GET_AVAILABLE_SCWRYPTS) - - ########################################## - - [ $SEARCH_NAME ] && SCWRYPTS_AVAILABLE=$({ - echo $SCWRYPTS_AVAILABLE | head -n1 - echo $SCWRYPTS_AVAILABLE | sed -e 's/\x1b\[[0-9;]*m//g' | grep "^$SEARCH_NAME *$SEARCH_TYPE *$SEARCH_GROUP\$" - }) || { - [ $SEARCH_TYPE ] && { - SCWRYPTS_AVAILABLE=$(\ - { - echo $SCWRYPTS_AVAILABLE | head -n1 - echo $SCWRYPTS_AVAILABLE | grep ' [^/]*'$SEARCH_TYPE'[^/]* ' - } \ - | awk '{$2=""; print $0;}' \ - | sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \ - | column -ts '^' - ) - } - - [ $SEARCH_GROUP ] && { - SCWRYPTS_AVAILABLE=$( - { - echo $SCWRYPTS_AVAILABLE | head -n1 - echo $SCWRYPTS_AVAILABLE | grep "$SEARCH_GROUP"'[^/]*$' - } \ - | awk '{$NF=""; print $0;}' \ - | sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \ - | column -ts '^' - ) - } - - [[ ${#SEARCH_PATTERNS[@]} -gt 0 ]] && { - POTENTIAL_ERROR+="\n PATTERNS : $SEARCH_PATTERNS" - local P - for P in ${SEARCH_PATTERNS[@]} - do - SCWRYPTS_AVAILABLE=$( - { - echo $SCWRYPTS_AVAILABLE | head -n1 - echo $SCWRYPTS_AVAILABLE | grep $P - } - ) - done - } - } - - [[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -lt 2 ]] && { - FAIL 1 "$(echo " - no such scwrypt exists - NAME : '$SEARCH_NAME' - TYPE : '$SEARCH_TYPE' - GROUP : '$SEARCH_GROUP' - PATTERNS : '$SEARCH_PATTERNS' - " | sed "1d; \$d; /''$/d")" - } - - ########################################## - - [[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -eq 2 ]] \ - && SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | tail -n1) \ - || SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | FZF "select a script to run" --header-lines 1) \ - ; - - [ $SCWRYPT_SELECTION ] || exit 2 - - ########################################## - - local NAME TYPE GROUP - SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION - - export SCWRYPT_NAME=$NAME - export SCWRYPT_TYPE=$TYPE - export SCWRYPT_GROUP=$GROUP - - ##################################################################### - ### environment variables and configuration validation ############## - ##################################################################### - - local ENV_REQUIRED=true \ - && [ ! $CI ] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/environment ]] \ - || ENV_REQUIRED=false - - local REQUIRED_ENVIRONMENT_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$SCWRYPT_GROUP) - - [[ $ENV_REQUIRED =~ true ]] && { - [ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV) - - for GROUP in ${SCWRYPTS_GROUPS[@]} - do - local ENV_FILE=$(SCWRYPTS__GET_ENV_FILE "$ENV_NAME" "$GROUP") - source "$ENV_FILE" || FAIL 5 "missing or invalid environment '$GROUP/$ENV_NAME'" - - for f in $(eval 'echo $SCWRYPTS_STATIC_CONFIG__'$GROUP) - do - source "$f" || FAIL 5 "invalid static config '$f'" - done - done - - export ENV_NAME - } - - ########################################## - - [ $REQUIRED_ENVIRONMENT_REGEX ] && { - [[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \ - || FAIL 5 "group '$SCWRYPT_GROUP' requires current environment name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" - } - - ########################################## - - [ ! $SUBSCWRYPT ] && [[ $ENV_NAME =~ prod ]] && { - STATUS "on '$ENV_NAME'; checking diff against origin/main" - - GIT_SCWRYPTS fetch --quiet origin main - local SYNC_STATUS=$? - - GIT_SCWRYPTS diff --exit-code origin/main -- . >&2 - local DIFF_STATUS=$? - - [[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && { - SUCCESS 'up-to-date with origin/main' - } || { - SCWRYPTS_LOG_LEVEL=3 WARNING "you are trying to run in ${__BRIGHT_RED}production${__YELLOW} but $([[ $SYNC_STATUS -ne 0 ]] && echo 'I am unable to verify your scwrypts version')$([[ $DIFF_STATUS -ne 0 ]] && echo 'your scwrypts is out-of-date (diff listed above)')" - - yN 'continue?' || { - REMINDER "you can use 'scwrypts --update' to quickly update scwrypts to latest" - ABORT - } - } - } - - ########################################## - - local RUN_STRING=$(SCWRYPTS__GET_RUNSTRING $SCWRYPT_NAME $SCWRYPT_TYPE $SCWRYPT_GROUP) - [ "$RUN_STRING" ] || return 42 - - ##################################################################### - ### logging and pretty header/footer setup ########################## - ##################################################################### - - local LOGFILE \ - && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] \ - && [ ! $SUBSCWRYPT ] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ - && [[ ! $SCWRYPT_NAME =~ interactive ]] \ - && LOGFILE="$SCWRYPTS_LOG_PATH/$(echo $GROUP/$TYPE/$NAME | sed 's/^\.\///; s/\//\%/g').log" \ - || LOGFILE='/dev/null' \ - ; - - local RUN_MODE=normal - [[ $LOGFILE =~ ^/dev/null$ ]] && RUN_MODE=no-logfile - [[ $SCWRYPT_NAME =~ interactive ]] && RUN_MODE=interactive - - local HEADER FOOTER - - [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && { - HEADER=$( - echo " - ===================================================================== - script : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME - run at : $(date) - config : $ENV_NAME - log level : $SCWRYPTS_LOG_LEVEL - \\033[1;33m--- SCWRYPT BEGIN ---------------------------------------------------\\033[0m - " | sed 's/^\s\+//; 1d' - ) - - FOOTER="\\033[1;33m--- SCWRYPT END ---------------------------------------------------\\033[0m" - } - - [ $SUBSCWRYPT ] && { - HEADER="\\033[0;33m--- ($SUBSCWRYPT) BEGIN $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" - FOOTER="\\033[0;33m--- ($SUBSCWRYPT) END $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" - } - - ##################################################################### - ### run the scwrypt ################################################# - ##################################################################### - - [ ! $SUBSCWRYPT ] && export SUBSCWRYPT=0 - - set -o pipefail - { - [ $HEADER ] && echo $HEADER - case $RUN_MODE in - normal ) - (eval "$RUN_STRING $(printf "%q " "$@")") - EXIT_CODE=$? - ;; - no-logfile ) - eval "$RUN_STRING $(printf "%q " "$@")" - EXIT_CODE=$? - ;; - interactive ) - eval "$RUN_STRING $(printf "%q " "$@")" /dev/tty 2>&1 - EXIT_CODE=$? - ;; - esac - [ $FOOTER ] && echo $FOOTER - [[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m' - - [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && [ ! $SUBSCWRYPT ] \ - && echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m" - - return $EXIT_CODE - } 2>&1 | tee --append "$LOGFILE" - -} $@ diff --git a/scwrypts b/scwrypts index 9f7f24d..3b051c4 100755 --- a/scwrypts +++ b/scwrypts @@ -1,2 +1,396 @@ #!/bin/zsh -source "${0:a:h}/run" $@ + +export EXECUTION_DIR=$(pwd) +source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 + +##################################################################### +() { + cd "$SCWRYPTS_ROOT__scwrypts" + GIT_SCWRYPTS() { git -C "$SCWRYPTS_ROOT__scwrypts" $@; } + local ERRORS=0 + local USAGE=' + usage: scwrypts [...options...] [...patterns...] -- [...script options...] + + options: + selection + -m, --name only run the script if there is an exact match + (requires type and group) + -g, --group only use scripts from the indicated group + -t, --type only use scripts of the indicated type + + runtime + -y, --yes auto-accept all [yn] prompts through current scwrypt + -e, --env set environment; overwrites SCWRYPTS_ENV + -n shorthand for "--log-level 0" + -v, --log-level [0-4] set scwrypts log level to one of the following: + 0 : only command output and critical failures; skips logfile + 1 : add success / failure messages + 2 : include status update messages + 3 : (default) include warning messages + 4 : include debug messages + + alternate commands + -h, --help display this message and exit + -l, --list print out command list and exit + --list-envs print out environment list and exit + --update update scwrypts library to latest version + --version print out scwrypts version and exit + + patterns: + - a list of glob patterns to loose-match a scwrypt by name + + script options: + - everything after "--" is forwarded to the scwrypt you run + ("-- --help" will provide more information) + ' + + ##################################################################### + ### cli argument parsing and global configuration ################### + ##################################################################### + + local ENV_NAME="$SCWRYPTS_ENV" + local SEARCH_PATTERNS=() + + local VARSPLIT SEARCH_GROUP SEARCH_TYPE SEARCH_NAME + + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=3 + + while [[ $# -gt 0 ]] + do + case $1 in + -[a-z][a-z]* ) + VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/') + set -- $(echo " $VARSPLIT ") ${@:2} + ;; + + ### alternate commands ################### + + -h | --help ) + USAGE + return 0 + ;; + + -l | --list ) + SCWRYPTS__GET_AVAILABLE_SCWRYPTS + return 0 + ;; + + --list-envs ) + SCWRYPTS__GET_ENV_NAMES + return 0 + ;; + + --version ) + echo scwrypts $(GIT_SCWRYPTS describe --tags) + return 0 + ;; + + --update ) + GIT_SCWRYPTS fetch --quiet origin main + GIT_SCWRYPTS fetch --quiet origin main --tags + local SYNC_STATUS=$? + + GIT_SCWRYPTS diff --exit-code origin/main -- . >/dev/null 2>&1 + local DIFF_STATUS=$? + + [[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && { + SUCCESS 'already up-to-date with origin/main' + } || { + GIT_SCWRYPTS rebase --autostash origin/main \ + && SUCCESS 'up-to-date with origin/main' \ + && GIT_SCWRYPTS log -n1 \ + || { + GIT_SCWRYPTS rebase --abort + ERROR 'unable to update scwrypts; please try manual upgrade' + REMINDER "installation in '$(pwd)'" + } + } + return 0 + ;; + + ### scwrypts filters ##################### + + -m | --name ) + [ $2 ] || { ERROR "missing value for argument $1"; break; } + SEARCH_NAME=$2 + shift 1 + ;; + + -g | --group ) + [ $2 ] || { ERROR "missing value for argument $1"; break; } + SEARCH_GROUP=$2 + shift 1 + ;; + + -t | --type ) + [ $2 ] || { ERROR "missing value for argument $1"; break; } + SEARCH_TYPE=$2 + shift 1 + ;; + + ### runtime settings ##################### + + -y | --yes ) export __SCWRYPTS_YES=1 ;; + + -n | --no-log ) + SCWRYPTS_LOG_LEVEL=0 + [[ $1 =~ ^--no-log$ ]] && WARNING 'the --no-log flag is deprecated and will be removed in scwrypts v4.2' + ;; + + -v | --log-level ) + [[ $2 =~ ^[0-4]$ ]] || ERROR "invalid setting for log-level '$2'" + SCWRYPTS_LOG_LEVEL=$2 + shift 1 + ;; + + -e | --env ) + [ $2 ] || { ERROR "missing value for argument $1"; break; } + + [ $ENV_NAME ] && DEBUG 'overwriting session environment' + + ENV_NAME="$2" + STATUS "using CLI environment '$ENV_NAME'" + shift 1 + ;; + + ########################################## + + -- ) shift 1; break ;; # pass arguments after '--' to the scwrypt + --* ) ERROR "unrecognized argument '$1'" ;; + * ) SEARCH_PATTERNS+=($1) ;; + esac + shift 1 + done + + [ $SEARCH_NAME ] && { + [ $SEARCH_TYPE ] || ERROR '--name requires --type argument' + [ $SEARCH_GROUP ] || ERROR '--name requires --group argument' + } + + CHECK_ERRORS + + ##################################################################### + ### scwrypts selection / filtering ################################## + ##################################################################### + + local SCWRYPTS_AVAILABLE + SCWRYPTS_AVAILABLE=$(SCWRYPTS__GET_AVAILABLE_SCWRYPTS) + + ########################################## + + [ $SEARCH_NAME ] && SCWRYPTS_AVAILABLE=$({ + echo $SCWRYPTS_AVAILABLE | head -n1 + echo $SCWRYPTS_AVAILABLE | sed -e 's/\x1b\[[0-9;]*m//g' | grep "^$SEARCH_NAME *$SEARCH_TYPE *$SEARCH_GROUP\$" + }) || { + [ $SEARCH_TYPE ] && { + SCWRYPTS_AVAILABLE=$(\ + { + echo $SCWRYPTS_AVAILABLE | head -n1 + echo $SCWRYPTS_AVAILABLE | grep ' [^/]*'$SEARCH_TYPE'[^/]* ' + } \ + | awk '{$2=""; print $0;}' \ + | sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \ + | column -ts '^' + ) + } + + [ $SEARCH_GROUP ] && { + SCWRYPTS_AVAILABLE=$( + { + echo $SCWRYPTS_AVAILABLE | head -n1 + echo $SCWRYPTS_AVAILABLE | grep "$SEARCH_GROUP"'[^/]*$' + } \ + | awk '{$NF=""; print $0;}' \ + | sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \ + | column -ts '^' + ) + } + + [[ ${#SEARCH_PATTERNS[@]} -gt 0 ]] && { + POTENTIAL_ERROR+="\n PATTERNS : $SEARCH_PATTERNS" + local P + for P in ${SEARCH_PATTERNS[@]} + do + SCWRYPTS_AVAILABLE=$( + { + echo $SCWRYPTS_AVAILABLE | head -n1 + echo $SCWRYPTS_AVAILABLE | grep $P + } + ) + done + } + } + + [[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -lt 2 ]] && { + FAIL 1 "$(echo " + no such scwrypt exists + NAME : '$SEARCH_NAME' + TYPE : '$SEARCH_TYPE' + GROUP : '$SEARCH_GROUP' + PATTERNS : '$SEARCH_PATTERNS' + " | sed "1d; \$d; /''$/d")" + } + + ########################################## + + [[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -eq 2 ]] \ + && SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | tail -n1) \ + || SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | FZF "select a script to run" --header-lines 1) \ + ; + + [ $SCWRYPT_SELECTION ] || exit 2 + + ########################################## + + local NAME TYPE GROUP + SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION + + export SCWRYPT_NAME=$NAME + export SCWRYPT_TYPE=$TYPE + export SCWRYPT_GROUP=$GROUP + + ##################################################################### + ### environment variables and configuration validation ############## + ##################################################################### + + local ENV_REQUIRED=true \ + && [ ! $CI ] \ + && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ + && [[ ! $SCWRYPT_NAME =~ scwrypts/environment ]] \ + || ENV_REQUIRED=false + + local REQUIRED_ENVIRONMENT_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$SCWRYPT_GROUP) + + [ $ENV_NAME ] && [ $REQUIRED_ENVIRONMENT_REGEX ] && { + [[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \ + || FAIL 5 "group '$SCWRYPT_GROUP' requires current environment name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" + } + + [[ $ENV_REQUIRED =~ true ]] && { + [ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV) + + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + local ENV_FILE=$(SCWRYPTS__GET_ENV_FILE "$ENV_NAME" "$GROUP") + source "$ENV_FILE" || FAIL 5 "missing or invalid environment '$GROUP/$ENV_NAME'" + + for f in $(eval 'echo $SCWRYPTS_STATIC_CONFIG__'$GROUP) + do + source "$f" || FAIL 5 "invalid static config '$f'" + done + done + + export ENV_NAME + } + + [ $REQUIRED_ENVIRONMENT_REGEX ] && { + [[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \ + || FAIL 5 "group '$SCWRYPT_GROUP' requires current environment name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" + } + + ########################################## + + [ ! $SUBSCWRYPT ] && export SUBSCWRYPT=0 + + [[ $SUBSCWRYPT -eq 0 ]] && [[ $ENV_NAME =~ prod ]] && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] && { + STATUS "on '$ENV_NAME'; checking diff against origin/main" + + local WARNING_MESSAGE + + [ ! $WARNING_MESSAGE ] && { + GIT_SCWRYPTS fetch --quiet origin main \ + && WARNING_MESSAGE='I am unable to verify your scwrypts version' + } + + [ ! $WARNING_MESSAGE ] && { + GIT_SCWRYPTS diff --exit-code origin/main -- . >/dev/null 2>&1 \ + || WARNING_MESSAGE='your scwrypts is currently out-of-date' + } + + [ $WARNING_MESSAGE ] && { + [[ $SCWRYPTS_LOG_LEVEL -lt 3 ]] && { + REMINDER "you are running in ${__BRIGHT_RED}production${__BRIGHT_MAGENTA} and $WARNING_MESSAGE" + } || { + GIT_SCWRYPTS diff --exit-code origin/main -- . >&2 + WARNING "you are trying to run in ${__BRIGHT_RED}production${__YELLOW} but $WARNING_MESSAGE (relevant diffs and errors above)" + yN 'continue?' || { + REMINDER "you can use 'scwrypts --update' to quickly update scwrypts to latest" + ABORT + } + } + } + } + + ########################################## + + local RUN_STRING=$(SCWRYPTS__GET_RUNSTRING $SCWRYPT_NAME $SCWRYPT_TYPE $SCWRYPT_GROUP) + [ "$RUN_STRING" ] || return 42 + + ##################################################################### + ### logging and pretty header/footer setup ########################## + ##################################################################### + + local LOGFILE \ + && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] \ + && [[ $SUBSCWRYPT -eq 0 ]] \ + && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ + && [[ ! $SCWRYPT_NAME =~ interactive ]] \ + && LOGFILE="$SCWRYPTS_LOG_PATH/$(echo $GROUP/$TYPE/$NAME | sed 's/^\.\///; s/\//\%/g').log" \ + || LOGFILE='/dev/null' \ + ; + + local RUN_MODE=normal + [[ $LOGFILE =~ ^/dev/null$ ]] && RUN_MODE=no-logfile + [[ $SCWRYPT_NAME =~ interactive ]] && RUN_MODE=interactive + + local HEADER FOOTER + + [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && { + HEADER=$( + echo " + ===================================================================== + script : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME + run at : $(date) + config : $ENV_NAME + log level : $SCWRYPTS_LOG_LEVEL + \\033[1;33m--- SCWRYPT BEGIN ---------------------------------------------------\\033[0m + " | sed 's/^\s\+//; 1d' + ) + + FOOTER="\\033[1;33m--- SCWRYPT END ---------------------------------------------------\\033[0m" + } + + [[ $SUBSCWRYPT -eq 0 ]] || { + HEADER="\\033[0;33m--- ($SUBSCWRYPT) BEGIN $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" + FOOTER="\\033[0;33m--- ($SUBSCWRYPT) END $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" + } + + ##################################################################### + ### run the scwrypt ################################################# + ##################################################################### + set -o pipefail + { + [ $HEADER ] && echo $HEADER + case $RUN_MODE in + normal ) + (eval "$RUN_STRING $(printf "%q " "$@")") + EXIT_CODE=$? + ;; + no-logfile ) + eval "$RUN_STRING $(printf "%q " "$@")" + EXIT_CODE=$? + ;; + interactive ) + eval "$RUN_STRING $(printf "%q " "$@")" /dev/tty 2>&1 + EXIT_CODE=$? + ;; + esac + [ $FOOTER ] && echo $FOOTER + [[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m' + + [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && [ ! $SUBSCWRYPT ] \ + && echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m" + + return $EXIT_CODE + } 2>&1 | tee --append "$LOGFILE" +} $@ diff --git a/zsh/lib/cloud/aws/eks.module.zsh b/zsh/lib/cloud/aws/eks.module.zsh index e4bfc67..95b83f2 100644 --- a/zsh/lib/cloud/aws/eks.module.zsh +++ b/zsh/lib/cloud/aws/eks.module.zsh @@ -27,6 +27,9 @@ EKS() { local CONTEXT="arn:aws:eks:${AWS_REGION}:${AWS_ACCOUNT}:cluster/${CLUSTER_NAME}" + kubectl config get-contexts | grep -q $CONTEXT \ + || EKS__CLUSTER_LOGIN -c $CLUSTER_NAME + local CONTEXT_ARGS=() case $1 in helm ) CONTEXT_ARGS+=(--kube-context $CONTEXT) ;; @@ -52,6 +55,7 @@ EKS__CLUSTER_LOGIN() { " REQUIRED_ENV=(AWS_ACCOUNT AWS_REGION) CHECK_ENVIRONMENT || return 1 + local CLUSTER_NAME while [[ $# -gt 0 ]] diff --git a/zsh/lib/scwrypts/meta.module.zsh b/zsh/lib/scwrypts/meta.module.zsh index 1f8fb8a..15c6608 100644 --- a/zsh/lib/scwrypts/meta.module.zsh +++ b/zsh/lib/scwrypts/meta.module.zsh @@ -12,7 +12,7 @@ SCWRYPTS__RUN() { # context wrapper to run scwrypts within scwrypts local EXIT_CODE=0 ((SUBSCWRYPT+=1)) - SUBSCWRYPT=$SUBSCWRYPT $SCWRYPTS_ROOT/run $@ + SUBSCWRYPT=$SUBSCWRYPT $SCWRYPTS_ROOT/scwrypts $@ EXIT_CODE=$? ((SUBSCWRYPT-=1)) diff --git a/zsh/lib/utils/io.zsh b/zsh/lib/utils/io.zsh index df3950b..508d9ac 100644 --- a/zsh/lib/utils/io.zsh +++ b/zsh/lib/utils/io.zsh @@ -6,6 +6,7 @@ source "${0:a:h}/io.print.zsh" [ ! $ERRORS ] && ERRORS=0 ERROR() { # command encountered an error + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ && PREFIX="ERROR ✖" COLOR=$__RED PRINT "$@" ((ERRORS+=1)) @@ -13,36 +14,42 @@ ERROR() { # command encountered an error } SUCCESS() { # command completed successfully + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ && PREFIX="SUCCESS ✔" COLOR=$__GREEN PRINT "$@" return 0 } REMINDER() { # include sysadmin reminder or other important notice to users + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ && PREFIX="REMINDER " COLOR=$__BRIGHT_MAGENTA PRINT "$@" return 0 } STATUS() { # general status updates (prefer this to generic 'echo') + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] \ && PREFIX="STATUS " COLOR=$__BLUE PRINT "$@" return 0 } WARNING() { # warning-level messages; not errors + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 3 ]] \ && PREFIX="WARNING " COLOR=$__YELLOW PRINT "$@" return 0 } DEBUG() { # helpful during development or (sparingly) to help others' development + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 4 ]] \ && PREFIX="DEBUG ℹ" COLOR=$__WHITE PRINT "$@" return 0 } PROMPT() { # you probably want to use yN or INPUT from below + [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ && PREFIX="PROMPT " COLOR=$__CYAN PRINT "$@" \ && PREFIX="USER ⌨" COLOR=$__BRIGHT_CYAN PRINT '' --no-line-end \