331 lines
8.4 KiB
Bash
331 lines
8.4 KiB
Bash
#!/bin/bash
|
|
#
|
|
# Zabbix Server Auto-Registration Configuration Script
|
|
# Creates auto-registration actions via the Zabbix API.
|
|
# Target server: zabbix.snarfnet.net
|
|
#
|
|
# Usage: bash configure_server_autoregistration.sh -u <api_user> -p <api_password>
|
|
#
|
|
# Prerequisites: curl, jq
|
|
#
|
|
set -euo pipefail
|
|
|
|
# --- Defaults ---
|
|
ZABBIX_URL="https://zabbix.snarfnet.net/api_jsonrpc.php"
|
|
API_USER=""
|
|
API_PASSWORD=""
|
|
AUTH_TOKEN=""
|
|
|
|
# --- Parse Arguments ---
|
|
usage() {
|
|
cat << EOF
|
|
Usage: $0 -u <username> -p <password> [-s <server_url>]
|
|
|
|
Options:
|
|
-u Zabbix API username (e.g., Admin)
|
|
-p Zabbix API password
|
|
-s Zabbix API URL (default: ${ZABBIX_URL})
|
|
-h Show this help
|
|
|
|
Example:
|
|
$0 -u Admin -p zabbix
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
while getopts "u:p:s:h" opt; do
|
|
case ${opt} in
|
|
u) API_USER="${OPTARG}" ;;
|
|
p) API_PASSWORD="${OPTARG}" ;;
|
|
s) ZABBIX_URL="${OPTARG}" ;;
|
|
h) usage ;;
|
|
*) usage ;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "${API_USER}" ] || [ -z "${API_PASSWORD}" ]; then
|
|
echo "ERROR: -u and -p are required."
|
|
usage
|
|
fi
|
|
|
|
# --- Functions ---
|
|
|
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2; }
|
|
|
|
api_call() {
|
|
local payload="$1"
|
|
local response
|
|
response=$(curl -s -X POST "${ZABBIX_URL}" \
|
|
-H "Content-Type: application/json-rpc" \
|
|
-d "${payload}")
|
|
|
|
# Check for errors
|
|
local error
|
|
error=$(echo "${response}" | jq -r '.error // empty')
|
|
if [ -n "${error}" ]; then
|
|
log "ERROR: API call failed:"
|
|
echo "${response}" | jq '.error' >&2
|
|
return 1
|
|
fi
|
|
|
|
echo "${response}"
|
|
}
|
|
|
|
authenticate() {
|
|
log "Authenticating with Zabbix API..."
|
|
local response
|
|
response=$(api_call "{
|
|
\"jsonrpc\": \"2.0\",
|
|
\"method\": \"user.login\",
|
|
\"params\": {
|
|
\"username\": \"${API_USER}\",
|
|
\"password\": \"${API_PASSWORD}\"
|
|
},
|
|
\"id\": 1
|
|
}")
|
|
|
|
AUTH_TOKEN=$(echo "${response}" | jq -r '.result')
|
|
if [ -z "${AUTH_TOKEN}" ] || [ "${AUTH_TOKEN}" = "null" ]; then
|
|
log "ERROR: Authentication failed. Check username/password."
|
|
exit 1
|
|
fi
|
|
log "Authenticated successfully."
|
|
}
|
|
|
|
get_or_create_hostgroup() {
|
|
local group_name="$1"
|
|
|
|
# Try to find existing group
|
|
local response
|
|
response=$(api_call "{
|
|
\"jsonrpc\": \"2.0\",
|
|
\"method\": \"hostgroup.get\",
|
|
\"params\": {
|
|
\"filter\": {
|
|
\"name\": [\"${group_name}\"]
|
|
}
|
|
},
|
|
\"auth\": \"${AUTH_TOKEN}\",
|
|
\"id\": 3
|
|
}")
|
|
|
|
local groupid
|
|
groupid=$(echo "${response}" | jq -r '.result[0].groupid // empty')
|
|
|
|
if [ -n "${groupid}" ]; then
|
|
log " Found host group '${group_name}' (ID: ${groupid})"
|
|
echo "${groupid}"
|
|
return
|
|
fi
|
|
|
|
# Create the group
|
|
log " Creating host group '${group_name}'..."
|
|
response=$(api_call "{
|
|
\"jsonrpc\": \"2.0\",
|
|
\"method\": \"hostgroup.create\",
|
|
\"params\": {
|
|
\"name\": \"${group_name}\"
|
|
},
|
|
\"auth\": \"${AUTH_TOKEN}\",
|
|
\"id\": 4
|
|
}")
|
|
|
|
groupid=$(echo "${response}" | jq -r '.result.groupids[0] // empty')
|
|
if [ -z "${groupid}" ]; then
|
|
log "ERROR: Failed to create host group '${group_name}'."
|
|
echo "${response}" | jq . >&2
|
|
exit 1
|
|
fi
|
|
|
|
log " Created host group '${group_name}' (ID: ${groupid})"
|
|
echo "${groupid}"
|
|
}
|
|
|
|
get_template_id() {
|
|
local template_name="$1"
|
|
|
|
local response
|
|
response=$(api_call "{
|
|
\"jsonrpc\": \"2.0\",
|
|
\"method\": \"template.get\",
|
|
\"params\": {
|
|
\"filter\": {
|
|
\"host\": [\"${template_name}\"]
|
|
}
|
|
},
|
|
\"auth\": \"${AUTH_TOKEN}\",
|
|
\"id\": 5
|
|
}")
|
|
|
|
local templateid
|
|
templateid=$(echo "${response}" | jq -r '.result[0].templateid // empty')
|
|
|
|
if [ -z "${templateid}" ]; then
|
|
# Try searching by visible name
|
|
response=$(api_call "{
|
|
\"jsonrpc\": \"2.0\",
|
|
\"method\": \"template.get\",
|
|
\"params\": {
|
|
\"search\": {
|
|
\"name\": \"${template_name}\"
|
|
}
|
|
},
|
|
\"auth\": \"${AUTH_TOKEN}\",
|
|
\"id\": 6
|
|
}")
|
|
templateid=$(echo "${response}" | jq -r '.result[0].templateid // empty')
|
|
fi
|
|
|
|
if [ -z "${templateid}" ]; then
|
|
log " WARNING: Template '${template_name}' not found. Skipping template link."
|
|
echo ""
|
|
return
|
|
fi
|
|
|
|
log " Found template '${template_name}' (ID: ${templateid})"
|
|
echo "${templateid}"
|
|
}
|
|
|
|
create_autoregistration_action() {
|
|
local action_name="$1"
|
|
local metadata_value="$2"
|
|
local groupid="$3"
|
|
local templateid="$4"
|
|
|
|
# Check if action already exists
|
|
local response
|
|
response=$(api_call "{
|
|
\"jsonrpc\": \"2.0\",
|
|
\"method\": \"action.get\",
|
|
\"params\": {
|
|
\"filter\": {
|
|
\"name\": \"${action_name}\",
|
|
\"eventsource\": \"2\"
|
|
}
|
|
},
|
|
\"auth\": \"${AUTH_TOKEN}\",
|
|
\"id\": 7
|
|
}")
|
|
|
|
local existing
|
|
existing=$(echo "${response}" | jq -r '.result[0].actionid // empty')
|
|
if [ -n "${existing}" ]; then
|
|
log " Action '${action_name}' already exists (ID: ${existing}). Skipping."
|
|
return
|
|
fi
|
|
|
|
# Build operations array
|
|
local operations="[
|
|
{
|
|
\"operationtype\": \"4\",
|
|
\"opgroup\": [
|
|
{
|
|
\"groupid\": \"${groupid}\"
|
|
}
|
|
]
|
|
}"
|
|
|
|
# Add template link if we have a template ID
|
|
if [ -n "${templateid}" ]; then
|
|
operations="${operations},
|
|
{
|
|
\"operationtype\": \"6\",
|
|
\"optemplate\": [
|
|
{
|
|
\"templateid\": \"${templateid}\"
|
|
}
|
|
]
|
|
}"
|
|
fi
|
|
|
|
operations="${operations}]"
|
|
|
|
# Create the action
|
|
log " Creating auto-registration action '${action_name}'..."
|
|
response=$(api_call "{
|
|
\"jsonrpc\": \"2.0\",
|
|
\"method\": \"action.create\",
|
|
\"params\": {
|
|
\"name\": \"${action_name}\",
|
|
\"eventsource\": \"2\",
|
|
\"status\": \"0\",
|
|
\"filter\": {
|
|
\"evaltype\": \"0\",
|
|
\"conditions\": [
|
|
{
|
|
\"conditiontype\": \"24\",
|
|
\"operator\": \"2\",
|
|
\"value\": \"${metadata_value}\"
|
|
}
|
|
]
|
|
},
|
|
\"operations\": ${operations}
|
|
},
|
|
\"auth\": \"${AUTH_TOKEN}\",
|
|
\"id\": 8
|
|
}")
|
|
|
|
local actionid
|
|
actionid=$(echo "${response}" | jq -r '.result.actionids[0] // empty')
|
|
if [ -n "${actionid}" ]; then
|
|
log " Created action '${action_name}' (ID: ${actionid})"
|
|
else
|
|
log " ERROR: Failed to create action '${action_name}'."
|
|
echo "${response}" | jq . >&2
|
|
fi
|
|
}
|
|
|
|
logout() {
|
|
api_call "{
|
|
\"jsonrpc\": \"2.0\",
|
|
\"method\": \"user.logout\",
|
|
\"params\": [],
|
|
\"auth\": \"${AUTH_TOKEN}\",
|
|
\"id\": 99
|
|
}" > /dev/null 2>&1 || true
|
|
log "Logged out."
|
|
}
|
|
|
|
# --- Main ---
|
|
|
|
log "=== Zabbix Server Auto-Registration Configuration ==="
|
|
log "Server: ${ZABBIX_URL}"
|
|
|
|
# Check dependencies
|
|
for cmd in curl jq; do
|
|
if ! command -v "${cmd}" &> /dev/null; then
|
|
log "ERROR: '${cmd}' is required but not installed."
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Authenticate
|
|
authenticate
|
|
|
|
# Get/create host groups
|
|
log "Setting up host groups..."
|
|
LINUX_GROUP_ID=$(get_or_create_hostgroup "Linux servers")
|
|
WINDOWS_GROUP_ID=$(get_or_create_hostgroup "Windows servers")
|
|
|
|
# Find templates
|
|
log "Looking up templates..."
|
|
LINUX_TEMPLATE_ID=$(get_template_id "Linux by Zabbix agent active")
|
|
WINDOWS_TEMPLATE_ID=$(get_template_id "Windows by Zabbix agent active")
|
|
|
|
# Create auto-registration actions
|
|
log "Creating auto-registration actions..."
|
|
create_autoregistration_action "Auto-register Linux hosts" "Linux" "${LINUX_GROUP_ID}" "${LINUX_TEMPLATE_ID}"
|
|
create_autoregistration_action "Auto-register Windows hosts" "Windows" "${WINDOWS_GROUP_ID}" "${WINDOWS_TEMPLATE_ID}"
|
|
|
|
# Logout
|
|
logout
|
|
|
|
log ""
|
|
log "=== Configuration Complete ==="
|
|
log ""
|
|
log "Summary:"
|
|
log " - Linux hosts with metadata 'Linux' → group 'Linux servers' + template"
|
|
log " - Windows hosts with metadata 'Windows' → group 'Windows servers' + template"
|
|
log ""
|
|
log "Agents configured with the matching PSK key should now auto-register."
|