Automagic ansible updates using the reports.

This commit is contained in:
Andreas B. Mundt 2023-12-18 12:57:15 +01:00
parent 877396dc15
commit 7ce165553d
5 changed files with 209 additions and 137 deletions

24
tools/collector Executable file
View file

@ -0,0 +1,24 @@
#!/usr/bin/bash
#
# collect messages from reporter and drop them into log files
#
set -eu
port=1234
#logdir="/var/log/collector"
logdir="/tmp/collector"
mkdir -vp "$logdir"
nc -k -l -u -p "$port" | while read line ; do
sndr="${line%%:*}"
msg="${line#*: }"
if [[ "$sndr" =~ [a-z0-9]+ ]] ; then
if [[ "$msg" =~ ^-------\ .+\ -------$ ]] ; then
echo "$(date --rfc-3339=seconds) → Message from '$sndr' received."
echo "$msg" > "$logdir/$sndr"
else
echo "$msg" >> "$logdir/$sndr"
fi
fi
done

72
tools/emitter Executable file
View file

@ -0,0 +1,72 @@
#!/usr/bin/bash
set -eu
## maximal age of file in minutes:
age="15"
pbook="lmn-client"
logdir="/tmp/collector"
debug=false
## date of latest git commit in ansible repository:
git_date="$(date --iso-8601=seconds --date="$(git log --date=iso-strict | \
head -3 | sed -nE "s/^Date:\s+(.+)$/\1/p")")"
#dir="$(mktemp -d)"
dir="/tmp/emitter"
mkdir -vp "$dir"
touch "$dir/${git_date//T*/}"
hlist=""
n=0
find_outdated(){
hlist=""
n=0
while IFS= read -r -d '' file ; do
$debug && echo -n "Processing host '$file' with IP address "
d="$(sed -nE "s/\s+drwx.+([0-9]{4}-[0-9]{2}-[0-9]{2} \S+).*/\1/p" "$file" | head -1)"
if [[ -z "$d" ]] || [[ $(date --date="$d" +%s) -lt $(date --date="$git_date" +%s) ]] ; then
r='([0-9]{1,3}\.){3}[0-9]{1,3}'
ipa="$(sed -nE "s|^\s+default via.+ src ($r) metric.+|\1|p" "$file")"
if [[ -z "$ipa" ]] ; then
# FIXME: Outdated report format, trying fallback:
ipa="$(grep -E "\s+2: en" -A3 "$file" | \
sed -nE "s|.+inet (10\.190\.[[:digit:]]{1,3}\.[[:digit:]]{1,3})/.+|\1|p")"
fi
$debug && echo "'$ipa'."
if ! grep -q "$ipa" "$dir/${git_date//T*/}" ; then
echo "$ipa" >> "$dir/${git_date//T*/}"
hlist="$hlist,$ipa"
n=$(( n + 1 ))
else
$debug && echo "Host already processed before."
fi
fi
done < <(find "$logdir" -maxdepth 1 -type f -mmin -$age -print0)
hlist="${hlist//^,/}"
}
run_ansible(){
local hsts="$1"
if [[ -n "$hsts" ]] ; then
if ! echo | ANSIBLE_RETRY_FILES_ENABLED=1 \
ANSIBLE_RETRY_FILES_SAVE_PATH="$dir" \
ansible-playbook --vault-password-file ~/.vaultpwd \
-bi inventory.yml "$pbook.yml" -l "$hsts" ; then
while IFS= read -r ipa ; do
sed -i "/$ipa/d" "$dir/${git_date//T*/}"
echo "IP address '$ipa' removed from '$dir/${git_date//T*/}'."
done < "$dir/$pbook.retry"
fi
fi
}
#################
while true ; do
date --rfc-3339=seconds
find_outdated
run_ansible "$hlist"
t=$(( 600/(n*n+1) ))
echo -n "Sleeping for $t seconds now ... "
sleep $t
done

17
tools/wol-generator.sh Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/bash
#
# Pipe the '--list-hosts' output of ansible into this program to wake up all corresponding hosts:
#
# ansible-playbook [...] -i inventory/inventory.yml -l R317 --list-hosts | ./wol-generator.sh
#
set -eu
tmpf="$(mktemp)"
devs='devices.csv'
while read -r line ; do
sed -nE -e "s%.*(..:..:..:..:..:..);(${line//./\\.});.*%\1 \2%p" "$devs" >> "$tmpf"
done < <(cat - | grep -E "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
wakeonlan -f "$tmpf"
rm "$tmpf"