Skip to content

Bashrc

# ~/.bashrc

# Se non interattiva, esci subito
[[ $- != *i* ]] && return

################################################################################
# 1. ESPORTAZIONI E VARIABILI D'AMBIENTE
################################################################################
export EDITOR=nano
export VISUAL=nano
export LESS='-R'
export GIT_PAGER=cat
export CLICOLOR=1
export LS_OPTIONS='--color=auto'
export MOZ_ENABLE_WAYLAND=1
export LIBVA_DRIVER_NAME=iHD
export SOPS_AGE_KEY_FILE=/home/fabio/age/sops.agekey
export GITLAB_TOKEN=glpat-key
export TF_HTTP_USERNAME="fmogavero"
export TF_HTTP_PASSWORD="$GITLAB_TOKEN"
export AWS_ACCESS_KEY_ID="key"
export AWS_SECRET_ACCESS_KEY="key"
export AWS_DEFAULT_REGION="us-east-1"

# Configurazione Kubeconfig multilivello
export KUBECONFIG=file.yaml:file2.yaml

# Gestione Storia Bash
export HISTSIZE=20000
export HISTFILESIZE=40000
export HISTCONTROL=ignoredups:ignorespace
export HISTTIMEFORMAT="%F %T "
shopt -s histappend cmdhist checkwinsize

# PATH di sistema e pacchetti locali
export PATH="$PATH:/home/fabio/.local/bin"
export PATH=/home/fabio/.opencode/bin:$PATH
# Ignora funzip e function quando premi TAB su 'fun'
EXECIGNORE="/usr/bin/funzip"
################################################################################
# 2. ALIAS DI SISTEMA E DI STRUMENTO
################################################################################
# Navigazione e utility base
alias ls='ls --color=auto'
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'
alias grep='grep --color=auto'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias ..='cd ..'
alias ...='cd ../..'
alias please='sudo $(fc -ln -1)'
alias cc='clear'
alias reload='source ~/.bashrc'
alias sk='xfce4-terminal --tab'
alias otp='bash /home/fabio/script/otp.sh'

# Alias Git shortcut
alias gs='git status -sb'
alias ga='git add'
alias gc='git commit'
alias gsw='git switch'
alias gba='git branch -a'
alias gp='git pull'
alias gP='git push'
alias gsh='git show'
alias gr='git restore'
alias grf='git restore --source'
alias gl='git log --oneline --graph --decorate --date-order -n 15'
alias gll='git log --graph --date-order --pretty=format:"%C(yellow)%h%Creset %C(auto)%d%Creset %C(green)%ad%Creset %s %C(bold blue)<%an>%Creset" --date=format:"%d-%m-%Y %H:%M" --all -n 15'

################################################################################
# 3. COMPLETAMENTI AUTOMATICI E BINDINGS
################################################################################
bind 'set completion-ignore-case on'
bind 'set show-all-if-ambiguous on'
bind -x '"\C-g": git-pick'

if [[ -f /etc/bash_completion ]] && ! shopt -oq posix; then
    . /etc/bash_completion
fi

# Caricamento moduli di completamento dinamici
[[ -f /usr/share/bash-completion/completions/git ]] && . /usr/share/bash-completion/completions/git
command -v kubectl &>/dev/null && source <(kubectl completion bash) 2>/dev/null
command -v helm &>/dev/null && source <(helm completion bash) 2>/dev/null
command -v terraform &>/dev/null && complete -C terraform terraform 2>/dev/null

################################################################################
# 4. CONFIGURAZIONE DEL PROMPT DI SISTEMA (PS1)
################################################################################
PROMPT_COMMAND='EXIT=$?'
PS1='$( \
    USER_COLOR="\[\e[1;32m\]"; \
    [[ $EUID -eq 0 ]] && USER_COLOR="\[\e[1;31m\]"; \
    DIR="\[\e[1;36m\]\w\[\e[0m\]"; \
    BRANCH=""; \
    if git rev-parse --is-inside-work-tree &>/dev/null; then \
        BRANCH=" (\[\e[1;33m\]$(git symbolic-ref --short HEAD 2>/dev/null)\[\e[0m\])"; \
    fi; \
    K8S_CTX=""; \
    if command -v kubectl &>/dev/null; then \
        CTX=$(kubectl config current-context 2>/dev/null); \
        if [[ -n "$CTX" ]]; then \
            K8S_CTX=" [⎈ \[\e[1;35m\]$CTX\[\e[0m\]]"; \
        fi; \
    fi; \
    CODE=""; \
    if [[ $EXIT -ne 0 ]]; then \
        CODE=" \[\e[1;31m\][✘ $EXIT]\[\e[0m\]"; \
    else \
        CODE=" \[\e[1;32m\][✔]\[\e[0m\]"; \
    fi; \
    echo -e "\[\e[1;34m\]\u@\h\[\e[0m\]:$DIR$BRANCH$K8S_CTX$CODE\n${USER_COLOR}\u\[\e[0m\]: " \
)'

################################################################################
# 5. FUNZIONI CORE E DI DIAGNOSTICA KUBERNETES / GITOPS
################################################################################

# Menu Generale degli Strumenti Disponibili
funzioni() {
    printf "\n\033[1;36m==================================================================\033[0m\n"
    printf "\033[1;36m===             STRUMENTI DI DIAGNOSTICA E AUTOMAZIONE         ===\033[0m\n"
    printf "\033[1;36m==================================================================\033[0m\n\n"

    local menu_items=(
        "klogs          -> Visualizza i log di un pod in streaming"
        "eventik8s      -> Monitora gli eventi K8s o FluxCD in tempo reale (-w)"
        "kconfigmap     -> Mostra l'intero contenuto YAML di una ConfigMap"
        "kfind-cm       -> Cerca stringhe lunghe o chiavi dentro una ConfigMap"
        "kdebug-pod     -> Diagnostica rapida dello stato pod e relativi eventi"
        "gt             -> Esegue Git add, commit con messaggio e push automatico"
        "gitman         -> Manuale rapido dei comandi Git avanzati e di ripristino"
        "helman         -> Manuale rapido per la gestione e il debug delle Chart Helm"
        "fluxman        -> Manuale di comandi FluxCD, GitOps e validazioni locali"
        "dockerman      -> Manuale per gestione, pulizia e debug di Docker Compose"
        "Esci"
    )

    echo "Seleziona lo strumento da avviare (Inserisci il numero):"
    echo "------------------------------------------------------------------"

    PS3=$'\nScelta numero: '
    select opt_text in "${menu_items[@]}"; do
        if [ -n "$opt_text" ]; then
            if [ "$opt_text" == "Esci" ]; then
                echo "Uscita."
                return 0
            fi

            local cmd=$(echo "$opt_text" | awk '{print $1}')
            echo "------------------------------------------------------------------"
            printf "\033[1;32m>>> Avvio comando: %s\033[0m\n" "$cmd"
            echo "------------------------------------------------------------------"
            $cmd
            break
        else
            echo "Scelta non valida. Riprova."
        fi
    done
}

# Ispezione Log Pod in streaming
klogs() {
    local ns="$1"
    local pod="$2"

    if [ -z "$ns" ]; then
        echo "=== Seleziona un Namespace ==="
        local namespaces=($(kubectl get ns -o jsonpath='{.items[*].metadata.name}'))
        select selected_ns in "${namespaces[@]}"; do
            if [ -n "$selected_ns" ]; then ns="$selected_ns"; break; else echo "Scelta non valida."; fi
        done
    fi

    if [ -z "$pod" ]; then
        echo "=== Seleziona un Pod in [$ns] ==="
        local pods=($(kubectl get pods -n "$ns" -o jsonpath='{.items[*].metadata.name}'))
        if [ ${#pods[@]} -eq 0 ]; then echo "Nessun pod trovato nel namespace $ns."; return 1; fi
        select selected_pod in "${pods[@]}"; do
            if [ -n "$selected_pod" ]; then pod="$selected_pod"; break; else echo "Scelta non valida."; fi
        done
    fi

    echo "--> Estrazione degli ultimi 100 log da $ns/$pod (in streaming)..."
    echo "------------------------------------------------------------------"
    kubectl logs -n "$ns" "$pod" --tail=100 -f
}

# Monitoraggio Eventi in tempo reale (Cluster o FluxCD)
eventik8s() {
    local choice="$1"

    if [ -z "$choice" ]; then
        echo "=== SELEZIONA IL TIPO DI EVENTI (Inserisci il numero) ==="
        local options=("Eventi Kubernetes (Cluster)" "Eventi FluxCD (GitOps)" "Esci")
        PS3="Scelta: "
        select opt in "${options[@]}"; do
            case $opt in
                "Eventi Kubernetes (Cluster)") choice="cluster"; break ;;
                "Eventi FluxCD (GitOps)")      choice="flux"; break ;;
                "Esci")                         echo "Annullato."; return 0 ;;
                *)                              echo "Scelta non valida. Riprova." ;;
            esac
        done
    fi

    case $choice in
        flux)
            printf "\033[1;34m>>> Eventi FluxCD (Real-time via K8s Events)\033[0m\n"
            kubectl get events -A -w --output=custom-columns="NAMESPACE:.metadata.namespace,TIME:.firstTimestamp,TYPE:.type,REASON:.reason,OBJECT:.involvedObject.name,MESSAGE:.message" | grep --line-buffered -E "flux-system|"
            ;;
        cluster|*)
            printf "\033[1;32m>>> Eventi Kubernetes (Real-time)\033[0m\n"
            kubectl get events -A -w --output=custom-columns="NAMESPACE:.metadata.namespace,TIME:.firstTimestamp,TYPE:.type,REASON:.reason,OBJECT:.involvedObject.name,MESSAGE:.message"
            ;;
    esac
}

# Dump YAML completo di una ConfigMap selezionata
kconfigmap() {
    local ns="$1"
    local cm="$2"

    if [ -z "$ns" ]; then
        echo "=== SELEZIONA UN NAMESPACE (Inserisci il numero) ==="
        local namespaces=($(kubectl get ns -o jsonpath='{.items[*].metadata.name}'))
        PS3="Numero namespace: "
        select selected_ns in "${namespaces[@]}"; do
            if [ -n "$selected_ns" ]; then ns="$selected_ns"; break; else echo "Scelta non valida. Riprova."; fi
        done
    fi

    if [ -z "$cm" ]; then
        echo "=== SELEZIONA UNA CONFIGMAP IN [$ns] (Inserisci il numero) ==="
        local cms=($(kubectl get configmap -n "$ns" -o jsonpath='{.items[*].metadata.name}'))
        if [ ${#cms[@]} -eq 0 ]; then echo "Nessuna ConfigMap trovata nel namespace $ns."; return 1; fi
        PS3="Numero ConfigMap: "
        select selected_cm in "${cms[@]}"; do
            if [ -n "$selected_cm" ]; then cm="$selected_cm"; break; else echo "Scelta non valida. Riprova."; fi
        done
    fi

    printf "\033[1;33m>>> Contenuto della ConfigMap: %s/%s\033[0m\n" "$ns" "$cm"
    echo "------------------------------------------------------------------"
    kubectl get configmap -n "$ns" "$cm" -o yaml
}

# Ricerca profonda e formattata di stringhe/chiavi lunghe nelle ConfigMap
kfind-cm() {
    local ns="$1"
    local cm="$2"

    if [ -z "$ns" ]; then
        echo "=== SELEZIONA UN NAMESPACE (Inserisci il numero) ==="
        local namespaces=($(kubectl get ns -o jsonpath='{.items[*].metadata.name}'))
        PS3="Numero namespace: "
        select selected_ns in "${namespaces[@]}"; do
            if [ -n "$selected_ns" ]; then ns="$selected_ns"; break; else echo "Scelta non valida."; fi
        done
    fi

    if [ -z "$cm" ]; then
        echo "=== SELEZIONA UNA CONFIGMAP (Inserisci il numero) ==="
        local cms=($(kubectl get configmap -n "$ns" -o jsonpath='{.items[*].metadata.name}'))
        if [ ${#cms[@]} -eq 0 ]; then echo "Nessuna ConfigMap."; return 1; fi
        PS3="Numero ConfigMap: "
        select selected_cm in "${cms[@]}"; do
            if [ -n "$selected_cm" ]; then cm="$selected_cm"; break; else echo "Scelta non valida."; fi
        done
    fi

    echo -n "Inserisci la stringa o chiave da cercare: "
    read -r search_term

    if [ -z "$search_term" ]; then
        echo "Termine vuoto. Mostro la risorsa intera formattata."
        kubectl get configmap -n "$ns" "$cm" -o json | jq -r '.data'
        return 0
    fi

    echo "------------------------------------------------------------------"
    printf "\033[1;33m>>> RISULTATI PER '%s' IN %s/%s\033[0m\n" "$search_term" "$ns" "$cm"
    echo "------------------------------------------------------------------"

    kubectl get configmap -n "$ns" "$cm" -o json \
        | jq -r '.data[]' \
        | grep -i -A 8 --color=always "$search_term"
}

# Diagnostica dello stato dei Pod ed eventi associati (Pod + Controller)
kdebug-pod() {
    printf "\033[1;34m>>> Caricamento della mappa dei pod...\033[0m\n"
    local all_pods=($(kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"\n"}{end}' | sort))

    if [ ${#all_pods[@]} -eq 0 ]; then echo "Nessun pod presente nel cluster."; return 0; fi

    echo "=== SELEZIONA IL POD DA ISPEZIONARE (Inserisci il numero) ==="
    PS3="Scelta: "
    select choice in "${all_pods[@]}" "Esci"; do
        if [ "$choice" == "Esci" ] || [ -z "$choice" ]; then echo "Annullato."; return 0; fi

        local ns=$(echo "$choice" | cut -d'/' -f1)
        local pod=$(echo "$choice" | cut -d'/' -f2)

        echo "------------------------------------------------------------------"
        printf "\033[1;33m>>> DIAGNOSI RAPIDA: %s/%s\033[0m\n" "$ns" "$pod"
        echo "------------------------------------------------------------------"

        local pod_json=$(kubectl get pod -n "$ns" "$pod" -o json)
        echo "$pod_json" | jq -r '.status.containerStatuses[] | "Container: \(.name)\nStato:     \(.state)\nPronto:    \(.ready)"'

        echo "------------------------------------------------------------------"
        printf "\033[1;33m>>> EVENTI CORRELATI (Pod + Parent Controller)\033[0m\n"
        echo "------------------------------------------------------------------"

        local parent=$(echo "$pod_json" | jq -r '.metadata.ownerReferences[0].name // empty')
        local filter="involvedObject.name=$pod"
        if [ -n "$parent" ]; then filter="$filter,involvedObject.name=$parent"; fi

        local events=$(kubectl get events -n "$ns" --field-selector "$filter" -o custom-columns="KIND:.involvedObject.kind,REASON:.reason,MESSAGE:.message" --no-headers | tail -n 5)
        if [ -z "$events" ]; then
            echo "Nessun evento recente registrato per questo stack nelle ultime ore."
        else
            echo "$events"
        fi
        break
    done
}

# Funzione Legacy per controllo rapido dei pod KO generici del cluster
kdebug() {
    echo "=== Pod in errore o crash ==="
    local failed_pods=$(kubectl get pods -A --no-headers | grep -v -E 'Running|Completed')

    if [ -z "$failed_pods" ]; then
        echo "Nessun pod in errore rilevato nel cluster."
    else
        echo "$failed_pods"
    fi
    echo ""
    echo "=== Ultimi 5 Eventi di Warning nel Cluster ==="
    kubectl get events -A --field-selector type=Warning --sort-by='.metadata.creationTimestamp' | tail -n 5
}

# Git Autocommit rapido con push
gt() {
    git add .
    if [ -z "$1" ]; then
        echo "Inserisci il messaggio del commit:"
        read msg
        git commit -m "$msg"
    else
        git commit -m "$1"
    fi
    git push
}

# Parser informativo interno per capire l'HelmRelease corrente nel prompt
__flux_hr_info() {
    local hr_file=$(grep -l "kind: HelmRelease" *.yaml 2>/dev/null | head -n 1)
    if [ -n "$hr_file" ]; then
        local hr_name=$(grep "name:" "$hr_file" | head -n 1 | awk '{print $2}')
        echo -e " [HR:$hr_name]"
    fi
}

################################################################################
# 6. DOCUMENTAZIONI INTEGRATE (MANUALI VELOCI)
################################################################################
gitman() {
  printf "\n\033[1;32m%-30s %-70s %s\033[0m\n" "Operazione" "Sintassi" "Descrizione"
  printf "%-30s %-70s %s\n" "------------------------------" "----------------------------------------------------------------------" "-----------"
  printf "%-30s %-70s %s\n" "Togliere dallo Stage" "git restore --staged <file>" "Riporta file da verde a rosso"
  printf "%-30s %-70s %s\n" "Annullare Modifiche Locali" "git restore <file>" "Ripristina file non committato"
  printf "%-30s %-70s %s\n" "Vedere Diff Locale" "git diff" "Mostra modifiche non in staging"
  printf "%-30s %-70s %s\n" "Vedere Diff Stage" "git diff --cached" "Mostra modifiche nello staging"
  printf "%-30s %-70s %s\n" "Diff tra Branch" "git diff master..demo" "Confronta due branch"
  printf "%-30s %-70s %s\n" "Vedere File Diversi" "git diff --name-status master..demo" "Lista file A/M/D tra branch"
  printf "%-30s %-70s %s\n" "Annullare Commit (Safe)" "git revert <hash>" "Crea commit opposto"
  printf "%-30s %-70s %s\n" "Provare Revert" "git revert -n <hash>" "Prepara revert senza commit"
  printf "%-30s %-70s %s\n" "Modificare Ultimo Commit" "git commit --amend" "Aggiorna ultimo commit"
  printf "%-30s %-70s %s\n" "Reset Soft" "git reset --soft HEAD~1" "Rimuove commit mantenendo staging"
  printf "%-30s %-70s %s\n" "Reset Hard" "git reset --hard HEAD" "Cancella modifiche non committate"
  printf "%-30s %-70s %s\n" "Eliminare file non tracciati" "git clean -f" "Rimuove file untracked"
  printf "%-30s %-70s %s\n" "Creare branch" "git switch -c nome-branch" "Crea e cambia branch"
  printf "%-30s %-70s %s\n" "Eliminare branch" "git branch -D nome-branch" "Forza eliminazione branch"
  printf "%-30s %-70s %s\n" "Merge branch" "git merge nome-branch" "Unisce branch corrente"
  printf "%-30s %-70s %s\n" "Rebase branch" "git rebase nome-branch" "Riallinea branch corrente"
  printf "%-30s %-70s %s\n" "Rebase Interattivo" "git rebase -i HEAD~N" "Squash/modifica commit"
  printf "%-30s %-70s %s\n" "Provare Merge senza Commit" "git merge --no-commit --no-ff branch" "Controlla merge prima del commit"
  printf "%-30s %-70s %s\n" "Annullare Merge" "git merge --abort" "Annulla merge in corso"
  printf "%-30s %-70s %s\n" "Visualizzare Cronologia" "git log --oneline --graph --all" "Storico completo grafico"
}

helman() {
  printf "\n\033[1;34m%-15s %-50s %s\033[0m\n" "Categoria" "Comando" "Descrizione"
  printf "%-15s %-50s %s\n" "---------------" "--------------------------------------------------" "--------------------------------------------------"
  printf "%-15s %-50s %s\n" "Repo" "helm repo add <name> <url>" "Aggiunge un repository remoto"
  printf "%-15s %-50s %s\n" "Update" "helm repo update" "Aggiorna le informazioni sui pacchetti locali"
  printf "%-15s %-50s %s\n" "Search" "helm search repo <keyword>" "Cerca pacchetti nei repo configurati"
  printf "%-15s %-50s %s\n" "List" "helm list -A" "Mostra tutte le release (tutti i namespace)"
  printf "%-15s %-50s %s\n" "Install" "helm install <release> <chart>" "Installa un nuovo pacchetto"
  printf "%-15s %-50s %s\n" "Upgrade" "helm upgrade --install <release> <chart>" "Aggiorna la release o la installa se non esiste"
  printf "%-15s %-50s %s\n" "Uninstall" "helm uninstall <release>" "Rimuove la release dal cluster"
  printf "%-15s %-50s %s\n" "History" "helm history <release>" "Mostra le revisioni passate di una release"
  printf "%-15s %-50s %s\n" "Rollback" "helm rollback <release> <revision>" "Ripristina una versione specifica"
  printf "%-15s %-50s %s\n" "Values" "helm get values <release>" "Mostra i parametri (values) usati per la release"
  printf "%-15s %-50s %s\n" "Manifest" "helm get manifest <release>" "Mostra i manifest YAML generati e deployati"
  printf "%-15s %-50s %s\n" "---------------" "--------------------------------------------------" "--------------------------------------------------"
  printf "\033[1;32m%-30s %-50s %s\033[0m\n" "Debug" "Sintassi" "Dettaglio"
  printf "%-30s %-50s %s\n" "Dry Run" "helm install --dry-run --debug" "Simula il deploy e stampa i manifest generati"
  printf "%-30s %-50s %s\n" "Template" "helm template <release> <chart>" "Renderizza i template YAML localmente"
  printf "%-30s %-50s %s\n" "Lint" "helm lint <chart-path>" "Verifica la sintassi e la struttura della Chart"
  printf "%-30s %-50s %s\n" "Show Values" "helm show values grafana/loki --version 7.0.0" "Mostra tutti i parametri predefiniti della Chart"
  printf "\n"
}

fluxman() {
  printf "\n\033[1;34m%-15s %-50s %s\033[0m\n" "Categoria" "Comando" "Descrizione"
  printf "%-15s %-50s %s\n" "---------------" "--------------------------------------------------" "--------------------------------------------------"
  printf "%-15s %-50s %s\n" "Kustomize" "flux get kustomizations" "Stato sincronizzazione manifest YAML"
  printf "%-15s %-50s %s\n" "Helm" "flux get helmreleases" "Stato delle release Helm gestite da Flux"
  printf "%-15s %-50s %s\n" "Sources" "flux get sources git" "Stato dei repository Git sorgente"
  printf "%-15s %-50s %s\n" "All" "flux get all -A" "Visione globale di tutte le risorse Flux"
  printf "%-15s %-50s %s\n" "Sync Flux" "flux reconcile ks flux-system" "Forza il check della configurazione cluster"
  printf "%-15s %-50s %s\n" "Sync App" "flux reconcile ks <name>" "Forza aggiornamento di una specifica Kustomization"
  printf "%-15s %-50s %s\n" "Sync Helm" "flux reconcile hr <name>" "Forza aggiornamento di una HelmRelease"
  printf "%-15s %-50s %s\n" "Sync Git" "flux reconcile source git <name>" "Pull immediato dal repository Git"
  printf "%-15s %-50s %s\n" "Suspend" "flux suspend ks <name>" "Ferma l'automazione (utile per test manuali)"
  printf "%-15s %-50s %s\n" "Resume" "flux resume ks <name>" "Riattiva l'automazione"
  printf "%-15s %-50s %s\n" "Logs" "flux logs -f" "Log aggregati di tutti i controller"
  printf "%-15s %-50s %s\n" "Trace" "flux trace <resource> <name>" "Analizza la catena di dipendenze di una risorsa"
  printf "%-15s %-50s %s\n" "Events" "flux get events -A" "Mostra gli eventi recenti di Flux in tutti i namespace"
  printf "%-15s %-50s %s\n" "K8s Events" "kubectl get events --sort-by='.lastTimestamp'" "Mostra gli eventi del cluster"
  printf "\033[1;33m%-15s %-50s %s\033[0m\n" "Local Valid." "--------------------------------------------------" "--------------------------------------------------"
  printf "%-15s %-50s %s\n" "Lint YAML" "yamllint <file.yaml>" "Verifica sintassi e formattazione YAML"
  printf "%-15s %-50s %s\n" "Build Kustom." "kustomize build <dir>" "Verifica logica e patch di Kustomize locale"
  printf "%-15s %-50s %s\n" "Dry-run K8s" "kustomize build . | kubectl apply --dry-run=client -f -" "Verifica validità manifest contro API K8s"
  printf "%-15s %-50s %s\n" "Flux Build" "flux build ks <name> --path <dir>" "Simula output finale di una Kustomization Flux"
  printf "\033[1;33m%-15s %-50s %s\033[0m\n" "Helm Valid." "--------------------------------------------------" "--------------------------------------------------"
  printf "%-15s %-50s %s\n" "Helm Lint" "helm lint <chart_dir>" "Verifica errori strutturali nella Chart Helm"
  printf "%-15s %-50s %s\n" "Helm Template" "helm template <name> <chart_dir> -f values.yaml" "Genera i manifest per testare i valori locali"
  printf "%-15s %-50s %s\n" "Flux HR Build" "flux build hr <name> --path <dir>" "Simula la risorsa HelmRelease locale per Flux"
  printf "%-15s %-50s %s\n" "---------------" "--------------------------------------------------" "--------------------------------------------------"
  printf "\033[1;32m%-30s %-50s %s\033[0m\n" "Sistema" "Sintassi" "Dettaglio"
  printf "%-30s %-50s %s\n" "Check Install" "flux check" "Verifica integrità dei controller nel cluster"
  printf "%-30s %-50s %s\n" "Stats" "flux stats -A" "Mostra consumo risorse dei componenti Flux"
  printf "%-30s %-50s %s\n" "Version" "flux version" "Mostra versione client e server"
  printf "\n"
}

dockerman() {
  printf "\n\033[1;34m%-15s %-50s %s\033[0m\n" "Categoria" "Comando" "Descrizione"
  printf "%-15s %-50s %s\n" "Containers" "docker ps -a" "Elenco container (anche fermi)"
  printf "%-15s %-50s %s\n" "Images" "docker images" "Elenco immagini locali"
  printf "%-15s %-50s %s\n" "Stats" "docker stats" "CPU, RAM e I/O in tempo reale"
  printf "%-15s %-50s %s\n" "Exec" "docker exec -it <id> bash" "Entra in un container attivo"
  printf "%-15s %-50s %s\n" "Logs" "docker logs -f --tail 100 <id>" "Log in tempo reale (ultime 100 righe)"
  printf "%-15s %-50s %s\n" "Prune Images" "docker image prune" "Rimuove solo le immagini 'dangling' (senza tag)"
  printf "%-15s %-50s %s\n" "Clean Old" "docker image prune -a" "Rimuove TUTTE le immagini non usate"
  printf "%-15s %-50s %s\n" "RM Image" "docker rmi <image_id>" "Elimina una specifica immagine"
  printf "%-15s %-50s %s\n" "Compose Up" "docker compose up -d" "Avvia lo stack in background"
  printf "%-15s %-50s %s\n" "Compose Down" "docker compose down -v" "Spegne e rimuove volumi"
  printf "%-15s %-50s %s\n" "Stop Service" "docker compose stop <service>" "Ferma un servizio senza rimuoverlo"
  printf "%-15s %-50s %s\n" "Down Service" "docker compose rm -sv <service>" "Rimuove singolo servizio con relativi volumi"
  printf "%-15s %-50s %s\n" "---------------" "--------------------------------------------------" "--------------------------------------------------"
  printf "\033[1;32m%-30s %-50s %s\033[0m\n" "Focus" "Sintassi" "Dettaglio"
  printf "%-30s %-50s %s\n" "Down senza dipendenze" "docker compose rm -sv <service>" "Ferma e rimuove il servizio ignorando le dep."
  printf "%-30s %-50s %s\n" "Pulizia selettiva" "docker image prune -a --filter \"until=24h\"" "Rimuove immagini non usate più vecchie di 24h"
  printf "%-30s %-50s %s\n" "Stop No-Deps" "docker compose stop --no-deps <svc>" "Ferma il servizio ignorando dipendenze"
  printf "%-30s %-50s %s\n" "RM No-Deps" "docker compose rm -sv --no-deps <svc>" "Rimuove il servizio ignorando dipendenze"
  printf "\n"
}

k8sman() {
  printf "\n\033[1;35m%-20s %-75s %s\033[0m\n" "Risorsa" "Comando In-Line (Imperativo)" "Dettaglio Operativo"
  printf "%-20s %-75s %s\n" "--------------------" "---------------------------------------------------------------------------" "--------------------"
  printf "%-20s %-75s %s\n" "Pod (Run)" "kubectl run nginx --image=nginx --restart=Never" "Avvia un singolo Pod autonomo"
  printf "%-20s %-75s %s\n" "Pod + Env" "kubectl run app --image=nginx --env=\"ENV=prod\" --env=\"DEBUG=true\"" "Avvia Pod con variabili d'ambiente"
  printf "%-20s %-75s %s\n" "Deployment" "kubectl create deployment web --image=nginx --replicas=3" "Crea un Deployment con 3 repliche"
  printf "%-20s %-75s %s\n" "ConfigMap (Literal)" "kubectl create configmap my-config --from-literal=db.host=localhost" "Crea CM da coppie chiave-valore"
  printf "%-20s %-75s %s\n" "ConfigMap (File)" "kubectl create configmap app-env --from-file=.env" "Crea CM importando un file intero"
  printf "%-20s %-75s %s\n" "Secret (Generic)" "kubectl create secret generic db-pass --from-literal=password=OpaqueKey" "Crea Secret generico criptato in Base64"
  printf "%-20s %-75s %s\n" "Secret (Docker)" "kubectl create secret docker-registry regcred --docker-password=<pwd>" "Crea Secret per pullare da registry privati"
  printf "%-20s %-75s %s\n" "Expose (Service)" "kubectl expose deployment web --port=80 --target-port=8080 --type=ClusterIP" "Genera un Servizio ClusterIP per un Deploy"
  printf "\033[1;33m%-20s %-75s %s\033[0m\n" "Generazione YAML" "---------------------------------------------------------------------------" "--------------------"
  printf "%-20s %-75s %s\n" "Dry-Run Deploy" "kubectl create deployment nginx --image=nginx --dry-run=client -o yaml" "Genera lo YAML del Deploy senza applicarlo"
  printf "%-20s %-75s %s\n" "Dry-Run ConfigMap" "kubectl create configmap cfg --from-literal=k=v --dry-run=client -o yaml" "Genera lo YAML della ConfigMap a schermo"
  printf "%-20s %-75s %s\n" "Export su File" "kubectl run pod-test --image=redis --dry-run=client -o yaml > pod.yaml" "Salva il manifest generato direttamente in locale"
  printf "\n"
}