258 lines
7.7 KiB
Bash
Executable File
258 lines
7.7 KiB
Bash
Executable File
#!/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"
|
||
|