#!/bin/bash #if [ ! "$BASH_VERSION" ] ; then # bash $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 # exit 1 #fi declare -Ax args declare -Ax config declare -Ax messages wxi-config(){ echo -n "" } wx-init(){ wx-login wxi-header "Init" if [[ ! -z ${args['hostname']} && ${#args['hostname']} -gt 5 ]] then HOSTNAME="${args['hostname']}.devices.$DOMAIN" elif [[ $(hostname -d) ]] then HOSTNAME=$(hostname --fqdn) else wxi-content status "Hostname" "Required" wxi-stop fi if [[ ! -z ${args['device-type']} ]] then if [[ ${args['device-type']} == "server" ]] then DEVICE_TYPE="Server" elif [[ ${args['device-type']} == "workstation" ]] then DEVICE_TYPE="Workstation" else wxi-content status "Device Type" "Invalid" wxi-stop fi else wxi-content status "Device Type" "Required" wxi-stop fi mkdir -p ~/.ssh/keys &> /dev/null apt-get update &> /dev/null apt-get install -y python3-pip python3-venv jq git curl lsb-release &> /dev/null dnf install -y epel-release &> /dev/null dnf install -y python3-pip jq git curl lsb_release &> /dev/null python3 -m venv /opt/ansible &> /dev/null /opt/ansible/bin/pip3 install ansible &> /dev/null /opt/ansible/bin/pip3 install cryptography dnspython hvac jmespath netaddr pexpect xmltodict &> /dev/null curl \ -H "X-Vault-Token: $TOKEN" \ -X GET \ https://$VAULT_DOMAIN/v1/init.sh/data/ssh -s | jq -r '.data.data.privkey' > ~/.ssh/keys/init chmod 700 ~/.ssh/keys/init &> /dev/null mkdir -p ~/.ansible &> /dev/null if [ ! -f ~/.ansible/vars.yml ] then echo "---" > ~/.ansible/vars.yml echo "hostname: $HOSTNAME" >> ~/.ansible/vars.yml echo "info:" >> ~/.ansible/vars.yml echo " type: $DEVICE_TYPE" >> ~/.ansible/vars.yml echo "config:" >> ~/.ansible/vars.yml echo " identity:" >> ~/.ansible/vars.yml echo " vault:" >> ~/.ansible/vars.yml echo " domain: $VAULT_DOMAIN" >> ~/.ansible/vars.yml fi GIT_DOMAIN="git.waren.io" GIT_PORT="2222" GIT_REPOSITORY="warengroup-private/infra-plus" export HVT=$TOKEN /opt/ansible/bin/ansible-galaxy collection install ansible.posix ansible.utils ansible.windows community.crypto community.dns community.docker community.general community.grafana community.hashi_vault community.libvirt community.mongodb community.mysql community.postgresql community.windows containers.podman --upgrade &> /dev/null /opt/ansible/bin/ansible-pull -U ssh://git@$GIT_DOMAIN:$GIT_PORT/$GIT_REPOSITORY -d ~/.ansible/pull/infra --accept-host-key --private-key ~/.ssh/keys/init --extra-vars @~/.ansible/vars.yml playbooks/init.yml -t init unset HVT } wx-login(){ wxi-header "Login" wxi-restricted --user wxi-restricted --org wxi-restricted --vault wxi-header "$ORG_HEADER" h3 if [[ ! -z ${args['auth-method']} ]] then AUTH_METHOD=${args['auth-method']} elif [[ ! -z ${args['token']} ]] then AUTH_METHOD=token elif [[ -f "$HOME/.warengroup/config.json" && $(cat $HOME/.warengroup/config.json | jq -r .login.$ORG.token) != 'null' && $(cat $HOME/.warengroup/config.json | jq -r .login.$ORG.token) != '' ]] then AUTH_METHOD=token elif [[ ! -z ${args['username']} ]] then AUTH_METHOD=ldap else AUTH_METHOD=ldap fi if [[ ! -z $AUTH_METHOD ]] then case $AUTH_METHOD in ldap) echo -n "Username: " if [[ ! -z ${args['username']} ]] then USERNAME=${args['username']} wxi-content text "$USERNAME" else read USERNAME fi echo -n "Password: " if [[ ! -z ${args['password']} ]] then PASSWORD=${args['password']} else read -s PASSWORD fi if [[ ! -z $PASSWORD ]] then wxi-content text "****************" else wxi-content text "" fi if [[ -z $USERNAME || -z $PASSWORD ]] then wxi-content status "Username & Password" "Required" wxi-footer wxi-stop fi VAULT_LOGIN=$(curl https://$VAULT_DOMAIN/v1/auth/ldap/login/$USERNAME -X POST -d '{ "password": "'$PASSWORD'" }' -s | jq -r '.auth.client_token') if [[ -z $VAULT_LOGIN || ${#VAULT_LOGIN} -lt 95 || ${#VAULT_LOGIN} -gt 95 ]] then wxi-content status "Login" "Failed" wxi-stop fi TOKEN=$VAULT_LOGIN wxi-config login ;; token) echo -n "Token: " if [[ ! -z ${args['token']} ]] then if [[ ${args['token']} != "true" ]] then TOKEN=${args['token']} fi elif [[ -f "$HOME/.warengroup/config.json" && $(cat $HOME/.warengroup/config.json | jq -r .login.$ORG.token) != 'null' && $(cat $HOME/.warengroup/config.json | jq -r .login.$ORG.token) != '' ]] then TOKEN=$(cat $HOME/.warengroup/config.json | jq -r .login.$ORG.token) else read -s TOKEN fi if [[ ! -z $TOKEN ]] then wxi-content text "***********************************************************************************************" fi if [[ -z $TOKEN ]] then wxi-content status "Token" "Required" wxi-footer wxi-stop fi if [[ ${#TOKEN} -lt 95 || ${#TOKEN} -gt 95 ]] then wxi-content status "Token" "Invalid" wxi-footer wxi-stop fi VAULT_LOGIN=$(curl https://$VAULT_DOMAIN/v1/auth/token/renew-self -X POST --header "X-Vault-Token: $TOKEN" -d '{ "token": "'$TOKEN'" }' -s | jq -r '.auth.client_token') if [[ -z $VAULT_LOGIN || ${#VAULT_LOGIN} -lt 95 || ${#VAULT_LOGIN} -gt 95 ]] then wxi-content status "Login" "Failed" wxi-stop fi TOKEN=$VAULT_LOGIN wxi-config login ;; *) wxi-content status "Login Type" "Unsupported" wxi-footer wxi-stop ;; esac fi VAULT_USERNAME=$(curl https://$VAULT_DOMAIN/v1/auth/token/lookup-self -X GET --header "X-Vault-Token: $TOKEN" -s | jq -r '.data.display_name') if [[ -z $VAULT_USERNAME ]] then wxi-content status "Login" "Username Missing" wxi-stop elif [[ $VAULT_USERNAME != ldap* && $VAULT_USERNAME != oidc* ]] then wxi-content status "Login" "Authentication Method Invalid" wxi-stop elif [[ $VAULT_USERNAME == ldap* ]] then USERNAME=${VAULT_USERNAME#ldap-} elif [[ $VAULT_USERNAME == oidc* ]] then USERNAME=${VAULT_USERNAME#oidc-} fi wxi-footer } wxi-restricted(){ if [[ -z $1 || $1 == "--user" ]] then if [[ $USER != "root" && $USER != "local" ]] then wxi-content status "Command" "Restricted" wxi-content text "It's not permitted to execute this command as $USER." wxi-footer wxi-repeat "\n" 3 exit 1 fi fi if [[ $1 == "--org" ]] then if [[ ! -z ${args['org']} ]] then case ${args['org']} in warengroup) ORG=warengroup ;; cwchristerw) ORG=cwchristerw ;; *) wxi-content status "Organization" "Unsupported" wxi-footer wxi-stop ;; esac elif [[ $(hostname -d) == "devices.waren.io" ]] then ORG=warengroup elif [[ $(hostname -d) == "devices.christerwaren.fi" ]] then ORG=cwchristerw fi if [[ ! -z $ORG ]] then case $ORG in warengroup) DOMAIN=waren.io VAULT_DOMAIN=vault.cwinfo.net ORG_HEADER="Warén Group" ;; cwchristerw) DOMAIN=christerwaren.fi VAULT_DOMAIN=vault.cwinfo.net ORG_HEADER="Christer Warén" ;; *) wxi-content status "Organization" "Unsupported" wxi-footer wxi-stop ;; esac else wxi-content status "Organization" "Required" wxi-footer wxi-stop fi fi if [[ -z $1 || $1 == "--vault" ]] then if [[ -z $VAULT_DOMAIN ]] then wxi-content status "Vault" "Unavailable" wxi-footer wxi-repeat "\n" 3 exit 1 fi VAULT_STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://$VAULT_DOMAIN/v1/sys/health) if [[ ! $VAULT_STATUS -eq 200 ]] then wxi-content status "Vault" "Offline" wxi-footer wxi-repeat "\n" 3 exit 1 fi fi } wxi-start(){ wxi-header "Warén Init" h1 mkdir -p $HOME/.warengroup &> /dev/null if [[ ! -f "$HOME/.warengroup/config.json" || $(jq -e . < $HOME/.warengroup/config.json &>/dev/null; echo $?) -gt 0 ]] then echo '{}' | jq > $HOME/.warengroup/config.json fi mkdir -p $HOME/.ssh/keys chmod 700 -R $HOME/.ssh/keys } wxi-stop (){ rm -rf /.ssh/keys/init &> /dev/null wxi-repeat "\n" 3 exit 1 } wxi-content(){ if [[ $1 == "text" ]] then echo "$2" elif [[ $1 == "status" ]] then wxi-repeat "\n" 2 echo -n "$wxiBold" echo "Status" echo -n "$wxiNormal" echo "$2 - $3" elif [[ $1 == "link" ]] then echo "$2 - $3" fi } wxi-footer(){ echo "" echo "------------------------------" wxi-repeat " " $((30/2-12/2)) echo -n "$wxiBold" echo "Warén Group™" echo -n "$wxiNormal" wxi-repeat " " $((30/2-17/2)) echo "https://waren.io" echo "==============================" } wxiRed=$(tput setaf 196) wxiGreen=$(tput setaf 46) wxiYellow=$(tput setaf 226) wxiBlue=$(tput setaf 21) wxiPurple=$(tput setaf 165) wxiTurquoise=$(tput setaf 14) wxiPink=$(tput setaf 198) wxiOrange=$(tput setaf 202) wxiUnderline=$(tput smul) wxiBold=$(tput bold) wxiNormal=$(tput sgr0) wxi-header(){ if [[ $2 == "h1" ]] then wxi-repeat "\n" 3 echo "==============================" wxi-repeat " " $((30/2-${#1}/2)) echo -n "$wxiBold" echo "$1" echo -n "$wxiNormal" echo "==============================" fi if [[ $2 == "h2" || -z $2 ]] then wxi-start wxi-repeat " " $((30/2-6/2-${#1}/2)) echo -n "$wxiBold" echo ">> $1 <<" echo -n "$wxiNormal" echo "------------------------------" echo "" fi if [[ $2 == "h3" ]] then echo -n "$wxiBold" echo "$1" echo -n "$wxiNormal" fi } wxi-repeat() { if [[ $1 == " " ]] then local str=$1 n=$2 spaces printf -v spaces "%*s" $n " " printf "%s" "${spaces// /$str}" else for i in $(seq 1 $2); do echo -en $1 done fi } i=1 while [[ "$1" != "" ]] do case $1 in --*) key="${1%%=*}" value="${1#*=}" if [[ "$value" == "$key" ]] then shift value="$1" fi if [[ -z $value ]] then value=true fi args["${key#--}"]="$value" ;; -*) key="${1%=*}" value="${1#*=}" if [[ "$value" == "$key" ]] then shift value="$1" fi if [[ -z $value ]] then value=true fi args["${key#-}"]="$value" ;; *) args["$i"]="${1%%=*}" i=$((i + 1)) ;; esac shift done wx-init wxi-stop