ZabbixPreventDuplicateHosts Doppelte Hosts bei Installations des Agenten und Autoregistrierung verhindern
Aus znilwiki
Changelog:
- 25.06.2018 Erste Version 0.0.0.27
- 26.06.2018 Version 1.0.0.8: Modus für das hinzufügen eines Templates eingebaut / Fehlerbehandlung COM-Fehler eingebaut
Problem
Bei einem Kunden wurden die VMware-Templates von Zabbix genutzt. Dabei wird unter anderem jede VM automatisch als ein eigener Host registriert.
Die UUID der VM dient dabei als Host name, der Name der VM wird als Visible name genutzt:
Nun sollte zusätzlich der Zabbix-Agent auf allen VM installiert werden um mehr Möglichkeiten bei der Überwachung zu haben.
Aber natürlich sollten dafür die Hosts nicht doppelt angelegt sondern die bereits vorhandenen genutzt werden.
Dabei gab es zwei Hürden zu meistern:
- Die Schreibweise des Hostnamen: Im vCenter wurden die Namen der VMs sowohl GROßSCHREIBUNG als auch kleinschreibung als auch GROßundklein geschrieben. Und Zabbix ist "case sensitive", beachtet also die Groß- und Kleinschreibung.
- In der Agentkonfigurationsdatei soll der "Host name" angegeben werden - und das ist hier ja die UUID
Lösung
Für die Installation nutze ich eine selbst geschriebene Batchdatei: Zabbix Agent für Windows per Skript automatisch installieren Musterdatei (nur in einer aktuelleren Version).
In der Batchdatei wird der Computername ermittelt und in die Konfigurationsdatei des Agenten geschrieben.
In diese wollte ich nun nach der Ermittlung des Computernamens einen Prüfung gegen den Zabbix-Server einbauen:
- Prüfen ob es schon einen Hosts mit dem aktuellen Computernamen gibt, dabei sowohl in Host name als auch in Visible name nachsehen
- Falls ja den dort gesetzten Host name zurück geben
Der zurück gegebene Host name kann dann in der Konfigurationsdatei eingesetzt werden, der Visible name wird als Kommentar dazu geschrieben
Downloads
Version 1.0.0.8: ZabbixPreventDuplicateHosts_1.0.0.8.zip
Inhalt:
- ZabbixPreventDuplicateHosts.exe das Programm
- ZabbixPreventDuplicateHosts.ini Beispiel-ini mit Zugansdaten
- BatchExampleGetGostname.cmd Beispiel wie das ganze in einer Batch-Datei genutzt werden kann
- ZabbixPreventDuplicateHosts.au3 der Quellcode
Version 0.0.0.27: ZabbixPreventDuplicateHosts.zip
Inhalt:
- ZabbixPreventDuplicateHosts.exe das Programm
- ZabbixPreventDuplicateHosts.ini Beispiel-ini mit Zugansdaten
- BatchExample.cmd Beispiel wie das ganze in einer Batch-Datei genutzt werden kann
Vorbereitung
Legt auf dem Zabbix-Server einen Benutzer an der die API nutzen darf.
Dieser braucht mindestens lesenden Zugriff (am besten auf alle Hosts) und sollte sowohl im Benutzernamen als auch im Passwort auf Sonderzeichen verzichten.
In den Beispielen ist der Benutzer apiuser mit dem Passwort userpassword
Anleitung
Wir die ZabbixPreventDuplicateHosts.exe ohne Parameter oder mit /? aufgerufen so erscheint die Hilfe:
+------------------------------------------------------------------------------
| ZabbixPreventDuplicateHosts.exe - Version 1.0.0.8
+------------------------------------------------------------------------------
| 2018 von Bernhard Linz für http://znil.net - Kontakt: Bernhard@znil.net
+------------------------------------------------------------------------------
ZabbixPreventDuplicateHosts.exe prüft über die Zabbix-API ob es bereits einen
Host mit dem Namen des Computers gibt. Dabei werden verschiedene Schreibweisen
toleriert (Groß und Kleinschreibung, mit und ohne Domänensuffix) und der
gefundene Hostname zurück gegeben
-------------------------------------------------------------------------------
Aufruf für Abfragen:
--------------------
ZabbixPreventDuplicateHosts.exe [Parameter] <COMPUTERNAME>
ohne Parameter : Testet ob es einen Host mit der folgende Schreibweisen bei
'Host name' oder 'Visible name' schon gibt:
<COMPUTERNAME>.Computerdomain
<COMPUTERNAME>
Groß- und Kleinschreibung wird dabei ignoriert
/addVisibleName : Erweitert die Rückgabe um den Host 'Visible name'
/addHostID : Erweitert die Rückgabe um die Host-ID
Es findet eine Text-In-Text-Suche statt. Die Suche nach 'TEST8' findet also
die Hosts 'TEST8' aber auch 'TEST81', 'TEST8.beispiel.local' oder 'MeinTEST8443'
Es wird jeweils der kürzeste Treffer zurück gegeben (die wenigsten Zeichen).
Gibt es mehrere Treffer mit dem gleichen Namen so wird der älteste Eintrag in
Zabbix genommen
Rückgabe:
---------
Wird ein Host mit dem Namen gefunden so wird dessen Eintrag aus dem Feld
Host name
zurück gegeben - in der exakten Schreibweise. Ggf. steht bei LLD generierten
VMs die UUID. Der Exit-Code (%ERRORLEVEL%) ist 0
Wurde der Parameter '/addVisibleName' mit angegeben wo wird
Host name;Visible name
zurück gegeben.
Wird kein Host gefunden so ist der Rückgabewert
ZBXHOSTNOTFOUND
Der Exit-Code (%ERRORLEVEL%) ist 1
Gibt es einen Fehler so wird statt dessen eine passende Fehlerbeschreibung
zurück gegeben. Der Exit-Code (%ERRORLEVEL%) ist 2
Aufruf für Zusatzfunktionen:
----------------------------
ZabbixPreventDuplicateHosts.exe [Parameter] <HostID>
/AddTemplate=<ID> : Fügt dem Host das Template mit der angegebenen ID hinzu
Anmeldedaten des Zabbix-Servers:
--------------------------------
Für die Abfrage der API werden die URL, der Benutzername und das Passwort
benötigt. Diese lassen sich auf verschiedene Arten hinterlegen. Es wird in der
angegebenen Reihenfolge gesucht:
1. Per .ini-Datei im gleichen Verzeichnis:
C:\_AutoIt\ZabbixAgent\ZabbixPreventDuplicateHosts\ZabbixPreventDuplicateHosts.ini
Inhalt:
[ZABBIXAPI]
URL=http://IP_oder_DNSNAME/zabbix/api_jsonrpc.php
User=Benutzername
Password=Passwort
2. Über das Setzen der folgenden Umgebungsvariablen:
set ZABBIXURL="http://IP_oder_DNSNAME/zabbix/api_jsonrpc.php"
set ZABBIXUSER="Benutzername"
set ZABBIXPASSWORD="Passwort"
die dann per %ZABBIXURL%, %ZABBIXUSER% und %ZABBIXPASSWORD% genutzt
werden können. Dazu vor dem Aufruf z.B. in der gleichen CMD setzen.
3. Über das Setzen der folgenden Registry-Schlüssel
Schlüssel.....: HKLM\SOFTWARE\Zabbix\
Werte (REG_SZ): URL http://IP_oder_DNSNAME/zabbix/api_jsonrpc.php
User Benutzername
Password Passwort
zum Beispiel per Gruppenrichtlinie
Bitte Beachten:
Die URL kann auch mit https beginnen, Zertifikatsfehler werden ignoriert.
Je nach Installation ist der URL Pfad
http://IP_oder_DNSNAME/zabbix/api_jsonrpc.php oder
http://IP_oder_DNSNAME/api_jsonrpc.php
Für den API-Benutzer reichen lesende Rechte! Der Host kann aber nur gefunden
werden wenn für diesen auch Rechte vorhanden sind
+------------------------------------------------------------------------------
| ZabbixPreventDuplicateHosts.exe ist FREEWARE!
| Kopieren, weitergeben ausdrücklich erlaubt!
| Die jeweils aktuelleste Version, Anleitung und Quellcode findet Ihr unter:
| https://znil.net/index.php?title=ZabbixPreventDuplicateHosts
+------------------------------------------------------------------------------
Das Programm braucht natürlich die URL und die Zugangsdaten zum Zabbix-Server.
Zuerst sucht er in der .ini Datei im gleichen Verzeichnis, also passt die Daten dort an.
Alternativ geht es über Umgebungsvariablen oder Registry-Schlüssel (wie in der Hilfe beschrieben).
Host suchen
Sind die Daten in der ZabbixPreventDuplicateHosts.ini gemacht geht die Abfrage mit
ZabbixPreventDuplicateHosts.exe /AddVisibleName 9KL001dctest
In diesem Beispiel wird nach dem Host "9KL001dcte" gesucht.
Die Rückgabe ist:
423be0f8-175d-16c5-d2fa-817ed70079e3;9KL001DCTEST
Also die UUID (die Feld Host name steht) und der Name der VM.
Bei einem Host wo Visible name leer ist kommt folgendes zurück_
ZabbixPreventDuplicateHosts.exe /AddVisibleName 9KL001dc
Rückgabe:
9KL001DC;9KL001DC
Also beide mal der gleiche Wert (so macht das Zabbix)
Mit dem Parameter '/AddHostID' wird die Host-ID angehängt:
ZabbixPreventDuplicateHosts.exe /AddHostID 9KL001dctest
Rückgabe:
9KL001DCTEST;13714
Die Host-ID kann dann zum Beispiel genutzt werden um Templates mit dem Host zu verknüpfen.
In der BatchExampleGetHostname.cmd habe ich das ganze in einer Batch genutzt:
Quellcode:
@echo off
echo Ausgabe von allen 3 Werten:
echo ---------------------------
set ZABBIXHOSTNAME=
set ZABBIXVISIBLENAME=
set ZABBIXHOSTID=
for /f "tokens=1-3 delims=;" %%a in ('ZabbixPreventDuplicateHosts.exe /addVisibleName /addHostID %1') do (
set ZABBIXHOSTNAME=%%a
set ZABBIXVISIBLENAME=%%b
set ZABBIXHOSTID=%%c
)
echo Host name : %ZABBIXHOSTNAME%
echo Visible name: %ZABBIXVISIBLENAME%
echo Host ID : %ZABBIXHOSTID%
echo.
echo.
echo Ausgabe nur Host name:
echo ---------------------------
set ZABBIXHOSTNAME=
set ZABBIXVISIBLENAME=
set ZABBIXHOSTID=
for /f "tokens=*" %%a in ('ZabbixPreventDuplicateHosts.exe %1') do set ZABBIXHOSTNAME=%%a
echo Host name : %ZABBIXHOSTNAME%
Aufruf mit:
BatchExample.cmd 9KL001DCTEST
Rückgabe:
Ausgabe von allen 3 Werten: --------------------------- Host name : 423be0f8-175d-16c5-d2fa-817ed70079e3 Visible name: 9KL001DCTEST Host ID : 13714 Ausgabe nur Host name: --------------------------- Host name : 423be0f8-175d-16c5-d2fa-817ed70079e3
Template zum Host hinzufügen
Wenn man die Host-ID hat kann man unter Angabe der Template-ID dieses dem Host hinzufügen:
ZabbixPreventDuplicateHosts.exe /addTemplate=10462 13714
In diesem Beispiel wird das Template mit der ID 10462 dem Host mit der ID 13714 hinzugefügt.
Woher bekommt Ihr die Template-ID? Öffnet das Template im Webbrowser auf dem Zabbix-Server, die ID steht dann in der URL:
Wollt Ihr mehrere Templates hinzufügen so müsst Ihr für jedes einen weiteren Aufruf des Befehls hinzufügen.
Hat der Host das Template bereits so passiert nichts, Ihr erhaltet trotzdem die Meldung das es Erfolgreich hinzugefügt wurde.
Quellcode
#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=zabbix.ico
#AutoIt3Wrapper_Outfile=ZabbixPreventDuplicateHosts.exe
#AutoIt3Wrapper_UseUpx=y
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_Description=ZabbixPreventSuplicateHosts.exe
#AutoIt3Wrapper_Res_Fileversion=1.0.0.9
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=Apache License 2.0
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Res_Language=1031
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Array.au3>
#include <Date.au3>
Opt("TrayIconHide", 0)
Opt("MustDeclareVars", 1)
; ###############################################################################################################################
; ###############################################################################################################################
; ****************************************************************************************
; ## ## ### ######## #### ### ######## ## ######## ######
; ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
; ## ## ## ## ## ## ## ## ## ## ## ## ## ##
; ## ## ## ## ######## ## ## ## ######## ## ###### ######
; ## ## ######### ## ## ## ######### ## ## ## ## ##
; ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
; ### ## ## ## ## #### ## ## ######## ######## ######## ######
; ****************************************************************************************
Global $s_IniFile = @ScriptDir & "\" & StringTrimRight(@ScriptName, 4) & ".ini"
Global $oErrorHandler = ObjEvent("AutoIt.Error", "_COMErrFunc")
; 10 20 30 40 50 60 70 80
; 12345678901234567890123456789012345678901234567890123456789012345678901234567890
Dim $s_Header = _
"+------------------------------------------------------------------------------" & @CRLF & _
"| ZabbixPreventDuplicateHosts.exe - Version " & FileGetVersion(@ScriptName) & @CRLF & _
"+------------------------------------------------------------------------------" & @CRLF & _
"| 2018 von Bernhard Linz für http://znil.net - Kontakt: Bernhard@znil.net" & @CRLF & _
"+------------------------------------------------------------------------------" & @CRLF & _
@CRLF
; 10 20 30 40 50 60 70 80
; 12345678901234567890123456789012345678901234567890123456789012345678901234567890
Dim $s_HilfeText = _
"ZabbixPreventDuplicateHosts.exe prüft über die Zabbix-API ob es bereits einen" & @CRLF & _
"Host mit dem Namen des Computers gibt. Dabei werden verschiedene Schreibweisen" & @CRLF & _
"toleriert (Groß und Kleinschreibung, mit und ohne Domänensuffix) und der" & @CRLF & _
"gefundene Hostname zurück gegeben" & @CRLF & _
"-------------------------------------------------------------------------------" & @CRLF & _
@CRLF & _
"Aufruf für Abfragen: " & @CRLF & _
"-------------------- " & @CRLF & _
@CRLF & _
@ScriptName & " [Parameter] <COMPUTERNAME>" & @CRLF & _
@CRLF & _
" ohne Parameter : Testet ob es einen Host mit der folgende Schreibweisen bei" & @CRLF & _
" 'Host name' oder 'Visible name' schon gibt:" & @CRLF & _
" <COMPUTERNAME>.Computerdomain" & @CRLF & _
" <COMPUTERNAME>" & @CRLF & _
" Groß- und Kleinschreibung wird dabei ignoriert" & @CRLF & _
@CRLF & _
" /addVisibleName : Erweitert die Rückgabe um den Host 'Visible name'" & @CRLF & _
@CRLF & _
" /addHostID : Erweitert die Rückgabe um die Host-ID" & @CRLF & _
@CRLF & _
" Es findet eine Text-In-Text-Suche statt. Die Suche nach 'TEST8' findet also" & @CRLF & _
" die Hosts 'TEST8' aber auch 'TEST81', 'TEST8.beispiel.local' oder 'MeinTEST8443'" & @CRLF & _
" Es wird jeweils der kürzeste Treffer zurück gegeben (die wenigsten Zeichen)." & @CRLF & _
" Gibt es mehrere Treffer mit dem gleichen Namen so wird der älteste Eintrag in" & @CRLF & _
" Zabbix genommen" & @CRLF & _
@CRLF & _
"Rückgabe: " & @CRLF & _
"--------- " & @CRLF & _
@CRLF & _
" Wird ein Host mit dem Namen gefunden so wird dessen Eintrag aus dem Feld" & @CRLF & _
" Host name" & @CRLF & _
" zurück gegeben - in der exakten Schreibweise. Ggf. steht bei LLD generierten" & @CRLF & _
" VMs die UUID. Der Exit-Code (%ERRORLEVEL%) ist 0" & @CRLF & _
" Wurde der Parameter '/addVisibleName' mit angegeben wo wird" & @CRLF & _
" Host name;Visible name" & @CRLF & _
"zurück gegeben." & @CRLF & _
@CRLF & _
" Wird kein Host gefunden so ist der Rückgabewert" & @CRLF & _
" ZBXHOSTNOTFOUND" & @CRLF & _
" Der Exit-Code (%ERRORLEVEL%) ist 1" & @CRLF & _
@CRLF & _
" Gibt es einen Fehler so wird statt dessen eine passende Fehlerbeschreibung" & @CRLF & _
" zurück gegeben. Der Exit-Code (%ERRORLEVEL%) ist 2" & @CRLF & _
@CRLF & _
@CRLF & _
"Aufruf für Zusatzfunktionen: " & @CRLF & _
"---------------------------- " & @CRLF & _
@CRLF & _
@ScriptName & " [Parameter] <HostID>" & @CRLF & _
@CRLF & _
" /AddTemplate=<ID> : Fügt dem Host das Template mit der angegebenen ID hinzu" & @CRLF & _
@CRLF & _
@CRLF & _
"Anmeldedaten des Zabbix-Servers:" & @CRLF & _
"--------------------------------" & @CRLF & _
@CRLF & _
" Für die Abfrage der API werden die URL, der Benutzername und das Passwort" & @CRLF & _
" benötigt. Diese lassen sich auf verschiedene Arten hinterlegen. Es wird in der" & @CRLF & _
" angegebenen Reihenfolge gesucht:" & @CRLF & _
@CRLF & _
" 1. Per .ini-Datei im gleichen Verzeichnis:" & @CRLF & _
" " & $s_IniFile & @CRLF & _
" Inhalt:" & @CRLF & _
" [ZABBIXAPI]" & @CRLF & _
" URL=http://IP_oder_DNSNAME/zabbix/api_jsonrpc.php" & @CRLF & _
" User=Benutzername" & @CRLF & _
" Password=Passwort" & @CRLF & _
@CRLF & _
" 2. Über das Setzen der folgenden Umgebungsvariablen:" & @CRLF & _
' set ZABBIXURL="http://IP_oder_DNSNAME/zabbix/api_jsonrpc.php"' & @CRLF & _
' set ZABBIXUSER="Benutzername"' & @CRLF & _
' set ZABBIXPASSWORD="Passwort"' & @CRLF & _
" die dann per %ZABBIXURL%, %ZABBIXUSER% und %ZABBIXPASSWORD% genutzt" & @CRLF & _
" werden können. Dazu vor dem Aufruf z.B. in der gleichen CMD setzen." & @CRLF & _
@CRLF & _
" 3. Über das Setzen der folgenden Registry-Schlüssel" & @CRLF & _
" Schlüssel.....: HKLM\SOFTWARE\Zabbix\" & @CRLF & _
" Werte (REG_SZ): URL http://IP_oder_DNSNAME/zabbix/api_jsonrpc.php" & @CRLF & _
" User Benutzername" & @CRLF & _
" Password Passwort" & @CRLF & _
" zum Beispiel per Gruppenrichtlinie" & @CRLF & _
@CRLF & _
"Bitte Beachten:" & @CRLF & _
" Die URL kann auch mit https beginnen, Zertifikatsfehler werden ignoriert." & @CRLF & _
" Je nach Installation ist der URL Pfad" & @CRLF & _
" http://IP_oder_DNSNAME/zabbix/api_jsonrpc.php oder" & @CRLF & _
" http://IP_oder_DNSNAME/api_jsonrpc.php" & @CRLF & _
" Für den API-Benutzer reichen lesende Rechte! Der Host kann aber nur gefunden" & @CRLF & _
" werden wenn für diesen auch Rechte vorhanden sind" & @CRLF & _
"+------------------------------------------------------------------------------" & @CRLF & _
"| ZabbixPreventDuplicateHosts.exe ist FREEWARE!" & @CRLF & _
"| Kopieren, weitergeben ausdrücklich erlaubt!" & @CRLF & _
"| Die jeweils aktuelleste Version, Anleitung und Quellcode findet Ihr unter:" & @CRLF & _
"| https://znil.net/index.php?title=ZabbixPreventDuplicateHosts" & @CRLF & _
"+------------------------------------------------------------------------------" & " " & @CRLF
; Domäne aus der Registry auslesen. Ist das Feld leer so ist der Computer in keiner Domäne sondern in einer Arbeitsgruppe
Global $s_Domain = RegRead('HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters','Domain')
; Ob das Visible Name Feld mit durchsucht wird oder nicht
Global $b_AddVisibleName = False
Global $b_AddHostID = False
Global $b_AdditionalFunction = False
Global $s_OutputText = ""
Global $s_Computername = ""
Global $s_HostID = ""
Global $s_TemplateID = ""
; Die Variablen mit den Zugangsdaten zum Server:
Global $__zbxURL = ""
Global $__zbxUser = ""
Global $__zbxPassword = ""
; ###############################################################################################################################
; ###############################################################################################################################
; *************************************************************************************
; ######## ## ## ## ## ###### ######## #### ####### ## ## ######
; ## ## ## ### ## ## ## ## ## ## ## ### ## ## ##
; ## ## ## #### ## ## ## ## ## ## #### ## ##
; ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ######
; ## ## ## ## #### ## ## ## ## ## ## #### ##
; ## ## ## ## ### ## ## ## ## ## ## ## ### ## ##
; ## ####### ## ## ###### ## #### ####### ## ## ######
; *************************************************************************************
Func _COMErrFunc()
; Do nothing special, just check @error after suspect functions.
EndFunc ;==>_COMErrFunc
; # # # ##### ### ##### ####### ####### # #
; # # ## # # # # # # # # # ## ##
; # # # # # # # # # # # # # # #
; # # # # # ##### # ##### # # ##### # # #
; ####### # # # # # # # # # # #
; # # # ## # # # # # # # # #
; # # # # ##### ### ####### ####### ####### # #
;#######
; _ANSI2OEM löst das Problem mit dem Umlauten und anderen Sonderzeichen. Es wandelt Text so um das er korrekt in der DOS-Box dargestellt wird
; So können hier im Quellcode auch Umlaute verwendet werden (in den Textausgaben) und diese werden dann korrekt dargestellt
Func _ANSI2OEM($text)
$text = DllCall('user32.dll', 'Int', 'CharToOem', 'str', $text, 'str', '')
Return $text[2]
;Return $text
EndFunc ;==>_ANSI2OEM
; # # #
; # # # # ###### ###### # # # # #### #### ###### ##### ###### # #
; # # # # # # # # # # # # # # # # # ## #
; ####### # # ##### ##### # # # # #### # ##### ##### ##### # # #
; # # # # # # ####### # # # # ### # # # # # # #
; # # # # # # # # # # # # # # # # # # # ##
; # # # ###### # ###### # # #### #### #### ###### ##### ###### # #
;#######
; Hilfsroutine die den Hilfetext ausgibt
Func _HilfeAusgeben()
ConsoleWrite(_ANSI2OEM($s_Header))
ConsoleWrite(_ANSI2OEM($s_HilfeText))
EndFunc ;==>_HilfeAusgeben
; #############################################################################################################################################################
Func _zbx_Login( $__zbxURL, $__zbxUser, $__zbxPassword)
Local $__zbxJSON = '{"params":{"password":"' & $__zbxPassword & '","user":"' & $__zbxUser & '","userData":true},"jsonrpc":"2.0","method":"user.login","id":42}'
Local $__oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
Local $__zbxSessionId = ""
$__oHTTP.Open("POST", $__zbxURL , False)
; ignore all SSL errors
$__oHTTP.Option("WinHttpRequestOption_SslErrorIgnoreFlags") = 0x3300
;~ $__oHTTP.Option(4) = 13056 ; turns off ssl error messages and warnings
$__oHTTP.Option(4) = 0x3300
; Unknown certification authority (CA) or untrusted root 0x0100
; Wrong usage 0x0200
; Invalid common name (CN) 0x1000
; Invalid date or certificate expired 0x2000
$__oHTTP.SetRequestHeader("Content-Type", "application/json-rpc")
$__oHTTP.Send($__zbxJSON)
Local $__oReceived = $__oHTTP.ResponseText
Local $__oStatusCode = $__oHTTP.Status
;~ MsgBox(0, "_zbx_Login", StringReplace($__oReceived,",", "," & @CRLF) & @CRLF & @CRLF & "Status Code: " & $__oStatusCode)
If $__oStatusCode = 200 Then
Local $__atemp = StringSplit($__oReceived, ",:", 0)
For $i = 1 To $__atemp[0] Step 1
If StringInStr($__atemp[$i], "sessionid") > 0 Then
$__zbxSessionId = StringRegExpReplace($__atemp[$i + 1], '[^A-Za-z0-9_().+\%\-\s]+', "")
ExitLoop
EndIf
Next
EndIf
Return $__zbxSessionId
EndFunc
; #############################################################################################################################################################
Func _zbx_Logout( $__zbxURL, $__zbxSessionId)
Local $__zbxJSON = '{"jsonrpc": "2.0","method": "user.logout","params": [],"id": 42,"auth": "' & $__zbxSessionId & '"}'
Local $__oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
Local $__zbxResult = 0
$__oHTTP.Option(4) = 13056 ; turns off ssl error messages and warnings
$__oHTTP.Open("POST", $__zbxURL , False)
$__oHTTP.Option("WinHttpRequestOption_SslErrorIgnoreFlags") = 0x3300
$__oHTTP.Option(4) = 0x3300
$__oHTTP.SetRequestHeader("Content-Type", "application/json-rpc")
$__oHTTP.Send($__zbxJSON)
Local $__oReceived = $__oHTTP.ResponseText
Local $__oStatusCode = $__oHTTP.Status
;~ MsgBox(0, "_zbx_Logout", StringReplace($__oReceived,",", "," & @CRLF) & @CRLF & @CRLF & "Status Code: " & $__oStatusCode)
If $__oStatusCode = 200 Then
Local $__atemp = StringSplit($__oReceived, ",:", 0)
For $i = 1 To $__atemp[0] Step 1
If StringInStr($__atemp[$i], "result") > 0 Then
$__zbxResult = StringRegExpReplace($__atemp[$i + 1], '[^A-Za-z0-9_().+\%\-\s]+', "")
ExitLoop
EndIf
Next
EndIf
Return $__zbxResult
EndFunc
; #############################################################################################################################################################
Func _zbx_HostGetId($__zbxURL, $__zbxSessionId, $__zbxHostname)
Local $__zbxJSON = '{"params":{"filter":{"name":"' & $__zbxHostname & '"},"output":["hostid"]},"jsonrpc": "2.0","method": "host.get","auth": "' & $__zbxSessionId & '","id":42}'
Local $__oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
Local $__zbxHostId = ""
$__oHTTP.Open("POST", $__zbxURL , False)
$__oHTTP.Option("WinHttpRequestOption_SslErrorIgnoreFlags") = 0x3300
$__oHTTP.Option(4) = 0x3300
$__oHTTP.SetRequestHeader("Content-Type", "application/json-rpc")
$__oHTTP.Send($__zbxJSON)
Local $__oReceived = $__oHTTP.ResponseText
Local $__oStatusCode = $__oHTTP.Status
;~ MsgBox(0, "_zbx_HostGetId", StringReplace($__oReceived,",", "," & @CRLF) & @CRLF & @CRLF & "Status Code: " & $__oStatusCode)
If $__oStatusCode = 200 Then
Local $__atemp = StringSplit($__oReceived, ",:", 0)
For $i = 1 To $__atemp[0] Step 1
If StringInStr($__atemp[$i], "hostid") > 0 Then
$__zbxHostId = StringRegExpReplace($__atemp[$i + 1], '[^A-Za-z0-9_().+\%\-\s]+', "")
ExitLoop
EndIf
Next
EndIf
Return $__zbxHostId
EndFunc
; #############################################################################################################################################################
Func _zbx_HostSearchGetId($__zbxURL, $__zbxSessionId, $__zbxHostname)
;~ Local $__zbxJSON = '{"params":{"search":{"name":"' & $__zbxHostname & '"},"output":["hostid"]},"jsonrpc": "2.0","method": "host.get","auth": "' & $__zbxSessionId & '","id":42}'
Local $__zbxJSON = '{"params":{"search":{"name":"' & $__zbxHostname & '"},"output":["hostid","host","name"]},"jsonrpc": "2.0","method": "host.get","auth": "' & $__zbxSessionId & '","id":42}'
Local $__oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
Local $__tempHostId[1][3] ; [0][0] = Anzahl
; [x][0] = Host-ID
; [x][1] = Host name
; [x][2] = Visible name
Local $__zbxHostId[3] = [ "", "", ""] ; 0 = Host-ID, 1 = "Host name", 2 = "Visible name"
$__oHTTP.Open("POST", $__zbxURL , False)
$__oHTTP.Option("WinHttpRequestOption_SslErrorIgnoreFlags") = 0x3300
$__oHTTP.Option(4) = 0x3300
$__oHTTP.SetRequestHeader("Content-Type", "application/json-rpc")
$__oHTTP.Send($__zbxJSON)
Local $__oReceived = $__oHTTP.ResponseText
Local $__oStatusCode = $__oHTTP.Status
;~ MsgBox(0, "$__oReceived", $__oReceived & @CRLF & "Status Code: " & $__oStatusCode)
;~ MsgBox(0, "_zbx_HostGetId", StringReplace($__oReceived,",", "," & @CRLF) & @CRLF & @CRLF & "Status Code: " & $__oStatusCode)
If $__oStatusCode = 200 Then
Local $__atemp = StringSplit($__oReceived, ",:", 0)
_ArrayDisplay($__oReceived)
For $i = 1 To $__atemp[0] Step 1
If StringInStr($__atemp[$i], "hostid") > 0 Then
$__tempHostId[0][0] = $__tempHostId[0][0] + 1
ReDim $__tempHostId[ $__tempHostId[0][0] + 1 ][3]
$__tempHostId[ $__tempHostId[0][0] ][0] = StringRegExpReplace($__atemp[$i + 1], '[^A-Za-z0-9_().+\%\-\s]+', "")
EndIf
If StringInStr($__atemp[$i], "host") > 0 Then
$__tempHostId[ $__tempHostId[0][0] ][1] = StringRegExpReplace($__atemp[$i + 1], '[^A-Za-z0-9_().+\%\-\s]+', "")
EndIf
If StringInStr($__atemp[$i], "name") > 0 Then
$__tempHostId[ $__tempHostId[0][0] ][2] = StringRegExpReplace($__atemp[$i + 1], '[^A-Za-z0-9_().+\%\-\s]+', "")
EndIf
Next
EndIf
If $__tempHostId[0][0] > 0 Then
$__zbxHostId[0] = $__tempHostId[1][0]
$__zbxHostId[1] = $__tempHostId[1][1]
$__zbxHostId[2] = $__tempHostId[1][2]
Else
Return $__zbxHostId ; Ist hier ein Array!
EndIf
; Sortieren - Statt des ersten wollen wir den kürzesten Namen - und von diesen wird es der erste und damit älteste-
For $i = 1 To $__tempHostId[0][0] Step 1
If StringLen($__zbxHostId[1]) < StringLen($__zbxHostId[2]) Then
If StringLen($__zbxHostId[1]) > $__tempHostId[$i][1] Then
$__zbxHostId[0] = $__tempHostId[$i][0]
$__zbxHostId[1] = $__tempHostId[$i][1]
$__zbxHostId[2] = $__tempHostId[$i][2]
EndIf
Else
If StringLen($__zbxHostId[2]) > $__tempHostId[$i][2] Then
$__zbxHostId[0] = $__tempHostId[$i][0]
$__zbxHostId[1] = $__tempHostId[$i][1]
$__zbxHostId[2] = $__tempHostId[$i][2]
EndIf
EndIf
Next
Return $__zbxHostId ; Ist hier ein Array!
EndFunc
; #############################################################################################################################################################
Func _zbx_AddTemplateToHost($__zbxURL, $__zbxSessionId, $__zbxHostId, $__zbxTemplateId)
Local $__zbxJSON = '{"jsonrpc":"2.0","method":"template.massadd","params":{"templates":[{"templateid":"' & $__zbxTemplateId & '"}],"hosts":[{"hostid":"' & $__zbxHostId & '"}]},"auth": "' & $__zbxSessionId & '","id":42}'
Local $__oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
Local $__zbxResult = ""
$__oHTTP.Open("POST", $__zbxURL , False)
$__oHTTP.Option("WinHttpRequestOption_SslErrorIgnoreFlags") = 0x3300
$__oHTTP.Option(4) = 0x3300
$__oHTTP.SetRequestHeader("Content-Type", "application/json-rpc")
$__oHTTP.Send($__zbxJSON)
Local $__oReceived = $__oHTTP.ResponseText
Local $__oStatusCode = $__oHTTP.Status
;~ MsgBox(0, "_zbx_HostRemoveMaintenance", StringReplace($__oReceived,",", "," & @CRLF) & @CRLF & @CRLF & "Status Code: " & $__oStatusCode)
;~ ConsoleWrite("$__zbxJSON:" & @CRLF & $__zbxJSON & @CRLF)
;~ ConsoleWrite("$__oReceived:" & @CRLF & $__oReceived & @CRLF)
If $__oStatusCode = 200 Then
Local $__atemp = StringSplit($__oReceived, ",:", 0)
For $i = 1 To $__atemp[0] Step 1
If StringInStr($__atemp[$i], "templateids") > 0 Then
$__zbxResult = StringRegExpReplace($__atemp[$i + 1], '[^A-Za-z0-9_().+\%\-\s]+', "")
ExitLoop
EndIf
Next
EndIf
If $__zbxResult = "" Then
$__zbxResult = $__oReceived
EndIf
Return $__zbxResult
EndFunc
; ###############################################################################################################################
; ###############################################################################################################################
; ****************************************
; ## ## ### #### ## ##
; ### ### ## ## ## ### ##
; #### #### ## ## ## #### ##
; ## ### ## ## ## ## ## ## ##
; ## ## ######### ## ## ####
; ## ## ## ## ## ## ###
; ## ## ## ## #### ## ##
; ****************************************
; falls keine Parameter angegeben wurden die Hilfe ausgeben
If $CmdLine[0] = 0 And @Compiled = 1 Then
_HilfeAusgeben()
Exit 0
EndIf
;testen ob der Parameter 1 ist auf "/?" testen und ebenfalls Hilfe ausgeben
If @Compiled = 1 Then
If $CmdLine[1] = "/?" Then
_HilfeAusgeben()
Exit 0
EndIf
EndIf
; Die übergebenen Parameter auswerten und zuordnen
For $i = 1 To $CmdLine[0]
If $CmdLine[$i] = "/AddVisibleName" Then
; Auch das Feld "Visible Name" mit Durchsuchen
$b_AddVisibleName = True
ElseIf $CmdLine[$i] = "/AddHostID" Then
$b_AddHostID = True
ElseIf StringLeft($CmdLine[$i], StringLen("/AddTemplate=")) = "/AddTemplate=" Then
$s_TemplateID = StringTrimLeft($CmdLine[$i], StringLen("/AddTemplate="))
$b_AdditionalFunction = True
If $i < $CmdLine[0] Then
$s_HostID = $CmdLine[$i + 1]
ExitLoop
EndIf
Else
; Da es nur einen möglichen Parameter gibt muss es ansonsten der Computername sein den wir prüfen sollen
$s_Computername = $CmdLine[$i]
;~ ConsoleWrite("$s_Computername: " & $s_Computername & @CRLF)
ExitLoop
EndIf
Next
; Nur für Tests
If @Compiled = 0 Then
$b_AddVisibleName = True
$s_Computername = "9KL001DC"
EndIf
; Haben wir einen Computernamen den wir abfragen sollen?
If $s_Computername = "" And $b_AdditionalFunction = False Then
ConsoleWrite(_ANSI2OEM("FEHLER: Es wurde kein Computername / Hostname angegeben!" & @CRLF))
Exit 1
EndIf
; Haben wir eine HostID?
If $s_HostID = "" And $b_AdditionalFunction = True Then
ConsoleWrite(_ANSI2OEM("FEHLER: Es wurde keine Host-ID angegeben!" & @CRLF))
Exit 1
EndIf
; ###############################################################################################################################
; Zugangsdaten zum Zabbix-Server erhalten:
; Fall 1: Die Zugansdaten stehen in der ZabbixPreventDuplicateHosts.ini
; ConsoleWrite($s_IniFile & @CRLF)
If FileExists($s_IniFile) = 1 Then
$__zbxURL = IniRead($s_IniFile, "ZABBIXAPI", "URL", "")
$__zbxUser = IniRead($s_IniFile, "ZABBIXAPI", "User", "")
$__zbxPassword = IniRead($s_IniFile, "ZABBIXAPI", "Password", "")
EndIf
;Fall 2: Die Zugangsdaten stehen in den Umgebungsvariablen
If $__zbxURL = "" Then $__zbxURL = StringReplace(EnvGet("ZABBIXURL"), '"', '')
If $__zbxUser = "" Then $__zbxUser = StringReplace(EnvGet("ZABBIXUSER"), '"', '')
If $__zbxPassword = "" Then $__zbxPassword = StringReplace(EnvGet("ZABBIXPASSWORD"), '"', '')
; Fall 3: Die Zugangsdaten wurden per Registry gesetzt. Lesen mit 2 Versuchen wegen der 32/64Bit Geschichte (ja es gibt bessere Lösungen)
If $__zbxURL = "" Then
If $__zbxURL = "" Then $__zbxURL = RegRead("HKLM\SOFTWARE\Zabbix", "URL")
If $__zbxURL = "" Then $__zbxURL = RegRead("HKLM64\SOFTWARE\Zabbix", "URL")
If $__zbxUser = "" Then $__zbxUser = RegRead("HKLM\SOFTWARE\Zabbix", "User")
If $__zbxUser = "" Then $__zbxUser = RegRead("HKLM64\SOFTWARE\Zabbix", "User")
If $__zbxPassword = "" Then $__zbxPassword = RegRead("HKLM\SOFTWARE\Zabbix", "Password")
If $__zbxPassword = "" Then $__zbxPassword = RegRead("HKLM64\SOFTWARE\Zabbix", "Password")
EndIf
; Nun prüfen ob wir alles haben:
If $__zbxURL = "" Or StringLeft($__zbxURL, 4) <> "http" Then
ConsoleWrite(_ANSI2OEM("FEHLER: URL zum Zabbix-Server nicht gesetzt." & @CRLF))
Exit 1
EndIf
If $__zbxUser = "" Then
ConsoleWrite(_ANSI2OEM("FEHLER: Benutzer für Anmeldung am Zabbix-Server nicht gesetzt." & @CRLF))
Exit 1
EndIf
If $__zbxPassword = "" Then
ConsoleWrite(_ANSI2OEM("FEHLER: Passwort für Anmeldung am Zabbix-Server nicht gesetzt." & @CRLF))
Exit 1
EndIf
;~ MsgBox(0,"","$__zbxURL: " & $__zbxURL & @CRLF & "$__zbxUser: " & $__zbxUser & @CRLF & "$__zbxPassword: " & $__zbxPassword)
;~ ConsoleWrite("$__zbxURL: " & $__zbxURL & @CRLF & "$__zbxUser: " & $__zbxUser & @CRLF & "$__zbxPassword: " & $__zbxPassword & @CRLF)
; Soweit so gut - Melden wir uns am Zabbix-Serve an:
Global $__zbxSessionId = _zbx_Login( $__zbxURL, $__zbxUser, $__zbxPassword)
;~ ConsoleWrite("$__zbxSessionId: " & $__zbxSessionId & @CRLF)
If $__zbxSessionId = "" Then
; Leider hat die Anmeldung nicht geklappt
ConsoleWrite(_ANSI2OEM("FEHLER: Anmeldung am Zabbix-Server fehlgeschlagen. URL, Benutzername und Passwort prüfen!" & @CRLF))
Exit 1
EndIf
;~ $s_Computername = "9KL001dct"
If $b_AdditionalFunction = False Then
; Nun müssen wir den Host finden:
;~ Global $__zbxHostId = _zbx_HostGetId($__zbxURL, $__zbxSessionId, $s_Computername)
Global $__zbxHostData = _zbx_HostSearchGetId($__zbxURL, $__zbxSessionId, $s_Computername)
;~ ConsoleWrite("ID .........: " & $__zbxHostData[0] & @CRLF)
;~ ConsoleWrite("Host name...: " & $__zbxHostData[1] & @CRLF)
;~ ConsoleWrite("Visible name: " & $__zbxHostData[2] & @CRLF)
If $__zbxHostData[0] = "" Then
ConsoleWrite("ZBXHOSTNOTFOUND" & @CRLF)
Else
$s_OutputText = $__zbxHostData[1]
If $b_AddVisibleName = True Then
$s_OutputText = $s_OutputText & ";" & $__zbxHostData[2]
EndIf
If $b_AddHostID = True Then
$s_OutputText = $s_OutputText & ";" & $__zbxHostData[0]
EndIf
ConsoleWrite($s_OutputText & @CRLF)
EndIf
Else
Consolewrite(_ANSI2OEM("Füge Template " & $s_TemplateID & " zu Host " & $s_HostID & " hinzu ... " & @CRLF))
Local $s_Result = _zbx_AddTemplateToHost($__zbxURL, $__zbxSessionId, $s_HostID, $s_TemplateID)
If $s_Result = $s_TemplateID Then
ConsoleWrite(_ANSI2OEM("Template Erfolgreich hinzugefügt!"))
Else
ConsoleWrite(_ANSI2OEM("FEHLER beim Template hinzufügen: " & $s_Result & @CRLF))
EndIf
EndIf
; und wieder Abmelden:
If $__zbxSessionId <> "" Then
_zbx_Logout( $__zbxURL, $__zbxSessionId)
EndIf
Exit 0