sync-awx-inventory/sync-awx-inventory.sh
2025-05-30 08:11:49 +02:00

258 lines
7.7 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
############################################################
# Decription: this script synchronize the hosts source
# file with an AWX inventory
#
# Author: Gilles Mouchet (gilles.mouchet@gmail.com)
# Creation Date: 29.05.2025
# Version: 1.0
#
# Install: see README.md
# Usage: ./sync-awx-inventory.sh --help
# Changelog:
# V1.0 - 29.05.2025 - GMo
# Added
# - Creation of script from scratch
#
############################################################
version=1.0
#user=user_name
#pass=secret
cred_file=$HOME/.awxcred
# awx server
awx_srv=awx
awx_srv_url=https://${awx_srv}.gmolab.net
# awx inventory name
awx_inventory=linux
# search domain in hosts file
search_domain=gmolab
search_domain_prefix=net
# hosts file
src_hosts_file=/etc/hosts
log_tag=syn_awx_inv
# array of host name in /etc/hosts
hosts_array=()
#----- FUNCTIONS -----#
# function add host in awx inventory
add_host_in_awx() { #inventories/{id}/hosts/
api_rc=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$awx_srv_url/api/v2/hosts/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $awx_token" \
-d @- <<EOF
{
"name": "$1",
"inventory": $inventory_id
}
EOF
)
#echo $api_rc
return $api_rc
}
# function delete host from AWX inventory
del_host_from_awx() {
# get host id
host_id=$(curl -s -H "Authorization: Bearer $awx_token" \
"$awx_srv_url/api/v2/inventories/$inventory_id/hosts/?name=$1" | jq -r '.results[0].id')
# check if host exist in inventory
if [[ "$host_id" == "null" || -z "$host_id" ]]; then
msg="'$1' not found in inventory id."
echo ${msg}; logger -t $log_tag ${msg}
exit 1
fi
# delete host
api_rc=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
-H "Authorization: Bearer $awx_token" \
"$awx_srv_url/api/v2/hosts/$host_id/")
return $api_rc
}
#--------------------------#
# END FUNCTION #
#--------------------------#
#--------------------------#
# MAIN #
#--------------------------#
# display stdout and stderr on screen and on log
# to read log use sudo "journalctl -f -t syn_awx_inv" command
exec > >(tee /dev/tty | logger -t $log_tag)
exec 2> >(tee /dev/tty >&2 | logger -t $log_tag)
case $1 in
-p|--parameter)
cat << EOF
Credentials file (\$cred_file): $cred_file
Source file (\$src_hosts_file): $src_hosts_file
AWX inventory (\$awx_inventory): $awx_inventory
Domain search in src (\$search_domain): $search_domain.$search_domain_prefix
AWX server url (\$awx_srv_url): $awx_srv_url
Log tag (\$log_tag): $log_tag
EOF
exit 1
;;
-h|--help)
cat << EOF
Usage: $(basename "$0") OPTIONS
Synchronizes the hosts source file with an AWX inventory
Options:
-p, --parameter display parameters
-l, --help display this help text and exit
-v, --version display the verion
EOF
exit
;;
-v|--version)
cat << EOF
$(basename "$0") v$version (c) 1990 - $(date +%Y) by Gilles Mouchet
Non-Commercial Use License See LICENSE for details
EOF
exit
;;
esac
logger -t $log_tag "[INFO] - start script"
#check if awx server is up
if ! nc -z -w 2 $awx_srv 22 2>/dev/null; then
echo "[ERROR] - server '$awx_srv_url' is not up"
exit 1
fi
# read awx credential
if [ -f $cred_file ]; then
awx_token=$(grep "token=" $cred_file | cut -d'=' -f2)
else
echo "[ERROR] - file $cred_file not found !"
exit 1
fi
#---------- create host list from inventory
# get inventory id
inventory_id=$(curl -s -H "Authorization: Bearer $awx_token" \
"$awx_srv_url/api/v2/inventories/?name=$awx_inventory"| jq -r '.results[0].id')
# get inventory items
# this curl display onliy the 25 first host (pagination)
#awx_item=$(curl -s -H "Authorization: Bearer $awx_token" \
# "$awx_srv_url/api/v2/inventories/$inventory_id/hosts/")
# this get ALL hosts in inventory
next_url="$awx_srv_url/api/v2/inventories/$inventory_id/hosts/"
while [ -n "$next_url" ] && [ "$next_url" != "null" ]; do
awx_item=$(curl -s -H "Authorization: Bearer $awx_token" -H "Accept: application/json" "$next_url")
# extract hostnames and add them to the table
mapfile -t new_hosts < <(echo "$awx_item" | jq -r '.results[].name')
hosts_in_awx+=("${new_hosts[@]}")
next_url=$(echo "$awx_item" | jq -r '.next')
# complete the URL if necessary
if [[ "$next_url" =~ ^/ ]]; then
next_url="$awx_srv_url$next_url"
fi
done
#---------- create host list from hosts file
# read hosts fiée
while IFS= read -r line; do
hosts_in_file+=("$line")
done < <( grep -v '^#' $src_hosts_file \
| sed 's/#.*//' \
| tr -s ' ' \
| tr '\t' ' ' \
| cut -d ' ' -f2- \
| tr ' ' '\n' \
| grep '\.'$search_domain'\.'$search_domain_prefix'$' \
| sed 's/\.'$search_domain'\.'$search_domain_prefix'$//' \
| sort -u
)
#
# for debug only
# test for pagination 30 hosts
#hosts_in_file=(titi gros-minet tom jerry cortex minus road-runner coyote bugs-bunny riri fifi loulou picsou \
# donald-duck mickey pluto mister-magoo droopy calimero scooby-doo samy daffy-duck popey \
# woody-woodpecker garfield casper winnie casper homer marge bart)
# test for pagination 25 hosts
#hosts_in_file=(titi gros-minet tom jerry cortex minus road-runner coyote bugs-bunny fifi loulou picsou \
# donald-duck mickey scooby-doo samy daffy-duck popey \
# woody-woodpecker garfield casper winnie casper homer marge bart)
# CAUTION delete all host in AWX inventory
#hosts_in_file=()
#---------- add host in awx inventory if not exixts
echo "[INFO] - add host to '$awx_inventory' AWX inventory"
action_add=false
# loop on each element of the source host file
for item_host in "${hosts_in_file[@]}"; do
found=false
# loop on each item from awx inventory
for item_awx in "${hosts_in_awx[@]}"; do
# check if host in source exist in awx inventoy
if [[ "$item_host" == "$item_awx" ]]; then
found=true
break
fi
done
# if not found, add host into awx inventory
if ! $found; then
action_add=true
add_host_in_awx $item_host
rc=$?
if [ "$rc" -eq "201" ]; then
echo "[SUCCESS] - host '$item_host' successfully added to '$awx_inventory' AWX inventory"
else
echo "[ERROR] - error $rc when adding '$item_host' to '$awx_inventory' AWX inventory"
#exit 1
fi
fi
done
if ! $action_add; then
echo "[INFO] - no hosts added to AWX '$awx_inventory' inventory"
fi
echo ""
#---------- check if hosts from awx exist in the source host file
#---------- if not, delete from awx inventory
echo "[INFO] - delete host from '$awx_inventory' AWX inventory"
action_del=false
# loop on each item from awx inventory
for item_awx in "${hosts_in_awx[@]}"; do
found=false
# loop on each element of the source host file
for item_host in "${hosts_in_file[@]}"; do
# check if host in awx inventory exist in the source host file
if [[ "$item_awx" == "$item_host" ]]; then
found=true
break
fi
done
# if not found, delete host from awx inventory
if ! $found; then
action_del=true
del_host_from_awx $item_awx
rc=$?
if [[ "$rc" == "204" ]]; then
echo "[SUCCESS] - host '$item_awx' successfully deleted from '$awx_inventory' inventory"
else
echo "[ERROR] - error $rc when deleting '$item_awx' from '$awx_inventory' AWX inventory"
exit 1
fi
fi
done
if ! $action_del; then
echo "[INFO] - no host to delete from '$awx_inventory AWX inventory"
fi
echo ""
echo "[INFO] - the '$awx_inventory' inventory on AWX is up to date"
logger -t $log_tag "[INFO] - start script"