#!/bin/bash # # DICE VERDE O ROSSO PER OGNI ACCESSO, e per ogni rosso cosa fare. # # ./verifica.sh # per chi ha la VPN # ./verifica.sh --senza-vpn # per chi non la ha: staging non raggiungibile e' giallo # # Non modifica niente e non chiede niente: si puo' lanciare quando si vuole, # anche da Claude. Esce 0 se e' tutto verde, 1 altrimenti. set -u cd "$(dirname "$0")" || exit 1 . ./comune.sh # Chi non ha la VPN non arriva a staging, ed e' giusto cosi': senza questa # opzione quel rosso faceva uscire 1 anche un PC preparato bene per il suo ruolo. SENZA_VPN=0 case "${1:-}" in --senza-vpn) SENZA_VPN=1 ;; "") ;; *) echo "Uso: ./verifica.sh [--senza-vpn]" >&2 ; exit 2 ;; esac ROSSI=0 rosso () { male "$@" ; ROSSI=$((ROSSI + 1)) ; } titolo "Programmi" for P in git docker aws curl ssh ; do if c_e "$P" ; then ok "$P" ; else rosso "$P non installato" ; fi done if c_e docker ; then if docker info > /dev/null 2>&1 ; then ok "Docker risponde" else rosso "Docker installato ma non risponde (e' acceso? il tuo utente e' nel gruppo docker?)" ; fi fi if c_e claude ; then ok "Claude Code" ; else attento "Claude Code non installato (non obbligatorio, ma ti guida)" ; fi titolo "Gitea" UTENTE="$(utente_gitea)" ; ESITO_GITEA=$? if [ -n "$UTENTE" ] ; then ok "token valido (utente $UTENTE)" # Si chiede a git la credenziale che userebbe davvero: un gestore qualsiasi # configurato non vuol dire che abbia quella giusta, e un token vecchio # rimasto li' fa funzionare l'API ma non git clone. GIT_PASSWORD="$(password_git_gitea)" if [ "$GIT_PASSWORD" = "$(token_gitea)" ] ; then ok "git entra su $GITEA_HOST con il tuo token" elif [ -n "$GIT_PASSWORD" ] ; then rosso "git usa un accesso a Gitea diverso dal tuo token (vecchio o di un altro): rilancia ./configura.sh, che lo sostituisce" else rosso "git non ha le credenziali di Gitea: rilancia ./configura.sh" fi unset GIT_PASSWORD elif [ "$ESITO_GITEA" = "2" ] ; then rosso "Gitea ($GITEA_URL) non risponde: controlla la connessione a internet e rilancia" else rosso "token Gitea mancante o non valido: rilancia ./configura.sh" fi titolo "AWS" # Chi e' la persona lo dice Gitea: una chiave AWS di un altro sul PC vuol dire # che tutto quello che fa su AWS risulta fatto da lui. Senza Gitea non si puo' # dire che la chiave sia sua, e quindi non e' verde. AWS_OPZ=(--cli-connect-timeout 10 --cli-read-timeout 15) CONFLITTI="$(aws_variabili_in_conflitto)" [ -n "$CONFLITTI" ] && attento "nel terminale sono impostate $CONFLITTI: la AWS CLI usa quelle, non la chiave di ~/.aws/credentials" if c_e aws && IDENTITA="$(AWS_MAX_ATTEMPTS=1 aws sts get-caller-identity "${AWS_OPZ[@]}" --query Arn --output text 2> /dev/null)" && [ -n "$IDENTITA" ] ; then if [ -z "$UTENTE" ] ; then rosso "c'e' una chiave AWS (${IDENTITA#arn:aws:iam::}), ma finche' Gitea non va non posso dire che sia tua" elif aws_e_di "$IDENTITA" "$UTENTE" ; then ok "accesso: $UTENTE" else rosso "la chiave AWS di questo PC e' di ${IDENTITA#arn:aws:iam::}, non tua ($UTENTE nell'account OTO $AWS_ACCOUNT): rilancia ./configura.sh, che la sostituisce" fi if AWS_MAX_ATTEMPTS=1 aws ssm get-parameter "${AWS_OPZ[@]}" --region "$AWS_REGIONE" --name "$SSM_PROVA" --query Parameter.Name --output text > /dev/null 2>&1 ; then ok "legge i segreti comuni su SSM" else rosso "non legge SSM: all'amministratore serve darti il ruolo di sviluppo" fi else rosso "AWS non configurato: rilancia ./configura.sh, che ti dice dove crearti la chiave nella console ($AWS_CONSOLE)" fi titolo "Chiave SSH" if [ -f "$CHIAVE_SSH" ] ; then ok "$CHIAVE_SSH" ; else rosso "chiave mancante: rilancia ./configura.sh" ; fi # I nomi con cui la cercano i deploy dei progetti for ALTRA in $CHIAVI_SSH_PROGETTI ; do [ -e "$ALTRA" ] || rosso "manca $ALTRA, che usano i deploy dei progetti: rilancia ./configura.sh" done titolo "VPN e server" # La VPN si riconosce da una cosa sola: staging, che sta su rete privata, # risponde sulla porta SSH. Niente `timeout`: sul Mac non c'e'. porta_aperta () { bash -c "exec 3<>/dev/tcp/$1/$2" 2> /dev/null & local pid=$! ( sleep 5 ; kill "$pid" 2> /dev/null ) & local sveglia=$! wait "$pid" 2> /dev/null ; local esito=$? kill "$sveglia" 2> /dev/null return "$esito" } # Un tentativo, e il motivo se non si entra: "non entri" da solo faceva # pensare ai ruoli anche quando mancava la chiave del server su questo PC. # Esce 0 se si entra, 1 se e' la chiave tua, 2 se e' altro (scritto in MOTIVO). entra () { local errore errore="$(ssh -o BatchMode=yes -o ConnectTimeout=8 "$1" true 2>&1 > /dev/null)" && return 0 case "$errore" in *"Permission denied"*) return 1 ;; *"Host key verification failed"*|*"IDENTIFICATION HAS CHANGED"*) MOTIVO="questo PC non ha la chiave giusta del server: rilancia ./configura.sh, che la registra" ;; *"Connection closed"*|*"Connection reset"*) MOTIVO="il server ha chiuso la connessione: dopo troppi tentativi sbagliati la chiude per qualche minuto, aspetta e rilancia" ;; *) MOTIVO="ssh dice: $(printf '%s\n' "$errore" | grep -v '^\*\*' | tail -1)" ;; esac return 2 } if porta_aperta "$STAGING_HOST" 22 ; then ok "staging raggiungibile (la VPN e' accesa)" entra "$STAGING_NOME" ; ESITO=$? if [ "$ESITO" = "0" ] ; then ok "entri su staging ($STAGING_NOME)" elif [ "$ESITO" = "1" ] ; then rosso "staging non accetta la tua chiave: l'amministratore deve ancora aggiungerla" else rosso "staging ($STAGING_NOME): $MOTIVO" ; fi elif [ "$SENZA_VPN" = "1" ] ; then attento "staging non raggiungibile: senza VPN e' normale" else rosso "staging non raggiungibile: la VPN e' accesa?" fi # Le produzioni sono due finche' i siti non sono migrati tutti. La nuova sta # dietro la stessa VPN di staging. Un tentativo solo per macchina: la nuova # chiude le porte per un po' a chi sbaglia il login piu' volte di fila. # Solo il rifiuto della chiave dipende dal ruolo: il resto si sistema da qui. NON_AUTORIZZATO="il server non accetta la tua chiave (normale se non hai il ruolo di rilascio; se ce l'hai, chiedi a chi amministra di aggiungerla)" if porta_aperta "$PRODUZIONE_HOST" 22 ; then entra "$PRODUZIONE_NOME" ; ESITO=$? if [ "$ESITO" = "0" ] ; then ok "entri in produzione ($PRODUZIONE_NOME)" elif [ "$ESITO" = "1" ] ; then attento "produzione ($PRODUZIONE_NOME): $NON_AUTORIZZATO" else rosso "produzione ($PRODUZIONE_NOME): $MOTIVO" ; fi else attento "produzione ($PRODUZIONE_NOME): non raggiungibile (sta dietro la VPN, come staging)" fi entra "$PRODUZIONE_VECCHIA_NOME" ; ESITO=$? if [ "$ESITO" = "0" ] ; then ok "entri nella produzione vecchia ($PRODUZIONE_VECCHIA_NOME)" elif [ "$ESITO" = "1" ] ; then attento "produzione vecchia ($PRODUZIONE_VECCHIA_NOME): $NON_AUTORIZZATO" else rosso "produzione vecchia ($PRODUZIONE_VECCHIA_NOME): $MOTIVO" ; fi titolo "Risultato" if [ "$ROSSI" = "0" ] ; then ok "tutto a posto. Prossimo passo: ./progetti.sh" exit 0 fi male "$ROSSI cose da sistemare (sopra, in rosso)" exit 1