#!/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 @- < >(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"