#!/bin/bash set -e -o pipefail shq() {( while [ $# -gt 0 ];do echo -n "'$(echo -n "$1" | sed -e "s/'/'\"'\"'/g")'" shift done )} json() {( # json encode the argument jq -n --arg v "$@" '$v' )} GARAGE_NAMESPACE="${GARAGE_NAMESPACE-garage}" ARGS="$(shq "$@")" ZERO="$0" ONE="$1" ONE_UNDER="$(echo -n "$ONE" | tr - _)" NL="$(echo)" enumerate_pods() { # enumerate kubernetes-based garage pods kubectl get pod -n "$GARAGE_NAMESPACE" -l app=garage -o json | yq -ot '.items[] | [ .metadata.name, .status.podIP, .spec.containers[].ports[]|select(.name == "rpc")|.hostPort, .spec.nodeName ]' | while read -r pod ip port node;do gnid="$(grun "$pod" node id -q)" printf "%${#pod}s %25s %s\n" $pod $node "$gnid@$ip:$port" done } get_ids() { # get the public id of all discoverable servers enumerate_pods | while read -r pod node gnid;do echo "$gnid" done } iterstats() { # get stats from running garage nodes via iteration over discovered ids get_ids | while read -r id;do garage -h "$id" stats done } grun() { TARGET="$1" shift kubectl exec -n "$GARAGE_NAMESPACE" -c garage "$TARGET" -- garage "$@" } garage() { # run an arbitrary garage command via a random garage pod grun ds/garage "$@" } generate_secrets() { # generates secrets required to run garage kubectl create secret -n "$GARAGE_NAMESPACE" generic garage-secrets \ --from-literal=admin-token="$( openssl rand -base64 32 )" \ --from-literal=metrics-token="$( openssl rand -base64 32 )" \ --from-literal=rpc-secret="$( openssl rand -hex 32 )" } generate_layout() {( # generates a sample layout, (args are included verbatim, e.g. -t k8s) enumerate_pods | while read -r pod node gnid;do kubectl get node/$node -o json | jq -r --arg zero "$ZERO" ' [ $zero, "garage", "layout", "assign", "-t", .metadata.name, "-c", "\(.metadata.labels["strudelline.net/garage-meta-free-bytes"]|tonumber/1024/1024/1024|floor)G" ]+$ARGS.positional | @sh' --args -- "$@" "${gnid%%@*}" | while read -r cmd;do eval "set $cmd" printf " %q" "$@" | cut -c 2- done done )} make_bucket() { # make a bucket along with metadata in a namespace TARGETBUCKET="$1" TARGETKEYNAME="${2-$TARGETBUCKET}-app-key" TARGETNS="${3-$TARGETBUCKET}" TARGETSECRET="${3-$TARGETKEYNAME}" kubectl get namespace "$TARGETNS" > /dev/null garage bucket create "$TARGETBUCKET" eval "$( (garage key info "$TARGETKEYNAME" 2> /dev/null || garage key create "$TARGETKEYNAME") | awk ' /^key id: /i {printf("KID=%s\n", $3);} /^secret key: /i {printf("SK=%s\n", $3);} ')" garage bucket allow --read --write --owner "$TARGETBUCKET" --key "$TARGETKEYNAME" kubectl create secret generic \ -n "$TARGETNS" "$TARGETSECRET" \ --type kubernetes.io/basic-auth \ --from-literal=username="$KID" \ --from-literal=password="$SK" \ --from-literal=AWS_ACCESS_KEY_ID="$KID" \ --from-literal=AWS_SECRET_ACCESS_KEY="$SK" \ --from-literal=bucket="$TARGETBUCKET" kubectl label -n "$TARGETNS" secret/$TARGETSECRET bucket="$TARGETBUCKET" key="$TARGETKEYNAME" } connect() { # attempt to connect all nodes allids="$(get_ids)" primary="$(echo "$allids" | head -1)" echo "$allids" | sed 1d | while read -r id;do garage -h $primary node connect "$id" done } env() { # connect your local garage cli to a random node jq -n -r \ --argjson secret "$(kubectl get secret -n "$GARAGE_NAMESPACE" garage-secrets -o json)" \ --arg gnid "$(get_ids | head -1)" \ ' rpc_secret=\($secret.data."rpc-secret")", RPC_HOST=\($gnid)" ' } help() {( # this help exec 1>&2 echo "usage: $0 [options]" echo echo GARAGE SUBCOMMANDS: ( 2>&1 garage --help || true ) | awk 'p==1&&/^ / {print lc,$0;next} p==1 {lc=$1;print;} /^SUBCOMMANDS:$/ {p=1}' | while read -r cmd help;do printf " %-25s %s\n" "garage $cmd" "$help" done echo echo "GARAGE CLUSTER TOOLS:" grep -E "^[a-z_]+[(][)] {[(]? # .*" "$ZERO" | sed -Ee 's@[(][)] [{][(]? # @: @' | while read cmd help;do printf " %-25s %s\n" "$(echo -n $cmd | tr _ -)" "$help" done echo )} if [ "x$1" = x ];then help exit 1 fi # we translate - to _ to allow enumerate-pods or enumerate_pods. # it also changes -h to _h. if [ "x$ONE" = "x-h" ];then help exit 0 fi shift 1 "$ONE_UNDER" "$@"