Mam ten skrypt, który wykonuje wyszukiwanie poświadczenie dla każdego hosta, w systemie skarbca na miejscu, a następnie prowadzi do niego przerywnik.

#!/bin/bash

for host in `cat ~/.ansible/hosts`
  do
    SECRET=`/opt/vault/bin/get-admin-credential --tag=$host`
    HOST=`echo $SECRET | cut -d ';' -f1`
    LOGIN=`echo $SECRET | cut -d ';' -f2`
    DOMAIN=`echo $SECRET | cut -d ';' -f3`
    PWD=`echo $SECRET | cut -d ';' -f4`

    if [ -z "$DOMAIN" ]; then
      ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN ansible_password=$PWD" --limit $host
    else
      ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN@$DOMAIN ansible_password=$PWD" --limit $host
    fi
  done

To pętle nad każdym gospodarzem sekwencyjnie, próbowałem rzeczy z GNU parallel, ale nie byłem w stanie zrobić tego, czego chcę, prowadzenie pętli z 5 równolegle.

Ktoś wskazuje mnie we właściwym kierunku?

2
Greg 25 marzec 2020, 16:33

2 odpowiedzi

Najlepsza odpowiedź

Nie mam żadnych kryteriów "lub>" "lub " , więc jest to całkowicie nieświadomie, ale może się zamknąć:

doit(){
   host="$1"

   SECRET=$(/opt/vault/bin/get-admin-credential --tag=$host)
   HOST=$(echo $SECRET | cut -d ';' -f1)
   LOGIN=$(echo $SECRET | cut -d ';' -f2)
   DOMAIN=$(echo $SECRET | cut -d ';' -f3)
   PWD=$(echo $SECRET | cut -d ';' -f4)

   if [ -z "$DOMAIN" ]; then
      ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN ansible_password=$PWD" --limit $host
   else
      ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$HOST ansible_user=$LOGIN@$DOMAIN ansible_password=$PWD" --limit $host
   fi
}

# Export doit function to subshells created by GNU Parallel
export -f doit

parallel -a ~/.ansible/hosts doit

Stylistycznie istnieje kilka ulepszeń. Po pierwsze, zmienne powłoki składające się z wielkich liter są zarezerwowane, więc nie powinieneś użyć HOST, DOMAIN, DOMAIN itp. Również prawdopodobnie można również uprościć wszystkie nieestetyczne cięcie i echo Sekret za pomocą IFS=';' i read w ten sposób:

SECRET=$(/opt/vault/bin/get-admin-credential --tag=$host)
IFS=';' read host login domain pwd <<< "$SECRET"

Więc moja najlepsza i ostateczna odpowiedź brzmi:

doit(){
   host="$1"

   secret=$(/opt/vault/bin/get-admin-credential --tag=$host)
   IFS=';' read host login domain pwd <<< "$secret"

   if [ -z "$domain" ]; then
      ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$host ansible_user=$login ansible_password=$pwd" --limit $host
   else
      ansible-playbook -i ~/.ansible/hosts ~/.ansible/windows.yml -e "ansible_host=$host ansible_user=$login@$domain ansible_password=$pwd" --limit $host
   fi
}

# Export doit function to subshells created by GNU Parallel
export -f doit

parallel -a ~/.ansible/hosts doit
2
Mark Setchell 25 marzec 2020, 14:29

Po prostu musisz uruchomić ansible-playbook w tle za pomocą terminatora polecenia &. Zauważ jednak, że cała pętla może być uproszczona i poprawiona.

run_playbook () {
  ansible-playbook -i ~/.ansible/hosts \
                   -e "ansible_host=$2 ansible_login=$3 ansible_password=$4" \
                   ~/.ansible/windows.yml --limit "$1"
}

while IFS= read -r host; do
    secret=$(/opt/vault/bin/get-admin-credential --tag="$host")
    IFS=";" read -r shost slogin sdomain spasswd _ <<< "$secret"
    if [[ -n $sdomain ]]; then
      login="$slogin@$sdomain"
    fi
    run_playbook "$host" "$shost" "$login" "$password" &
done < ~/.ansible/hosts
1
chepner 25 marzec 2020, 14:40