=====================================================================

Excited to bring V5 to life. This includes some BREAKING CHANGES to
several aspects of ZSH-type scwrypts. Please refer to the readme
for upgrade details (specifically docs/upgrade/v4-to-v5.md)

--- New Features -------------------------

- ZSH testing library with basic mock capabilities

- new scwrypts environment file format includes metadata and more
  advanced features like optional parent env overrides, selection
  inheritence, and improved structurual flexibility

- speedup cache for non-CI runs of ZSH-type scwrypts

- ${scwryptsmodule} syntax now allows a consistent unique-naming
  scheme for functions in ZSH-type scwrypts while providing better
  insight into origin of API calls in other modules

- reusable, case-statement-driven argument parsers in ZSH-type scwrypts

--- Changes ------------------------------

- several utility function renames in ZSH-type scwrypts to improve
  consistency

- documentation comments included in ZSH libraries

- ZSH-type scwrypts now allow library modules to live alongside
  executables
  (zsh/lib still supported; autodetection determines default)

--- Bug Fixes ----------------------------

- hardened environment checking for REQUIRED_ENV variables; this removes
  the ability to overwrite variables in local function contexts
This commit is contained in:
2024-05-10 13:32:02 -06:00
committed by Wryn (yage) Wagner
parent 1b4060dd1c
commit 7f14edd039
271 changed files with 11459 additions and 10516 deletions

View File

@ -0,0 +1 @@
---

View File

@ -1,10 +1,3 @@
# Kubernetes `kubectl` Helper Plugin
# CI Helper
Leverages a local `redis` application to quickly and easily set an alias `k` for `kubectl --context <some-context> --namespace <some-namespace>`.
Much like scwrypts environments, `k` aliases are *only* shared amongst session with the same `SCWRYPTS_ENV` to prevent accidental cross-contamination.
## Getting Started
Enable the plugin in `~/.config/scwrypts/config.zsh` by adding `SCWRYPTS_PLUGIN_ENABLED__KUBECTL=1`.
Use `k` as your new `kubectl` and checkout `k --help` and `k meta --help`.
Disabled by default, this is used in CI contexts to try and identify missing requirements for the current workflow.

View File

@ -1,7 +1,7 @@
#!/bin/zsh
#!/usr/bin/env zsh
#####################################################################
MAIN() {
cd "$SCWRYPTS_ROOT__scwrypts/"
cd "$(scwrypts.config.group scwrypts root)"
DEPENDENCIES+=()
for group in ${SCWRYPTS_GROUPS[@]}
@ -11,7 +11,7 @@ MAIN() {
GROUP_HOME="$(eval 'echo $SCWRYPTS_ROOT__'$group)"
[ $GROUP_HOME ] && [ -d "$GROUP_HOME" ] || continue
STATUS "checking dependencies for $group"
echo.status "checking dependencies for $group"
DEPENDENCIES+=($(
for file in $(
{
@ -21,13 +21,13 @@ MAIN() {
} | grep -v '\.md$' | grep -v 'check-all-dependencies$')
do
sed -z 's/.*DEPENDENCIES+=(\([^)]*\)).*/\1\n/; s/#.*\n//g; s/\s\+/\n/g' "$GROUP_HOME/$file"
done
done
))
done
DEPENDENCIES=(zsh $(echo $DEPENDENCIES | sed 's/ /\n/g' | sort -u | grep '^[-_a-zA-Z]\+$'))
STATUS "discovered dependencies: ($DEPENDENCIES)"
echo.status "discovered dependencies: ($DEPENDENCIES)"
echo $DEPENDENCIES | sed 's/ /\n/g'
CHECK_ENVIRONMENT && SUCCESS "all dependencies satisfied"
utils.check-environment && echo.success "all dependencies satisfied"
}

View File

@ -1,5 +1 @@
SCWRYPTS_GROUPS+=(ci)
export SCWRYPTS_TYPE__ci=zsh
export SCWRYPTS_ROOT__ci="$SCWRYPTS_ROOT__scwrypts/plugins/ci"
export SCWRYPTS_COLOR__ci='\033[0m'
export ${scwryptsgroup}__type=zsh

View File

@ -0,0 +1,5 @@
---
scwrypts-kubectl-redis:
.DESCRIPTION: >-
[currently only 'managed'] 'managed' or 'custom' redis configuration
.ENVIRONMENT: SCWRYPTS_KUBECTL_REDIS

View File

@ -6,10 +6,11 @@ for CLI in kubectl helm flux
do
eval "_${CLI[1]}() {
local SUBSESSION=0
echo \${words[2]} | grep -q '^[0-9]\\+$' && SUBSESSION=\${words[2]}
local SUBSESSION_OFFSET=2
echo \${words[2]} | grep -q '^[0-9]\\+$' && SUBSESSION=\${words[2]} && SUBSESSION_OFFSET=3
local PASSTHROUGH_WORDS=($CLI)
[[ \$CURRENT -gt 2 ]] && echo \${words[2]} | grep -qv '^[0-9]\\+$' && {
[[ \$CURRENT -gt \${SUBSESSION_OFFSET} ]] && echo \${words[\${SUBSESSION_OFFSET}]} | grep -qv '^[0-9]\\+$' && {
local KUBECONTEXT=\$(k \$SUBSESSION meta get context)
local NAMESPACE=\$(k \$SUBSESSION meta get namespace)
@ -26,8 +27,8 @@ do
for WORD in \${words[@]:1}
do
case \$WORD in
[0-9]* ) continue ;;
-- )
( [0-9]* ) continue ;;
( -- )
echo \$words | grep -q 'exec' && ((DELIMIT_COUNT+=1))
[[ \$DELIMIT_COUNT -eq 0 ]] && ((DELIMIT_COUNT+=1)) && continue
;;
@ -37,7 +38,7 @@ do
echo \"\$words\" | grep -q '\\s\\+$' && PASSTHROUGH_WORDS+=(' ')
words=\"\$PASSTHROUGH_WORDS\"
words=\"\${PASSTHROUGH_WORDS[@]}\"
_$CLI
}
"

View File

@ -7,12 +7,12 @@ f() { _SCWRYPTS_KUBECTL_DRIVER flux $@; }
_SCWRYPTS_KUBECTL_DRIVER() {
[ ! $SCWRYPTS_ENV ] && {
ERROR "must set SCWRYPTS_ENV in order to use '$(echo $CLI | head -c1)'"
echo.error "must set SCWRYPTS_ENV in order to use '$(echo $CLI | head -c1)'"
return 1
}
which REDIS >/dev/null 2>&1 \
|| eval "$(scwrypts -n --name meta/get-static-redis-definition --type zsh --group kubectl)"
which kube.redis >/dev/null 2>&1 \
|| eval "$(scwrypts -n --name meta/get-static-redis-definition --type zsh --group kube)"
local CLI="$1"; shift 1
@ -38,16 +38,16 @@ _SCWRYPTS_KUBECTL_DRIVER() {
description: -
"
local USAGE__usage=$(echo $CLI | head -c1)
local USAGE__usage=$(echo $CLI | head -c1)
local USAGE__args="$(
{
echo "\\033[0;32m[0-9]\\033[0m^if the first argument is a number 0-9, uses or creates a subsession (default 0)"
echo "$(utils.colors.print green '[0-9]')^if the first argument is a number 0-9, uses or creates a subsession (default 0)"
echo " ^ "
for C in ${CUSTOM_COMMANDS[@]}
do
echo "\\033[0;32m$C\\033[0m^$(SCWRYPTS_KUBECTL_CUSTOM_COMMAND_DESCRIPTION__$C 2>/dev/null)"
done
echo "$(utils.colors.print green ${C})^$(SCWRYPTS_KUBECTL_CUSTOM_COMMAND_DESCRIPTION__$C 2>/dev/null)"
done
} | column -ts '^'
)"
@ -61,18 +61,18 @@ _SCWRYPTS_KUBECTL_DRIVER() {
utility. These functions leverage redis and scwrypts environments to
allow quick selection of contexts and namespaces usable across all
active shell instances.
The scwrypts group 'kubectl' has simple selection executables for
kubecontext and namespace, but also provides the library to enable
enriched, use-case-sensitive setup of kubernetes context.
All actions are scoped to the current SCWRYPTS_ENV
currently : \\033[0;33m$SCWRYPTS_ENV\\033[0m
currently : $(utils.colors.print yellow ${SCWRYPTS_ENV})
"
##########################################
local USER_ARGS=()
local CUSTOM_COMMAND=0
@ -134,9 +134,9 @@ _SCWRYPTS_KUBECTL_DRIVER() {
while [[ $# -gt 0 ]]; do USER_ARGS+=($1); shift 1; done
CHECK_ERRORS --no-fail || return 1
utils.check-errors || return 1
[[ $HELP -eq 1 ]] && { USAGE; return 0; }
[[ $HELP -eq 1 ]] && { utils.io.usage; return 0; }
#####################################################################
@ -154,12 +154,12 @@ _SCWRYPTS_KUBECTL_DRIVER() {
[ $CONTEXT ] && [[ $CLI =~ ^flux$ ]] && CLI_ARGS+=(--context $CONTEXT)
[[ $STRICT -eq 1 ]] && {
[ $CONTEXT ] || ERROR "missing kubectl 'context'"
[ $NAMESPACE ] || ERROR "missing kubectl 'namespace'"
[ $CONTEXT ] || echo.error "missing kubectl 'context'"
[ $NAMESPACE ] || echo.error "missing kubectl 'namespace'"
CHECK_ERRORS --no-fail --no-usage || {
ERROR "with 'strict' settings enabled, context and namespace must be set!"
REMINDER "
utils.check-errors --no-fail --no-usage || {
echo.error "with 'strict' settings enabled, context and namespace must be set!"
echo.reminder "
these values can be set directly with
$(echo $CLI | head -c1) meta set (namespace|context)
"
@ -170,16 +170,16 @@ _SCWRYPTS_KUBECTL_DRIVER() {
[ $NAMESPACE ] && CLI_ARGS+=(--namespace $NAMESPACE)
[[ $VERBOSE -eq 1 ]] && {
REMINDER "
echo.reminder "
context '$CONTEXT'
namespace '$NAMESPACE'
environment '$SCWRYPTS_ENV'
subsession '$SUBSESSION'
"
STATUS "running $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}"
echo.status "running $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}"
} || {
[[ $(_SCWRYPTS_KUBECTL_SETTINGS get context) =~ ^show$ ]] && {
REMINDER "$SCWRYPTS_ENV.$SUBSESSION : $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}"
echo.reminder "$SCWRYPTS_ENV.$SUBSESSION : $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}"
}
}
$CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}
@ -190,7 +190,7 @@ _SCWRYPTS_KUBECTL_DRIVER() {
_SCWRYPTS_KUBECTL_SETTINGS() {
# (get setting-name) or (set setting-name setting-value)
REDIS h$1 ${SCWRYPTS_ENV}:kubectl:settings ${@:2} | grep .
kube.redis h$1 ${SCWRYPTS_ENV}:kubectl:settings ${@:2} | grep .
}
#####################################################################

View File

@ -23,16 +23,16 @@ SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__meta() {
while [[ $# -gt 0 ]]
do
case $1 in
-h | --help ) HELP=1 ;;
( -h | --help ) HELP=1 ;;
set )
( set )
USAGE__usage+=" set"
USAGE__args="set (namespace|context)"
USAGE__description="interactively set a namespace or context for '$SCWRYPTS_ENV'"
case $2 in
namespace | context ) USER_ARGS+=($1 $2 $3); [ $3 ] && shift 1 ;;
-h | --help ) HELP=1 ;;
'' )
( namespace | context ) USER_ARGS+=($1 $2 $3); [ $3 ] && shift 1 ;;
( -h | --help ) HELP=1 ;;
( '' )
: \
&& SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta set context \
&& SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta set namespace \
@ -40,40 +40,40 @@ SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__meta() {
return $?
;;
* ) ERROR "cannot set '$2'" ;;
( * ) echo.error "cannot set '$2'" ;;
esac
shift 1
;;
get )
( get )
USAGE__usage+=" get"
USAGE__args="get (namespace|context|all)"
USAGE__description="output the current namespace or context for '$SCWRYPTS_ENV'"
case $2 in
namespace | context | all ) USER_ARGS+=($1 $2) ;;
( namespace | context | all ) USER_ARGS+=($1 $2) ;;
-h | --help ) HELP=1 ;;
( -h | --help ) HELP=1 ;;
* ) ERROR "cannot get '$2'" ;;
( * ) echo.error "cannot get '$2'" ;;
esac
shift 1
;;
copy )
( copy )
USAGE__usage+=" copy"
USAGE__args+="copy [0-9]"
USAGE__description="copy current subsession ($SUBSESSION) to target subsession id"
case $2 in
[0-9] ) USER_ARGS+=($1 $2) ;;
-h | --help ) HELP=1 ;;
* ) ERROR "target session must be a number [0-9]" ;;
( [0-9] ) USER_ARGS+=($1 $2) ;;
( -h | --help ) HELP=1 ;;
( * ) echo.error "target session must be a number [0-9]" ;;
esac
shift 1
;;
clear | show | hide | strict | loose ) USER_ARGS+=($1) ;;
( clear | show | hide | strict | loose ) USER_ARGS+=($1) ;;
* ) ERROR "no meta command '$1'"
( * ) echo.error "no meta command '$1'"
esac
shift 1
done
@ -81,10 +81,10 @@ SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__meta() {
SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta() {
case $1 in
get )
( get )
[[ $2 =~ ^all$ ]] && {
local CONTEXT=$(REDIS get --prefix current:context | grep . || echo "\\033[1;31mnone set\\033[0m")
local NAMESPACE=$(REDIS get --prefix current:namespace | grep . || echo "\\033[1;31mnone set\\033[0m")
local CONTEXT=$(kube.redis get --prefix current:context | grep . || utils.colors.print bright-red "none set")
local NAMESPACE=$(kube.redis get --prefix current:namespace | grep . || utils.colors.print bright-red "none set")
echo "
environment : $SCWRYPTS_ENV
context : $CONTEXT
@ -92,51 +92,53 @@ SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta() {
CLI settings
command context : $(_SCWRYPTS_KUBECTL_SETTINGS get context)
strict mode : $([[ $STRICT -eq 1 ]] && echo "on" || echo "\\033[1;31moff\\033[0m")
strict mode : $([[ $STRICT -eq 1 ]] && utils.colors.print green on || utils.colors.print bright-red off)
" | sed 's/^ \+//' >&2
return 0
}
REDIS get --prefix current:$2
kube.redis get --prefix current:$2
;;
set )
scwrypts -n --name set-$2 --type zsh --group kubectl -- $3 --subsession $SUBSESSION >/dev/null \
&& SUCCESS "$2 set"
;;
copy )
( set )
: \
&& STATUS "copying $1 to $2" \
&& scwrypts -n --name set-context --type zsh --group kubectl -- --subsession $2 $(k meta get context | grep . || echo 'reset') \
&& scwrypts -n --name set-namespace --type zsh --group kubectl -- --subsession $2 $(k meta get namespace | grep . || echo 'reset') \
&& SUCCESS "subsession $1 copied to $2" \
&& scwrypts -n --name set-$2 --type zsh --group kube -- $3 --subsession $SUBSESSION >/dev/null \
&& k $SUBSESSION meta get $2 \
;
;;
clear )
scwrypts -n --name set-context --type zsh --group kubectl -- --subsession $SUBSESSION reset >/dev/null \
&& SUCCESS "subsession $SUBSESSION reset to default"
( copy )
: \
&& echo.status "copying $1 to $2" \
&& scwrypts -n --name set-context --type zsh --group kube -- --subsession $2 $(k $1 meta get context | grep . || echo 'reset') \
&& scwrypts -n --name set-namespace --type zsh --group kube -- --subsession $2 $(k $1 meta get namespace | grep . || echo 'reset') \
&& echo.success "subsession $1 copied to $2" \
;
;;
show )
( clear )
scwrypts -n --name set-context --type zsh --group kube -- --subsession $SUBSESSION reset >/dev/null \
&& echo.success "subsession $SUBSESSION reset to default"
;;
( show )
_SCWRYPTS_KUBECTL_SETTINGS set context show >/dev/null \
&& SUCCESS "now showing full command context"
&& echo.success "now showing full command context"
;;
hide )
( hide )
_SCWRYPTS_KUBECTL_SETTINGS set context hide >/dev/null \
&& SUCCESS "now hiding command context"
&& echo.success "now hiding command context"
;;
loose )
( loose )
_SCWRYPTS_KUBECTL_SETTINGS set strict 0 >/dev/null \
&& WARNING "now running in 'loose' mode"
&& echo.warning "now running in 'loose' mode"
;;
strict )
( strict )
_SCWRYPTS_KUBECTL_SETTINGS set strict 1 >/dev/null \
&& SUCCESS "now running in 'strict' mode"
&& echo.success "now running in 'strict' mode"
;;
esac
}

View File

@ -1,7 +1,7 @@
#!/bin/zsh
use kubectl --group kubectl
#!/usr/bin/env zsh
use kubectl --group kube
#####################################################################
MAIN() {
KUBECTL__GET_CONTEXT
kube.kubectl.context.get
}

View File

@ -1,7 +1,7 @@
#!/bin/zsh
use kubectl --group kubectl
#!/usr/bin/env zsh
use kubectl --group kube
#####################################################################
MAIN() {
KUBECTL__GET_NAMESPACE
kube.kubectl.namespace.get
}

View File

@ -0,0 +1,10 @@
export ${scwryptsgroup}__type=zsh
export ${scwryptsgroup}__color=$(utils.colors.red)
#####################################################################
SCWRYPTS_STATIC_CONFIG__kubectl+=(
"${scwryptsgrouproot}/.config/static/redis.zsh"
)
source "${scwryptsgrouproot}/driver/kubectl.driver.zsh"

View File

@ -0,0 +1,18 @@
#####################################################################
DEPENDENCIES+=(kubectl)
use redis --group kube
#####################################################################
kube.cli() {
local NAMESPACE="$(kube.redis get --prefix "current:namespace")"
local CONTEXT="$(kube.kubectl.context.get)"
local ARGS=()
[ "${NAMESPACE}" ] && ARGS+=(--namespace "${NAMESPACE}")
[ "${CONTEXT}" ] && ARGS+=(--context "${CONTEXT}")
kubectl ${ARGS[@]} $@
}

View File

@ -0,0 +1,56 @@
#####################################################################
use --group kube kubectl/cli
use --group kube kubectl/namespace
use --group kube redis
#####################################################################
${scwryptsmodule}.get() { kube.redis get --prefix "current:context"; }
${scwryptsmodule}.set() {
local CONTEXT=$1
[ ! "${CONTEXT}" ] && return 1
[[ "${CONTEXT}" =~ reset ]] && {
: \
&& kube.redis del --prefix "current:context" \
&& kube.kubectl.namespace.set reset \
;
return $?
}
: \
&& kube.redis set --prefix "current:context" "${CONTEXT}" \
&& kube.kubectl.namespace.set reset \
;
}
${scwryptsmodule}.select() {
case "$(kube.kubectl.context.list | grep -v '^reset$' | wc -l)" in
( 0 )
echo.error "no contexts available"
return 1
;;
( 1 )
kube.kubectl.context.list | tail -n1
;;
( * )
kube.kubectl.context.list | utils.fzf 'select a context'
;;
esac
}
${scwryptsmodule}.list() {
echo reset
local ALL_CONTEXTS="$(kube.cli config get-contexts -o name | sort -u)"
echo "${ALL_CONTEXTS}" | grep -v '^arn:aws:eks'
[[ "${AWS_ACCOUNT}" ]] && {
echo "${ALL_CONTEXTS}" | grep "^arn:aws:eks:.*:${AWS_ACCOUNT}"
true
} || {
echo "${ALL_CONTEXTS}" | grep '^arn:aws:eks'
}
}

View File

@ -0,0 +1,17 @@
#
# combines kubectl with redis to both facilitate use of kubectl
# between varying contexts/namespaces AND grant persistence between
# terminal sessions
#
# redis wrapper for kubectl
use --group kube kubectl/cli
# simplify commands for kubecontexts
use --group kube kubectl/context
# simplify commands for namespaces
use --group kube kubectl/namespace
# local redirect commands for remote kubernetes services
use --group kube kubectl/service

View File

@ -0,0 +1,23 @@
${scwryptsmodule}.get() { kube.redis get --prefix "current:namespace"; }
${scwryptsmodule}.set() {
local NAMESPACE=$1
[ ! "${NAMESPACE}" ] && return 1
[[ "${NAMESPACE}" =~ reset ]] && {
kube.redis del --prefix "current:namespace"
return $?
}
kube.redis set --prefix "current:namespace" "${NAMESPACE}"
}
${scwryptsmodule}.select() {
kube.kubectl.namespace.list | utils.fzf 'select a namespace'
}
${scwryptsmodule}.list() {
echo reset
echo default
kube.cli get namespaces -o name | sed 's/^namespace\///' | sort | grep -v '^default$'
}

View File

@ -0,0 +1,77 @@
#####################################################################
use --group kube kubectl/cli
use --group kube kubectl/context
use --group kube kubectl/namespace
#####################################################################
${scwryptsmodule}.serve() {
[ "${CONTEXT}" ] || local CONTEXT="$(kube.kubectl.context.get)"
[ "${CONTEXT}" ] || echo.error 'must configure a context in which to serve'
[ "${NAMESPACE}" ] || local NAMESPACE="$(kube.kubectl.namespace.get)"
[ "${NAMESPACE}" ] || echo.error 'must configure a namespace in which to serve'
utils.check-errors --no-usage || return 1
[ "${SERVICE}" ] && SERVICE="$(kube.kubectl.service.list | jq -c "select (.service == \"${SERVICE}\")" || echo ${SERVICE})"
[ "${SERVICE}" ] || local SERVICE="$(kube.kubectl.service.select)"
[ "${SERVICE}" ] || echo.error 'must provide or select a service'
kube.kubectl.service.list | grep -q "^${SERVICE}$"\
|| echo.error "no service '${SERVICE}' in '${CONFIG}/${NAMESPACE}'"
utils.check-errors --no-usage || return 1
##########################################
SERVICE_PASSWORD="$(kube.kubectl.service.get-password)"
kube.kubectl.service.parse
echo.reminder "attempting to serve ${NAMESPACE}/${SERVICE_NAME}:${SERVICE_PORT}"
[ "${SERVICE_PASSWORD}" ] && echo.reminder "password : ${SERVICE_PASSWORD}"
kube.cli port-forward "service/${SERVICE_NAME}" "${SERVICE_PORT}"
}
#####################################################################
${scwryptsmodule}.select() {
[ "${NAMESPACE}" ] || local NAMESPACE="$(kube.kubectl.namespace.get)"
[ "${NAMESPACE}" ] || return 1
local SERVICES="$(kube.kubectl.service.list)"
local SELECTED="$({
echo "namespace service port"
echo ${SERVICES} \
| jq -r '.service + " " + .port' \
| sed "s/^/${NAMESPACE} /" \
;
} \
| column -t \
| utils.fzf 'select a service' --header-lines=1 \
| awk '{print $2;}' \
)"
echo "${SERVICES}" | jq -c "select (.service == \"${SELECTED}\")"
}
${scwryptsmodule}.list() {
kube.cli get service --no-headers\
| awk '{print "{\"service\":\""$1"\",\"ip\":\""$3"\",\"port\":\""$5"\"}"}' \
| jq -c 'select (.ip != "None")' \
;
}
${scwryptsmodule}.get-password() {
[ "${PASSWORD_SECRET}" ] && [ "${PASSWORD_KEY}" ] || return 0
kube.cli get secret "${PASSWORD_SECRET}" -o jsonpath="{.data.${PASSWORD_KEY}}" \
| base64 --decode
}
${scwryptsmodule}.parse() {
SERVICE_NAME="$(echo "${SERVICE}" | jq -r .service)"
SERVICE_PORT="$(echo "${SERVICE}" | jq -r .port | sed 's|/.*$||')"
}

View File

@ -0,0 +1,7 @@
#!/usr/bin/env zsh
use redis --group kube
#####################################################################
MAIN() {
echo $(kube.redis --get-static-definition)
}

View File

@ -5,16 +5,13 @@ DEPENDENCIES+=(
docker
)
# TODO; allow custom redis configuration
export SCWRYPTS_KUBECTL_REDIS=managed
REQUIRED_ENV+=()
REQUIRED_ENV+=(
SCWRYPTS_KUBECTL_REDIS
)
utils.environment.check SCWRYPTS_KUBECTL_REDIS --default managed
#####################################################################
REDIS() {
kube.redis() {
[ ! $USAGE ] && local USAGE="
usage: [...options...]
@ -24,7 +21,7 @@ REDIS() {
-p, --prefix apply dynamic prefix to the next command line argument
--get-prefix output key prefix for current session+subsession
--get-static-definition output the static ZSH function definition for REDIS
--get-static-definition output the static ZSH function definition for kube.redis
additional arguments and options are passed through to 'redis-cli'
"
@ -38,15 +35,15 @@ REDIS() {
while [[ $# -gt 0 ]]
do
case $1 in
-p | --prefix ) USER_ARGS+=("${REDIS_PREFIX}${SCWRYPTS_ENV}:${SUBSESSION}:$2"); shift 1 ;;
case $1 in
( -p | --prefix ) USER_ARGS+=("${REDIS_PREFIX}${SCWRYPTS_ENV}:${SUBSESSION}:$2"); shift 1 ;;
--subsession ) SUBSESSION=$2; shift 1 ;;
( --subsession ) SUBSESSION=$2; shift 1 ;;
--get-prefix ) echo $REDIS_PREFIX; return 0 ;;
--get-static-definition ) ECHO_STATIC_DEFINITION=1 ;;
( --get-prefix ) echo $REDIS_PREFIX; return 0 ;;
( --get-static-definition ) ECHO_STATIC_DEFINITION=1 ;;
* ) USER_ARGS+=($1) ;;
( * ) USER_ARGS+=($1) ;;
esac
shift 1
done
@ -62,14 +59,14 @@ REDIS() {
REDIS_ARGS+=(--raw)
[[ $ECHO_STATIC_DEFINITION -eq 1 ]] && {
echo "REDIS() {\
echo "kube.redis() {\
local USER_ARGS=(); \
[ ! \$SUBSESSION ] && local SUBSESSION=0 ;\
while [[ \$# -gt 0 ]]; \
do \
case \$1 in
-p | --prefix ) USER_ARGS+=(\"${REDIS_PREFIX}\${SCWRYPTS_ENV}:\${SUBSESSION}:\$2\"); shift 1 ;; \
* ) USER_ARGS+=(\$1) ;; \
( -p | --prefix ) USER_ARGS+=(\"${REDIS_PREFIX}\${SCWRYPTS_ENV}:\${SUBSESSION}:\$2\"); shift 1 ;; \
( * ) USER_ARGS+=(\$1) ;; \
esac; \
shift 1; \
done; \
@ -81,9 +78,9 @@ REDIS() {
redis-cli ${REDIS_ARGS[@]} ${USER_ARGS[@]}
}
REDIS ping | grep -qi pong || {
kube.redis ping 2>/dev/null | grep -qi pong || {
RPID=$(docker ps -a | grep scwrypts-kubectl-redis | awk '{print $1;}')
[ $RPID ] && STATUS 'refreshing redis instance' && docker rm -f $RPID
[ $RPID ] && echo.status 'refreshing redis instance' && docker rm -f $RPID
unset RPID
docker run \
@ -92,6 +89,6 @@ REDIS ping | grep -qi pong || {
--publish $SCWRYPTS_KUBECTL_REDIS_PORT__managed:6379 \
redis >/dev/null 2>&1
STATUS 'awaiting redis connection'
until REDIS ping 2>/dev/null | grep -qi pong; do sleep 0.5; done
echo.status 'awaiting redis connection'
until kube.redis ping 2>/dev/null | grep -qi pong; do sleep 0.5; done
}

View File

@ -1,5 +1,5 @@
#!/bin/zsh
use kubectl --group kubectl
#!/usr/bin/env zsh
use kubectl --group kube
#####################################################################
MAIN() {
@ -12,7 +12,7 @@ MAIN() {
options:
--context override context
--namespace override namespace
--subsession REDIS subsession (default 0)
--subsession kube.redis subsession (default 0)
to show a required password on screen, use both:
--password-secret Secret resource
@ -33,17 +33,17 @@ MAIN() {
--password-secret ) PASSWORD_SECRET=$2; shift 1 ;;
--password-key ) PASSWORD_KEY=$2; shift 1 ;;
-h | --help ) USAGE; return 0 ;;
-h | --help ) utils.io.usage; return 0 ;;
* )
[ $SERVICE ] && ERROR "unexpected argument '$2'"
[ $SERVICE ] && echo.error "unexpected argument '$2'"
SERVICE=$1
;;
esac
shift 1
done
CHECK_ERRORS
utils.check-errors --fail
KUBECTL__SERVE
kube.kubectl.serve
}

View File

@ -1,5 +1,5 @@
#!/bin/zsh
use kubectl --group kubectl
#!/usr/bin/env zsh
use kubectl --group kube
#####################################################################
MAIN() {
@ -10,7 +10,7 @@ MAIN() {
context (optional) the full name of the kubeconfig context to set
options:
--subsession REDIS subsession (default 0)
--subsession kube.redis subsession (default 0)
-h, --help show this dialogue and exit
"
@ -22,20 +22,18 @@ MAIN() {
case $1 in
--subsession ) SUBSESSION=$2; shift 1 ;;
-h | --help ) USAGE; return 0 ;;
* )
[ $CONTEXT ] && ERROR "unexpected argument '$2'"
[ $CONTEXT ] && echo.error "unexpected argument '$2'"
CONTEXT=$1
;;
esac
shift 1
done
[ $CONTEXT ] || CONTEXT=$(KUBECTL__SELECT_CONTEXT)
[ $CONTEXT ] || ERROR 'must provide or select a valid kube context'
[ $CONTEXT ] || CONTEXT=$(kube.kubectl.context.select)
[ $CONTEXT ] || echo.error 'must provide or select a valid kube context'
CHECK_ERRORS
utils.check-errors --fail
KUBECTL__SET_CONTEXT $CONTEXT
kube.kubectl.context.set $CONTEXT
}

View File

@ -1,5 +1,5 @@
#!/bin/zsh
use kubectl --group kubectl
#!/usr/bin/env zsh
use kubectl --group kube
#####################################################################
MAIN() {
@ -10,7 +10,7 @@ MAIN() {
namespace (optional) the full name of the namespace context to set
options:
--subsession REDIS subsession (default 0)
--subsession kube.redis subsession (default 0)
-h, --help show this dialogue and exit
"
@ -22,20 +22,20 @@ MAIN() {
case $1 in
--subsession ) SUBSESSION=$2; shift 1 ;;
-h | --help ) USAGE; return 0 ;;
-h | --help ) utils.io.usage; return 0 ;;
* )
[ $NAMESPACE ] && ERROR "unexpected argument '$2'"
[ $NAMESPACE ] && echo.error "unexpected argument '$2'"
NAMESPACE=$1
;;
esac
shift 1
done
[ $NAMESPACE ] || NAMESPACE=$(KUBECTL__SELECT_NAMESPACE)
[ $NAMESPACE ] || ERROR 'must provide or select a valid namespace'
[ $NAMESPACE ] || NAMESPACE=$(kube.kubectl.namespace.select)
[ $NAMESPACE ] || echo.error 'must provide or select a valid namespace'
CHECK_ERRORS
utils.check-errors --fail
KUBECTL__SET_NAMESPACE $NAMESPACE
kube.kubectl.namespace.set $NAMESPACE
}

View File

@ -1,11 +0,0 @@
SCWRYPTS_GROUPS+=(kubectl)
export SCWRYPTS_TYPE__kubectl=zsh
export SCWRYPTS_ROOT__kubectl="$SCWRYPTS_ROOT__scwrypts/plugins/kubectl"
export SCWRYPTS_COLOR__kubectl='\033[0;31m'
SCWRYPTS_STATIC_CONFIG__kubectl+=(
"$SCWRYPTS_ROOT__kubectl/.config/static/redis.zsh"
)
source "$SCWRYPTS_ROOT__kubectl/driver/kubectl.driver.zsh"

View File

@ -1,158 +0,0 @@
#####################################################################
DEPENDENCIES+=(
kubectl
)
REQUIRED_ENV+=()
use redis --group kubectl
#####################################################################
KUBECTL() {
local NAMESPACE=$(REDIS get --prefix "current:namespace")
local CONTEXT=$(KUBECTL__GET_CONTEXT)
local KUBECTL_ARGS=()
[ $NAMESPACE ] && KUBECTL_ARGS+=(--namespace $NAMESPACE)
[ $CONTEXT ] && KUBECTL_ARGS+=(--context $CONTEXT)
kubectl ${KUBECTL_ARGS[@]} $@
}
#####################################################################
KUBECTL__GET_CONTEXT() { REDIS get --prefix "current:context"; }
KUBECTL__SET_CONTEXT() {
local CONTEXT=$1
[ ! $CONTEXT ] && return 1
[[ $CONTEXT =~ reset ]] && {
: \
&& REDIS del --prefix "current:context" \
&& KUBECTL__SET_NAMESPACE reset \
;
return $?
}
: \
&& REDIS set --prefix "current:context" "$CONTEXT" \
&& KUBECTL__SET_NAMESPACE reset \
;
}
KUBECTL__SELECT_CONTEXT() {
KUBECTL__LIST_CONTEXTS | FZF 'select a context'
}
KUBECTL__LIST_CONTEXTS() {
echo reset
local ALL_CONTEXTS=$(KUBECTL config get-contexts -o name | sort)
echo $ALL_CONTEXTS | grep -v '^arn:aws:eks'
[[ $AWS_ACCOUNT ]] && {
echo $ALL_CONTEXTS | grep "^arn:aws:eks:.*:$AWS_ACCOUNT"
true
} || {
echo $ALL_CONTEXTS | grep '^arn:aws:eks'
}
}
#####################################################################
KUBECTL__GET_NAMESPACE() { REDIS get --prefix "current:namespace"; }
KUBECTL__SET_NAMESPACE() {
local NAMESPACE=$1
[ ! $NAMESPACE ] && return 1
[[ $NAMESPACE =~ reset ]] && {
REDIS del --prefix "current:namespace"
return $?
}
REDIS set --prefix "current:namespace" "$NAMESPACE"
}
KUBECTL__SELECT_NAMESPACE() {
KUBECTL__LIST_NAMESPACES | FZF 'select a namespace'
}
KUBECTL__LIST_NAMESPACES() {
echo reset
echo default
KUBECTL get namespaces -o name | sed 's/^namespace\///' | sort
}
#####################################################################
KUBECTL__SERVE() {
[ $CONTEXT ] || local CONTEXT=$(KUBECTL__GET_CONTEXT)
[ $CONTEXT ] || ERROR 'must configure a context in which to serve'
[ $NAMESPACE ] || local NAMESPACE=$(KUBECTL__GET_NAMESPACE)
[ $NAMESPACE ] || ERROR 'must configure a namespace in which to serve'
CHECK_ERRORS --no-fail --no-usage || return 1
[ $SERVICE ] && SERVICE=$(KUBECTL__LIST_SERVICES | jq -c "select (.service == \"$SERVICE\")" || echo $SERVICE)
[ $SERVICE ] || local SERVICE=$(KUBECTL__SELECT_SERVICE)
[ $SERVICE ] || ERROR 'must provide or select a service'
KUBECTL__LIST_SERVICES | grep -q "^$SERVICE$"\
|| ERROR "no service '$SERVICE' in '$CONFIG/$NAMESPACE'"
CHECK_ERRORS --no-fail --no-usage || return 1
##########################################
SERVICE_PASSWORD="$(KUBECTL__GET_SERVICE_PASSWORD)"
KUBECTL__SERVICE_PARSE
REMINDER "attempting to serve ${NAMESPACE}/${SERVICE_NAME}:${SERVICE_PORT}"
[ $SERVICE_PASSWORD ] && REMINDER "password : $SERVICE_PASSWORD"
KUBECTL port-forward service/$SERVICE_NAME $SERVICE_PORT
}
KUBECTL__SELECT_SERVICE() {
[ $NAMESPACE ] || local NAMESPACE=$(KUBECTL__GET_NAMESPACE)
[ $NAMESPACE ] || return 1
local SERVICES=$(KUBECTL__LIST_SERVICES)
local SELECTED=$({
echo "namespace service port"
echo $SERVICES \
| jq -r '.service + " " + .port' \
| sed "s/^/$NAMESPACE /" \
;
} \
| column -t \
| FZF 'select a service' --header-lines=1 \
| awk '{print $2;}' \
)
echo $SERVICES | jq -c "select (.service == \"$SELECTED\")"
}
KUBECTL__LIST_SERVICES() {
KUBECTL get service --no-headers\
| awk '{print "{\"service\":\""$1"\",\"ip\":\""$3"\",\"port\":\""$5"\"}"}' \
| jq -c 'select (.ip != "None")' \
;
}
KUBECTL__GET_SERVICE_PASSWORD() {
[ $PASSWORD_SECRET ] && [ $PASSWORD_KEY ] || return 0
KUBECTL get secret $PASSWORD_SECRET -o jsonpath="{.data.$PASSWORD_KEY}" \
| base64 --decode
}
KUBECTL__SERVICE_PARSE() {
SERVICE_NAME=$(echo $SERVICE | jq -r .service)
SERVICE_PORT=$(echo $SERVICE | jq -r .port | sed 's|/.*$||')
}

View File

@ -1,7 +0,0 @@
#!/bin/zsh
use redis --group kubectl
#####################################################################
MAIN() {
echo $(REDIS --get-static-definition)
}