ctctl/install.sh

249 lines
8.5 KiB
Bash
Raw Normal View History

2023-07-05 15:28:07 +02:00
#!/usr/bin/env bash
BIN_DIR=~/bin
2023-07-11 21:39:23 +02:00
DEFAULT_USER=${CTCTL_USER:-$(whoami | sed -r 's/\@.*//')}
DEFAULT_DOMAIN=${CTCTL_DOMAIN:-consul}
read -p "Enter your user login [${DEFAULT_USER}] " INSTALL_USER
INSTALL_USER=${INSTALL_USER:-${DEFAULT_USER}}
read -p "Enter container domain [${DEFAULT_DOMAIN}] " INSTALL_DOMAIN
INSTALL_DOMAIN=${INSTALL_DOMAIN:-${DEFAULT_DOMAIN}}
2023-07-05 15:28:07 +02:00
function get_gh_release() {
2023-07-11 21:39:23 +02:00
local VERSION
2023-07-11 22:10:52 +02:00
# Check if cached version file exists and has been modified less than 6 hours ago
if [[ -e "~/.ctctl/versions/$1" && $(stat -c %Y -- "~/.ctctl/versions/$1") -gt $(($EPOCHSECONDS - 21600)) ]]; then
2023-07-11 21:39:23 +02:00
VERSION=$(cat ~/.ctctl/versions/$1)
else
VERSION=$(curl --silent "https://api.github.com/repos/$1/releases/latest" | \
2023-08-21 11:19:53 +02:00
jq -r .tag_name | sed -E 's/^v//')
2023-07-11 21:39:23 +02:00
# Cache the last version so we don't ask github API every time
mkdir -p $(dirname ~/.ctctl/versions/$1)
echo -n ${VERSION} > ~/.ctctl/versions/$1
fi
echo ${VERSION}
2023-07-05 15:28:07 +02:00
}
# Detect OS
SYSTEM="$(uname -s)"
case "${SYSTEM}" in
Linux*) MACHINE=linux;;
Darwin*) MACHINE=darwin;;
*) MACHINE=unknown;;
esac
# Architesture, so we support Apple M1/M2 chips
CPU=$(uname -m)
case "${ARCH}" in
x86_64) ARCH=amd64;;
arm64) ARCH=arm64;;
*) ARCH=amd64;;
esac
2023-07-05 15:28:07 +02:00
if [ "${MACHINE}" = "unknown" ]; then
2023-07-11 21:39:23 +02:00
echo "Unsupported system"
2023-07-05 15:28:07 +02:00
exit 1
fi
# Check that we have the required utilities
for TOOL in jq openssl curl unzip fzf git; do
2023-07-05 15:28:07 +02:00
if ! command -v $TOOL > /dev/null 2>&1; then
2023-07-11 21:39:23 +02:00
echo "$TOOL not found. Please install it first"
2023-07-05 15:28:07 +02:00
exit 1
fi
done
[ -d ${BIN_DIR} ] || mkdir -p ${BIN_DIR}
2023-07-11 21:39:23 +02:00
mkdir -p ~/.ctctl/versions
2023-07-05 15:28:07 +02:00
# Install hashicorp binaries
for UTIL in vault consul consul-template nomad levant; do
LAST_VER=$(get_gh_release "hashicorp/${UTIL}")
2023-07-11 21:39:23 +02:00
echo "Last version of ${UTIL} is v${LAST_VER}"
2023-07-05 15:28:07 +02:00
if [ -x "${BIN_DIR}/${UTIL}" ]; then
2023-08-21 11:19:53 +02:00
CUR_VER=$(${BIN_DIR}/${UTIL} --version 2>/dev/null | head -1 | sed -E 's/.* v([0-9]+(\.[0-9]+)*).*/\1/')
2023-07-11 21:39:23 +02:00
echo "${UTIL} v${CUR_VER} is installed"
2023-07-05 15:28:07 +02:00
fi
if [ ! -x "${BIN_DIR}/${UTIL}" ] || ! echo -e "${LAST_VER}\n${CUR_VER}" | sort --version-sort --check > /dev/null 2>&1; then
2023-07-11 21:39:23 +02:00
echo "Installing ${UTIL} v${LAST_VER}"
curl -L -O https://releases.hashicorp.com/${UTIL}/${LAST_VER}/${UTIL}_${LAST_VER}_${MACHINE}_${ARCH}.zip
unzip -o -d ~/bin/ ${UTIL}_${LAST_VER}_${MACHINE}_${ARCH}.zip
rm -f ${UTIL}_${LAST_VER}_${MACHINE}_${ARCH}.zip
2023-07-05 15:28:07 +02:00
else
2023-07-11 21:39:23 +02:00
echo "Last ${UTIL} version (v${CUR_VER}) is already installed"
2023-07-05 15:28:07 +02:00
fi
done
## Install logcli
for UTIL in logcli; do
LAST_VER=$(get_gh_release "grafana/loki")
if [ -x "${BIN_DIR}/${UTIL}" ]; then
2023-08-21 11:19:53 +02:00
CUR_VER=$(${BIN_DIR}/${UTIL} --version 2>&1 | head -1 | sed -E 's/.* version ([0-9]+(\.[0-9]+)*).*/\1/')
2023-07-11 21:39:23 +02:00
echo "${UTIL} v${CUR_VER} is installed"
2023-07-05 15:28:07 +02:00
fi
if [ ! -x "${BIN_DIR}/${UTIL}" ] || ! echo -e "${LAST_VER}\n${CUR_VER}" | sort --version-sort --check > /dev/null 2>&1; then
2023-07-11 21:39:23 +02:00
echo "Installing ${UTIL} v${LAST_VER}"
curl -L -O https://github.com/grafana/loki/releases/download/v${LAST_VER}/logcli-${MACHINE}-${ARCH}.zip
unzip -o -d ~/bin/ ${UTIL}-${MACHINE}-${ARCH}.zip
rm -f ${UTIL}-${MACHINE}-${ARCH}.zip
mv -f ~/bin/logcli-${MACHINE}-${ARCH} ~/bin/logcli
2023-07-05 15:28:07 +02:00
else
2023-07-11 21:39:23 +02:00
echo "Last ${UTIL} version (v${CUR_VER}) is already installed"
2023-07-05 15:28:07 +02:00
fi
done
# Install yq
for UTIL in yq; do
LAST_VER=$(get_gh_release "mikefarah/yq")
if [ -x "${BIN_DIR}/${UTIL}" ]; then
2023-08-21 11:19:53 +02:00
CUR_VER=$(${BIN_DIR}/${UTIL} --version 2>&1 | sed -E 's/.* version v([0-9]+(\.[0-9]+)*).*/\1/')
2023-07-11 21:39:23 +02:00
echo "${UTIL} v${CUR_VER} is installed"
2023-07-05 15:28:07 +02:00
fi
if [ ! -x "${BIN_DIR}/${UTIL}" ] || ! echo -e "${LAST_VER}\n${CUR_VER}" | sort --version-sort --check > /dev/null 2>&1; then
2023-07-11 21:39:23 +02:00
echo "Installing ${UTIL} v${LAST_VER}"
curl -L -o ${BIN_DIR}/${UTIL} https://github.com/mikefarah/${UTIL}/releases/download/v${LAST_VER}/${UTIL}_${MACHINE}_${ARCH}
2023-08-21 11:19:53 +02:00
chmod +x ${BIN_DIR}/${UTIL}
else
echo "Last ${UTIL} version (v${CUR_VER}) is already installed"
fi
done
# Install gomplate
for UTIL in gomplate; do
LAST_VER=$(get_gh_release "hairyhenderson/${UTIL}")
if [ -x "${BIN_DIR}/${UTIL}" ]; then
CUR_VER=$(${BIN_DIR}/${UTIL} --version 2>&1 | sed -E 's/gomplate version ([0-9]+(\.[0-9]+)*)/\1/')
echo "${UTIL} v${CUR_VER} is installed"
fi
if [ ! -x "${BIN_DIR}/${UTIL}" ] || ! echo -e "${LAST_VER}\n${CUR_VER}" | sort --version-sort --check > /dev/null 2>&1; then
echo "Installing ${UTIL} v${LAST_VER}"
curl -L -o ${BIN_DIR}/${UTIL} https://github.com/hairyhenderson/${UTIL}/releases/download/v${LAST_VER}/${UTIL}_${MACHINE}-${ARCH}
2023-08-21 11:19:53 +02:00
chmod +x ${BIN_DIR}/${UTIL}
2023-07-05 15:28:07 +02:00
else
2023-07-11 21:39:23 +02:00
echo "Last ${UTIL} version (v${CUR_VER}) is already installed"
2023-07-05 15:28:07 +02:00
fi
done
mkdir -p ~/.bashrc.d
2023-07-11 21:39:23 +02:00
mkdir -p ~/.ctctl/${INSTALL_DOMAIN}
2023-07-05 15:28:07 +02:00
mkdir -p ~/.ctctl/bin
source ~/.bashrc
PREV_IFS=$IFS
DIR_IN_PATH=0
2023-07-11 21:39:23 +02:00
IFS=":"
2023-07-05 15:28:07 +02:00
for P in $PATH; do
[ "$P" = "~/bin" -o "$P" = "$(realpath ~/bin)" ] && DIR_IN_PATH=1
done
2023-07-11 21:39:23 +02:00
IFS=$PREV_IFS
2023-07-05 15:28:07 +02:00
2023-07-11 21:39:23 +02:00
echo "Configuring the environment"
echo
echo "Installing ct env scripts"
2023-07-05 15:28:07 +02:00
cp -f ctctl ~/.ctctl/bin/
mkdir -p ~/.local/share/bash-completion/completions
cp -f bash_completion ~/.local/share/bash-completion/completions/ctctl
chmod 755 ~/.ctctl/bin/*
2023-07-12 16:18:56 +02:00
cp -f ctctl.example.conf ~/.ctctl/${INSTALL_DOMAIN}/ctctl.example.conf
2023-07-05 15:28:07 +02:00
2023-07-11 21:39:23 +02:00
cat <<_EOF > ~/.ctctl/${INSTALL_DOMAIN}/ctctl.conf
2023-07-12 16:18:56 +02:00
CTCTL_USER=${INSTALL_USER}
CTCTL_DOMAIN=${INSTALL_DOMAIN}
2023-07-05 15:28:07 +02:00
_EOF
2023-07-11 21:39:23 +02:00
cat << '_EOF' > ~/.local/share/bash-completion/completions/vault
2023-07-05 15:28:07 +02:00
complete -C ~/bin/vault vault
2023-07-11 21:39:23 +02:00
_EOF
cat << '_EOF' > ~/.local/share/bash-completion/completions/nomad
2023-07-05 15:28:07 +02:00
complete -C ~/bin/nomad nomad
2023-07-11 21:39:23 +02:00
_EOF
cat << '_EOF' > ~/.local/share/bash-completion/completions/consul
2023-07-05 15:28:07 +02:00
complete -C ~/bin/consul consul
2023-07-11 21:39:23 +02:00
_EOF
logcli --completion-script-bash > ~/.local/share/bash-completion/completions/logcli
cat <<_EOF > ~/.bashrc.d/ctctl
2023-07-05 15:28:07 +02:00
alias ctctl='source ~/.ctctl/bin/ctctl'
_EOF
2023-07-11 21:39:23 +02:00
if [ "${DIR_IN_PATH}" = "0" ]; then
cat <<_EOF >> ~/.bashrc.d/ctctl
2023-07-05 15:28:07 +02:00
export PATH=$(realpath ~/bin):$PATH
_EOF
2023-07-11 21:39:23 +02:00
source ~/.bashrc.d/ctctl
fi
2023-07-05 15:28:07 +02:00
2023-07-11 21:39:23 +02:00
echo
echo "Configuring Vault access"
cat <<_EOF >> ~/.ctctl/${INSTALL_DOMAIN}/ctctl.conf
2023-07-12 16:18:56 +02:00
VAULT_ADDR=https://active.vault.service.${INSTALL_DOMAIN}:8200
2023-07-05 15:28:07 +02:00
_EOF
2023-07-11 21:39:23 +02:00
echo
echo "Configuring Nomad access"
cat <<_EOF >> ~/.ctctl/${INSTALL_DOMAIN}/ctctl.conf
2023-07-12 16:18:56 +02:00
NOMAD_ADDR=https://nomad.service.${INSTALL_DOMAIN}:4646
NOMAD_CACERT=~/.ctctl/${INSTALL_DOMAIN}/nomad/ca.crt
NOMAD_CLIENT_CERT=~/.ctctl/${INSTALL_DOMAIN}/nomad/cli.crt
NOMAD_CLIENT_KEY=~/.ctctl/${INSTALL_DOMAIN}/nomad/cli.key
2023-07-05 15:28:07 +02:00
_EOF
2023-07-11 21:39:23 +02:00
echo
echo "Configuring Consul access"
cat <<_EOF >> ~/.ctctl/${INSTALL_DOMAIN}/ctctl.conf
2023-07-12 16:18:56 +02:00
CONSUL_HTTP_ADDR=https://consul.service.${INSTALL_DOMAIN}:8501
CONSUL_CACERT=~/.ctctl/${INSTALL_DOMAIN}/consul/ca.crt
CONSUL_CLIENT_CERT=~/.ctctl/${INSTALL_DOMAIN}/consul/cli.crt
CONSUL_CLIENT_KEY=~/.ctctl/${INSTALL_DOMAIN}/consul/cli.key
2023-07-05 15:28:07 +02:00
_EOF
# Install the certificate renewer scripts
2023-07-11 21:39:23 +02:00
# We'll use consul-template to obtain and renew certificates for Nomad and Consul
2023-07-05 15:28:07 +02:00
for UTIL in nomad consul; do
2023-07-11 21:39:23 +02:00
mkdir -p ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}
# Create the files so realpath doesn't fail
2023-07-05 15:28:07 +02:00
# Note : on Linux we could use realpath -m, but not on MAC OS
for FILE in ca.crt cli.crt cli.key cli.p12 bundle.pem; do
2023-07-11 21:39:23 +02:00
touch ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/${FILE}
2023-07-05 15:28:07 +02:00
done
2023-07-11 21:39:23 +02:00
cat <<_EOF > ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/bundle.pem.tpl
{{ with pkiCert "pki/${UTIL}/issue/${UTIL}-user" "common_name=${CTCTL_USER:-$(whoami | sed -r 's/\@.*//')}.${UTIL}.${INSTALL_DOMAIN}" "ttl=8760h" }}
2023-07-05 15:28:07 +02:00
{{ .CA }}
{{ .Cert }}
{{ .Key }}
2023-07-11 21:39:23 +02:00
{{ .CA | writeToFile "$(realpath ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/ca.crt)" "" "" "0644" }}
{{ .Cert | writeToFile "$(realpath ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/cli.crt)" "" "" "0644" }}
{{ .Key | writeToFile "$(realpath ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/cli.key)" "" "" "0600" }}
2023-07-05 15:28:07 +02:00
{{ end }}
_EOF
2023-07-11 21:39:23 +02:00
cat <<_EOF > ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/consul-template.hcl
2023-07-05 15:28:07 +02:00
template {
2023-07-11 21:39:23 +02:00
source = "$(realpath ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/bundle.pem.tpl)"
destination = "$(realpath ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/bundle.pem)"
2023-07-05 15:28:07 +02:00
perms = 0640
exec {
2023-07-11 21:39:23 +02:00
# We create a PKCS12 bundle so we can easily import it in a web browser
command = "openssl pkcs12 -export -out $(realpath ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/cli.p12) -in $(realpath ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/cli.crt) -inkey $(realpath ~/.ctctl/${INSTALL_DOMAIN}/${UTIL}/cli.key) -passout pass:${UTIL}"
2023-07-05 15:28:07 +02:00
}
}
_EOF
done
source ~/.bashrc
echo
echo
echo ----------------------------------------------------------
echo Installation done. You can now switch to your new env with
2023-07-11 21:39:23 +02:00
echo ctctl switch ${INSTALL_DOMAIN}
2023-07-05 15:28:07 +02:00
echo
echo Then authenticate using
echo ctctl auth
echo
echo ----------------------------------------------------------