Ad Widget

Collapse

Batch geolocate Hosts on Zabbix 7 using IP mapping csv

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • rich@974
    Junior Member
    • Oct 2024
    • 13

    #1

    Batch geolocate Hosts on Zabbix 7 using IP mapping csv

    In my organisation we use an IP mapping system to keep track of on which site the machines are.
    So I made a CSV file with the name of the site, the IP, lattitude and longitude

    it looks like this
    Code:
    Name;Adresse-réseau;Nom-du-site;Adresse;Ville;Téléphone;niusite;lat;long;latl ong;url;
    Site-myCity-DSI;10.1.0.0;DIRECTION INFORMATIQUE;77, My Street;MY CITY;;411_150;49.25796858;4.03180774;49.25796858, 4.03180774;;
    Site-otherCity-DSI_lan-srv;10.2.0.0;DIRECTION Info Lan Srv;77 Other Street;OTHER CITY;;411_151;43.60447192;1.44385434;43.60447192, 1.44385434;;
    Of course I have many sites so I use this very short file just for testing

    Now I used chatGPT to help me translate a bash script I used on Centreon to do about the same thing, here it is:
    Code:
    #!/bin/bash
    
    # Zabbix API configuration
    ZABBIX_API_URL="http://<my zabbix server ip>/zabbix/api_jsonrpc.php"
    ZABBIX_USER="<my loggin>" # Use a zabbix account with super admin rights
    ZABBIX_PASSWORD="<my password>" # Replace with your Zabbix password
    
    # CSV file path
    FILE="${1}"
    
    # Get the API authentication token
    AUTH_TOKEN=$(curl -s -X POST -H "Content-Type: application/json" -d '{
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
    "username": "'"$ZABBIX_USER"'",
    "password": "'"$ZABBIX_PASSWORD"'"
    },
    "id": 1
    }' $ZABBIX_API_URL | jq -r '.result')
    
    # Ensure token was obtained
    if [ -z "$AUTH_TOKEN" ]; then
    echo "Failed to authenticate to Zabbix API."
    exit 1
    fi
    
    # Read the CSV file line by line
    IFS=$'\n'
    ((c=-1))
    for line in $(cat ${FILE}); do
    ((c++))
    if ((c==0)); then
    continue
    fi
    
    # Parse CSV line into variables
    IFS=';'
    read nom ip nomsite adresse ville telephone niusite lat long latlong url <<<"${line}"
    
    # Extract the subnet (first two segments of the IP address)
    subnet=$(echo "$ip" | cut -d'.' -f1,2)
    
    # Retrieve all host IDs that match the subnet and process them individually
    HOST_IDS=$(curl -s -X POST -H "Content-Type: application/json" -d '{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
    "output": ["hostid"],
    "search": {
    "ip": "'"$subnet"'."
    },
    "searchByAny": true
    },
    "auth": "'"$AUTH_TOKEN"'",
    "id": 1
    }' $ZABBIX_API_URL | jq -r '.result[].hostid')
    
    # Check if HOST_IDS is empty and notify if no hosts were found
    if [ -z "$HOST_IDS" ]; then
    echo "No host found for subnet $subnet. Skipping..."
    continue
    fi
    
    # Enable inventory and then update latitude/longitude
    while IFS= read -r HOST_ID; do
    # Step 1: Enable inventory
    enable_result=$(curl -s -X POST -H "Content-Type: application/json" -d '{
    "jsonrpc": "2.0",
    "method": "host.update",
    "params": {
    "hostid": "'"$HOST_ID"'",
    "inventory_mode": 0
    },
    "auth": "'"$AUTH_TOKEN"'",
    "id": 1
    }' $ZABBIX_API_URL)
    
    if [[ $(echo "$enable_result" | jq -r '.result') != "null" ]]; then
    echo "Enabled inventory for host (ID: $HOST_ID)."
    else
    echo "Failed to enable inventory for host (ID: $HOST_ID). Response: $enable_result"
    continue
    fi
    
    # Wait briefly to ensure inventory setting takes effect
    sleep 1
    
    # Step 2: Update location fields in the inventory
    update_result=$(curl -s -X POST -H "Content-Type: application/json" -d '{
    "jsonrpc": "2.0",
    "method": "host.update",
    "params": {
    "hostid": "'"$HOST_ID"'",
    "inventory": {
    "location_lat": "'"$lat"'",
    "location_lon": "'"$long"'"
    }
    },
    "auth": "'"$AUTH_TOKEN"'",
    "id": 1
    }' $ZABBIX_API_URL)
    
    if [[ $(echo "$update_result" | jq -r '.result') != "null" ]]; then
    echo "Updated host (ID: $HOST_ID) for $nom (Subnet: $subnet) with Latitude: $lat and Longitude: $long"
    else
    echo "Failed to update host (ID: $HOST_ID) for $nom (Subnet: $subnet). Response: $update_result"
    fi
    done <<< "$HOST_IDS"
    
    done
    
    # Logout from Zabbix API
    curl -s -X POST -H "Content-Type: application/json" -d '{
    "jsonrpc": "2.0",
    "method": "user.logout",
    "params": [],
    "auth": "'"$AUTH_TOKEN"'",
    "id": 1
    }' $ZABBIX_API_URL > /dev/null
    
    echo "Script completed."
    And you know what ? It works

    To run the script:
    - make sure the script and your csv file are in the same folder, on the zabbix server
    - make sur to make the script executable with
    Code:
    chmod +x zabbix-geotag-hosts.sh
    ​- and run the script like
    Code:
    sudo bash ./zabbix-geotag-hosts.sh IPmapping.csv
    I'm sure you could have come up with that yourself, ​but now you don't have to ^^

    If there is a way to make it better, please let me know
Working...