From 12384e095bcfb8095aca3348118ed0fb6d26f497 Mon Sep 17 00:00:00 2001 From: Christer Waren Date: Sun, 20 Sep 2026 05:03:09 +0300 Subject: [PATCH] Init: Update --- init.sh | 512 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 252 insertions(+), 260 deletions(-) diff --git a/init.sh b/init.sh index fabf5c3..f4d482e 100755 --- a/init.sh +++ b/init.sh @@ -153,80 +153,276 @@ wxi-config-legacy(){ mv $HOME/.warengroup/config.json.tmp $HOME/.warengroup/config.json &> /dev/null } +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 with root or local user." + 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-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-stop + ;; + esac + else + wxi-content status "Organization" "Required" + wxi-stop + fi + fi + + if [[ -z $1 || $1 == "--vault" ]] + then + if [[ -z $VAULT_DOMAIN ]] + then + wxi-content status "Vault" "Unavailable" + 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-repeat "\n" 3 + exit 1 + fi + fi +} + wx-init(){ - wx-login - wxi-header "Init" + wx-login + wxi-header "Init" - if [[ ! -z ${args['hostname']} && ${#args['hostname']} -gt 5 ]] + 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 - HOSTNAME="${args['hostname']}.devices.$DOMAIN" - elif [[ $(hostname -d) ]] + DEVICE_TYPE="Server" + elif [[ ${args['device-type']} == "workstation" ]] then - HOSTNAME=$(hostname --fqdn) + DEVICE_TYPE="Workstation" else - wxi-content status "Hostname" "Required" - wxi-stop + wxi-content status "Device Type" "Invalid" + wxi-stop fi + else + wxi-content status "Device Type" "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 - 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 passlib pexpect xmltodict &> /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 passlib 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 - 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 - chmod 700 ~/.ssh/keys/init &> /dev/null + mkdir -p ~/.ansible &> /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 - 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" - GIT_DOMAIN="git.waren.io" - GIT_PORT="2222" - GIT_REPOSITORY="warengroup-private/infra-plus" + export HVT=$TOKEN - export HVT=$TOKEN + /opt/ansible/bin/ansible-galaxy collection install ansible.mysql ansible.posix ansible.utils ansible.windows community.crypto community.dns community.docker community.general community.grafana community.hashi_vault community.libvirt community.mongodb community.postgresql community.windows containers.podman --upgrade &> /dev/null - /opt/ansible/bin/ansible-galaxy collection install ansible.mysql ansible.posix ansible.utils ansible.windows community.crypto community.dns community.docker community.general community.grafana community.hashi_vault community.libvirt community.mongodb 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 init.yml -t init - /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 init.yml -t init + unset HVT +} - unset HVT +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 + + echo -n "$wxiBold" + echo "Designed by" + echo -n "$wxiNormal" + wxiLink "Warén Group™" "https://waren.io" +} + +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 == "text*" ]] + then + echo -n "$2" + elif [[ $1 == "status" ]] + then + echo -n "Status: " + echo "$2 - $3" + elif [[ $1 == "link" ]] + then + echo "$2 - $3" + fi +} + +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) + +wxiLink() { + printf '\e]8;;%s\e\\%s\e]8;;\e\\\n' "$2" "$1" +} + +wxi-header(){ + if [[ $2 == "h1" || $2 == "" ]] + then + #wxi-repeat " " $(($(tput cols)/2-${#1}/2)) + echo -n "$wxiBold" + echo ${1^^} + echo -n "$wxiNormal" + echo "" + fi + + if [[ $2 == "h1*" ]] + then + #wxi-repeat " " $(($(tput cols)/2-${#1}/2)) + echo -n "$wxiBold" + echo ${1^^} + echo -n "$wxiNormal" + fi + + if [[ $2 == "h2" ]] + then + #wxi-repeat " " $(($(tput cols)/2-${#1}/2)) + echo -n "$wxiBold" + echo ">> $1 <<" + echo -n "$wxiNormal" + fi + + if [[ $2 == "h3" ]] + then + #wxi-repeat " " $(($(tput cols)/2-${#1}/2)) + echo -n "$wxiBold" + echo "$1" + echo -n "$wxiNormal" + fi + + if [[ $2 == "h4" ]] + then + #wxi-repeat " " $(($(tput cols)/2-${#1}/2)) + echo -n "$wxiUnderline" + 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 } wx-login(){ @@ -284,7 +480,6 @@ wx-login(){ if [[ -z $USERNAME || -z $PASSWORD ]] then wxi-content status "Username & Password" "Required" - wxi-footer wxi-stop fi @@ -292,7 +487,6 @@ wx-login(){ if [[ -z $VAULT_LOGIN || ${#VAULT_LOGIN} -lt 95 || ${#VAULT_LOGIN} -gt 95 ]] then wxi-content status "Login" "Failed" - wxi-footer wxi-stop fi @@ -322,14 +516,12 @@ wx-login(){ 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 @@ -337,7 +529,6 @@ wx-login(){ if [[ -z $VAULT_LOGIN || ${#VAULT_LOGIN} -lt 95 || ${#VAULT_LOGIN} -gt 95 ]] then wxi-content status "Login" "Failed" - wxi-footer if [[ $(wxi-config-legacy login read) ]] then @@ -353,7 +544,6 @@ wx-login(){ ;; *) wxi-content status "Login Type" "Unsupported" - wxi-footer wxi-stop ;; esac @@ -375,206 +565,8 @@ wx-login(){ 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 "------------------------------" - echo -n "$wxiBold" - echo "Designed by" - echo -n "$wxiNormal" - wxiLink "Warén Group™" "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) - -wxiLink() { - printf '\e]8;;%s\e\\%s\e]8;;\e\\\n' "$2" "$1" -} - -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 -} - -#{{ COMMANDS }} wxi-args "$@" wxi-config