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

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

- Introducing an optional plugin for `kubectl` facilitation! Check out
  'plugins/kubectl/README.md' for more details.

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

- The function which lists all available scwrypts now ignores
  directories with a top-level base called "plugins." If this is a name
  conflict, you will need to define your own
  `SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__<group>` function!

  (ref the changes in 'zsh/lib/scwrypts/run.module.zsh')
This commit is contained in:
Wryn (yage) Wagner 2023-08-28 18:42:38 -06:00
parent e199e9bf91
commit ab567f6950
17 changed files with 512 additions and 0 deletions

View File

@ -0,0 +1,2 @@
#!/bin/zsh
export SCWRYPTS_KUBECTL_REDIS=

View File

@ -0,0 +1 @@
SCWRYPTS_KUBECTL_REDIS | (currently only 'managed') 'managed' or 'custom' redis configuration

View File

@ -0,0 +1,4 @@
export SCWRYPTS_KUBECTL_REDIS_HOST__managed=127.0.0.1
export SCWRYPTS_KUBECTL_REDIS_PORT__managed=26379
export SCWRYPTS_KUBECTL_REDIS_AUTH__managed=
export SCWRYPTS_KUBECTL_REDIS_KEY_PREFIX__managed=

10
plugins/kubectl/README.md Normal file
View File

@ -0,0 +1,10 @@
# Kubernetes `kubectl` Helper Plugin
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`.

16
plugins/kubectl/get-context Executable file
View File

@ -0,0 +1,16 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use kubectl --group kubectl
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
KUBECTL__GET_CONTEXT
}
#####################################################################
MAIN $@

16
plugins/kubectl/get-namespace Executable file
View File

@ -0,0 +1,16 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use kubectl --group kubectl
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
KUBECTL__GET_NAMESPACE
}
#####################################################################
MAIN $@

View File

@ -0,0 +1,31 @@
#####################################################################
command -v compdef >/dev/null 2>&1 || return 0
#####################################################################
_k() {
local C=$(k meta get context)
local NS=$(k meta get namespace)
local KUBEWORDS=(kubectl)
[ $C ] && KUBEWORDS+=(--context $C)
[ $NS ] && KUBEWORDS+=(--namespace $NS)
words="$KUBEWORDS ${words[@]:1}"
_kubectl
}
compdef _k k
#####################################################################
_h() {
local C=$(k meta get context)
local NS=$(k meta get namespace)
local KUBEWORDS=(kubectl)
[ $C ] && KUBEWORDS+=(--context $C)
[ $NS ] && KUBEWORDS+=(--namespace $NS)
words="$KUBEWORDS ${words[@]:1}"
_helm
}
compdef _h h

View File

@ -0,0 +1,173 @@
[[ $SCWRYPTS_KUBECTL_DRIVER_READY -eq 1 ]] && return 0
k() { _SCWRYPTS_KUBECTL_DRIVER kubectl $@; }
h() { _SCWRYPTS_KUBECTL_DRIVER helm $@; }
_SCWRYPTS_KUBECTL_DRIVER() {
[ ! $SCWRYPTS_ENV ] && {
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)"
local CLI="$1"; shift 1
local SCWRYPTS_GROUP CUSTOM_COMMANDS=(meta)
for SCWRYPTS_GROUP in ${SCWRYPTS_GROUPS[@]}
do
CUSTOM_COMMANDS+=($(eval echo '$SCWRYPTS_KUBECTL_CUSTOM_COMMANDS__'$SCWRYPTS_GROUP))
done
##########################################
local USAGE_ARGS="$(for C in ${CUSTOM_COMMANDS[@]}; do echo " - $C"; done)"
local USAGE_OPTIONS="
-n, --namespace set the namespace for commands in '$SCWRYPTS_ENV'
-k, --context set the context for commands in '$SCWRYPTS_ENV'
"
local DESCRIPTION="
Provides 'k' (kubectl) and 'h' (helm) shorthands to the
respective 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.
"
local USAGE="
usage: $(echo $CLI | head -c1) [...args...] [...options...] -- [...$CLI options...]
args: -
options: -
-h, --help display this help dialogue
-v, --verbose output debugging information
DESCRIPTION
"
##########################################
local USER_ARGS=()
local CUSTOM_COMMAND=0
PARAMETER_OVERRIDES+=
local VERBOSE=0
while [[ $# -gt 0 ]]
do
case $1 in
-v | --verbose ) VERBOSE=1 ;;
-n | --namespace )
echo "TODO: set namespace ('$2')" >&2
USER_ARGS+=(--namespace $2); shift 1
;;
-k | --context | --kube-context )
echo "TODO: set context ('$2')" >&2
[[ $CLI =~ ^helm$ ]] && USER_ARGS+=(--kube-context $2)
[[ $CLI =~ ^kubectl$ ]] && USER_ARGS+=(--context $2)
shift 1
;;
meta )
CUSTOM_COMMAND=meta
USAGE_ARGS=" - get\n - set"
USAGE_OPTIONS=''
DESCRIPTION="perform meta-operations on $(echo $CLI | head -c1) for '$SCWRYPTS_ENV'"
case $2 in
-h | --help ) HELP=1 ;;
set )
USAGE_ARGS=" set (namespace|context)"
DESCRIPTION="interactively set a namespace or context for '$SCWRYPTS_ENV'"
case $3 in
namespace | context ) USER_ARGS+=($2 $3) ;;
-h | --help ) HELP=1 ;;
* ) ERROR "cannot set '$3'" >&2 ;;
esac
shift 1
;;
get )
USAGE_ARGS=" get (namespace|context)"
DESCRIPTION="output the current namespace or context for '$SCWRYPTS_ENV'"
case $3 in
namespace | context ) USER_ARGS+=($2 $3) ;;
-h | --help ) HELP=1 ;;
* ) ERROR "cannot get '$3'" >&2 ;;
esac
shift 1
;;
esac
shift 1
;;
-h | --help ) HELP=1 ;;
-- ) shift 1; break ;;
* ) USER_ARGS+=($1) ;;
esac
shift 1
done
while [[ $# -gt 0 ]]; do USER_ARGS+=($1); shift 1; done
CHECK_ERRORS --no-fail 2>&1 | sed 's/scwrypts -- //' >&2 || return 1
[[ $HELP -eq 1 ]] && {
[[ ! $CUSTOM_COMMAND =~ ^0$ ]] \
&& USAGE=$(echo $USAGE | sed "s/[[]\\.\\.\\.args\\.\\.\\.[]]/$CUSTOM_COMMAND &/")
USAGE=$(echo $USAGE | perl -pe "
s/args: -/args:\n$USAGE_ARGS/;
s^options: -^options:$USAGE_OPTIONS^;
s/DESCRIPTION/$DESCRIPTION/;
")
USAGE 2>&1 | sed 's/scwrypts -- //' >&2
return 0
}
#####################################################################
case $CUSTOM_COMMAND in
0 )
local CLI_ARGS=()
local CONTEXT=$(k meta get context)
local NAMESPACE=$(k meta get namespace)
[ $CONTEXT ] && [[ $CLI =~ ^helm$ ]] && CLI_ARGS+=(--kube-context $CONTEXT)
[ $CONTEXT ] && [[ $CLI =~ ^kubectl$ ]] && CLI_ARGS+=(--context $CONTEXT)
[ $NAMESPACE ] && CLI_ARGS+=(--namespace $NAMESPACE)
[[ $VERBOSE -eq 1 ]] && {
INFO "
using context '$CONTEXT'
using namespace '$NAMESPACE'
"
STATUS "running $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}"
}
$CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}
;;
* ) eval 'SCWRYPTS_KUBECTL_CUSTOM_COMMAND__'$CUSTOM_COMMAND ${USER_ARGS[@]} ;;
esac
}
SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta() {
case $1 in
get ) REDIS get --prefix current:$2; return 0 ;;
set ) scwrypts --name set-$2 --type zsh --group kubectl ;;
esac
}
#####################################################################
source ${0:a:h}/kubectl.driver.completion.zsh

View File

@ -0,0 +1,11 @@
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/kubectl.driver.zsh"

View File

@ -0,0 +1,79 @@
#####################################################################
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 =~ default ]] && {
: \
&& REDIS del --prefix "current:context" \
&& KUBECTL__SET_NAMESPACE default \
;
return $?
}
: \
&& REDIS set --prefix "current:context" "$CONTEXT" \
&& KUBECTL__SET_NAMESPACE default \
;
}
KUBECTL__SELECT_CONTEXT() {
KUBECTL__LIST_CONTEXTS | FZF 'select a context'
}
KUBECTL__LIST_CONTEXTS() {
echo default
KUBECTL config get-contexts -o name | sort
}
#####################################################################
KUBECTL__GET_NAMESPACE() { REDIS get --prefix "current:namespace"; }
KUBECTL__SET_NAMESPACE() {
local NAMESPACE=$1
[ ! $NAMESPACE ] && return 1
[[ $NAMESPACE =~ default ]] && {
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 default
KUBECTL get namespaces -o name | sed 's/^namespace\///' | sort
}

View File

@ -0,0 +1,90 @@
#####################################################################
DEPENDENCIES+=(
redis-cli
docker
)
# TODO; allow custom redis configuration
export SCWRYPTS_KUBECTL_REDIS=managed
REQUIRED_ENV+=(
SCWRYPTS_KUBECTL_REDIS
)
#####################################################################
REDIS() {
[ ! $USAGE ] && local USAGE="
usage: [...options...]
options:
-p, --prefix apply dynamic prefix to the next command line argument
--get-prefix output key prefix for current session
--get-static-definition output the static ZSH function definition for REDIS
other arguments are passed through to redis-cli
"
local REDIS_ARGS=() USER_ARGS=()
local REDIS_PREFIX=$(eval echo '$SCWRYPTS_KUBECTL_REDIS_KEY_PREFIX__'$SCWRYPTS_KUBECTL_REDIS)
local ECHO_STATIC_DEFINITION=0
while [[ $# -gt 0 ]]
do
case $1 in
-p | --prefix ) USER_ARGS+=("${SCWRYPTS_ENV}:${REDIS_PREFIX}$2"); shift 1 ;;
--get-prefix ) echo $REDIS_PREFIX; return 0 ;;
--get-static-definition ) ECHO_STATIC_DEFINITION=1 ;;
* ) USER_ARGS+=($1) ;;
esac
shift 1
done
local REDIS_HOST=$(eval echo '$SCWRYPTS_KUBECTL_REDIS_HOST__'$SCWRYPTS_KUBECTL_REDIS)
local REDIS_PORT=$(eval echo '$SCWRYPTS_KUBECTL_REDIS_PORT__'$SCWRYPTS_KUBECTL_REDIS)
local REDIS_AUTH=$(eval echo '$SCWRYPTS_KUBECTL_REDIS_AUTH__'$SCWRYPTS_KUBECTL_REDIS)
[ $REDIS_HOST ] && REDIS_ARGS+=(-h $REDIS_HOST)
[ $REDIS_PORT ] && REDIS_ARGS+=(-p $REDIS_PORT)
[ $REDIS_AUTH ] && REDIS_ARGS+=(-a $REDIS_AUTH)
REDIS_ARGS+=(--raw)
[[ $ECHO_STATIC_DEFINITION -eq 1 ]] && {
echo "REDIS() {\
local USER_ARGS=(); \
while [[ \$# -gt 0 ]]; \
do \
case \$1 in
-p | --prefix ) USER_ARGS+=(\"\${SCWRYPTS_ENV}:${REDIS_PREFIX}\$2\"); shift 1 ;; \
* ) USER_ARGS+=(\$1) ;; \
esac; \
shift 1; \
done; \
redis-cli ${REDIS_ARGS[@]} \${USER_ARGS[@]}; \
}" | sed 's/\s\+/ /g'
return 0
}
redis-cli ${REDIS_ARGS[@]} ${USER_ARGS[@]}
}
REDIS ping | grep -qi pong || {
RPID=$(docker ps -a | grep scwrypts-kubectl-redis | awk '{print $1;}')
[ $RPID ] && STATUS 'refreshing redis instance' && docker rm -f $RPID
unset RPID
docker run \
--detach \
--name scwrypts-kubectl-redis \
--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
}

View File

@ -0,0 +1,11 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use redis --group kubectl
CHECK_ENVIRONMENT
#####################################################################
echo $(REDIS --get-static-definition)

28
plugins/kubectl/set-context Executable file
View File

@ -0,0 +1,28 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use kubectl --group kubectl
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
local USAGE="
usage: [context]
args:
context the full name of the kubeconfig context to set
"
local CONTEXT="$1"
[ $CONTEXT ] || $(KUBECTL__SELECT_CONTEXT)
[ $CONTEXT ] || ERROR 'must provide or select a valid kube context'
CHECK_ERRORS
KUBECTL__SET_CONTEXT $CONTEXT
}
#####################################################################
MAIN $@

28
plugins/kubectl/set-namespace Executable file
View File

@ -0,0 +1,28 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use kubectl --group kubectl
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
local USAGE="
usage: [namespace]
args:
namespace the full name of the namespace to set
"
local NAMESPACE="$1"
[ $NAMESPACE ] || $(KUBECTL__SELECT_NAMESPACE)
[ $NAMESPACE ] || ERROR 'must provide or select a valid namespace'
CHECK_ERRORS
KUBECTL__SET_NAMESPACE $NAMESPACE
}
#####################################################################
MAIN $@

View File

@ -13,3 +13,8 @@ SCWRYPTS_ENV_SHORTCUT='' # CTRL + /
SCWRYPTS_ENV_PATH="$SCWRYPTS_CONFIG_PATH/environments"
SCWRYPTS_LOG_PATH="$SCWRYPTS_DATA_PATH/logs"
SCWRYPTS_OUTPUT_PATH="$SCWRYPTS_DATA_PATH/output"
# disabled = 0; enabled = 1
SCWRYPTS_PLUGIN_ENABLED__kubectl=1

View File

@ -38,5 +38,11 @@ SCWRYPTS_GROUPS=($(echo $SCWRYPTS_GROUPS | sed 's/\s\+/\n/g' | sort -u))
source "$SCWRYPTS_ROOT/zsh/lib/config.group.zsh" \
|| FAIL 69 'failed to set up scwrypts group; aborting'
#####################################################################
[[ $SCWRYPTS_PLUGIN_ENABLED__kubectl -eq 1 ]] && {
source "$SCWRYPTS_ROOT/plugins/kubectl/kubectl.scwrypts.zsh"
}
#####################################################################
__SCWRYPT=1 # arbitrary; indicates currently inside a scwrypt

View File

@ -54,6 +54,7 @@ SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__scwrypts() {
| grep -v '\.git' \
| grep -v 'node_modules' \
| sed "s/^\\.\\///; s/\\.[^.]*$//; s/^/$GROUP_TYPE/" \
| grep -v '^plugins/' \
;
}