Aktionen

Zabbix Skripte Maintenance Host oder Gruppe

Aus znilwiki

ACHTUNG-BAUSTELLE.png

Dieses Thema ist noch nicht vollständig! Es wird noch daran gearbeitet!


Die beiden Skripte nutze ich als Alertscripts und als Externalscripts direkt auf dem Zabbix Server.
Das Skript für die Hosts ist nahezu 1:1 das von

https://www.zabbix.org/wiki/Perl_script_to_add/remove_Maintenance

Ich habe nur den Fehler bei der Abfrage beseitigt (es wurden immer alle Hosts zurückgegeben, nicht nur der gewünschte).
Außerdem ignoriert es bei https Fehler mit selbst-signierten Zertifikaten.
Das Skript für die Gruppen ist das gleiche Skript nur angepasst an die Gruppen.



Hosts

nano zabbix_main_host.pl
#!/usr/bin/perl

use strict;
use Getopt::Std;
use vars qw/ %opt /;

my $url = "http://localhost/api_jsonrpc.php"; # change <zabbix server> to your zabbix server
my $apiuser="username"; # API User's Username
my $apipassword="password"; # API User's password
my $maintenanceid;

#############
# Begin main
#
init();
my $hostname = $opt{s};
my $duration = $opt{d} || 10800;
my $maintname = $opt{n}; 


# Authenticate against Zabbix for API Maintenance addition
my $auth = newrequest($url, $apiuser, $apipassword);
my $hostid = gethostid($hostname);

if($opt{r}){
    print "Removing maintenance for host $hostname\n";
    getmaintid($hostid,$maintname);
    exit(0);
}else{
    print "Adding maintenance for host $hostname\n";
    addmaint($hostid,$duration,$maintname);
}
exit(0);

#########################
# Get command line input
#
sub init(){
    my $opt_string = 'hrs:d:n:';
    getopts( "$opt_string", \%opt ) or usage();
    usage() if $opt{h};
    usage() if !$opt{s};
    usage() if !$opt{n};
}
#####################
# Print script usage
#
sub usage(){
    print STDERR << "EOF";
usage: $0 [-hr] -s hostname [-d duration] -n name
 -h          : This (help) message   
 -r          : Remove maintenance for specified host 
 -s hostname : Hostname in Zabbix
 -d          : Duration of maintenance in seconds. Leave blank to use default.
                 300 =  5 minutes
                1800 = 30 minutes
                3600 =  1 hour
               10800 =  3 hour (default)
 -n name     : unique identifier

-s and -n are required
 
example: $0 -s hostname -d 3600 -n backup
example: $0 -s hostname -r -n backup
EOF
    exit;
}


#############################################
# Zabbix API requests require authentication
#
sub newrequest {
    my ($url, $user, $password) = @_;
 
    my $authenticate = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
        "params": {
            "password": "$password",
            "user": "$user"
        },
        "jsonrpc": "2.0",
        "method": "user.login",
        "id": 0
    }'  $url | grep result | head -n 1 | cut -d '"' -f 8);
    my $auth = `$authenticate`;
    chomp($auth);
    return $auth

}

###################################################
# Subroutine to query Zabbix to get host id
#
sub gethostid{
    my $hostname = shift;
    my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
    "params": {
        "filter": {
            "name": "$hostname"
        }
    },
    "jsonrpc": "2.0",
    "method": "host.get",
    "auth": "$auth",
    "id": 2 }' $url);
    my $res = `$process`;
    chomp($res);

    # print "$res \n\n";
    my @output = split(/,/,$res);
    my $x=0;
    foreach(@output){
    if (($output[$x] =~ m/\"host\"/)&&($output[$x] =~ m/$hostname/)){
            $output[$x-2] =~ s/\[\{//g;
            $output[$x-2] =~ s/"//g;
            $output[$x-2] =~ s/hostid://g;
            $output[$x-2] =~ s/result://g;
            $output[$x-2] =~ s/\{//g;
            $hostid = $output[$x-2];
        }
        $x++;
    }
    if(!$hostid){
       print "WARNING - $hostname not found in maintenance for Zabbix.\n";
       exit(1);
    }
    print "Host ID: ".$hostid."\n";
    return $hostid
}


###################################################
# Subroutine to query Zabbix to get maintenance id
#
sub getmaintid{
    my $hostid = shift;
    my $maintname = shift;
    my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
    "params": {
        "output": "extend",
        "selectHosts": "refer",
        "selectGroups": "refer",
        "hostids": "$hostid"
    },
    "jsonrpc": "2.0",
    "method": "maintenance.get",
    "auth": "$auth",
    "id": 2 }' $url);
 
    my $res = `$process`;
    chomp($res);
 
    my @output = split(/,/,$res);
    my $x=0;
    foreach(@output){
        if (($output[$x] =~ m/\"name\"/)&&($output[$x] =~ m/ID $maintname/)){
            $output[$x-1] =~ s/\[\{//g;
            $output[$x-1] =~ s/"//g;
            $output[$x-1] =~ s/maintenanceid://g;
            $output[$x-1] =~ s/result://g;
            $output[$x-1] =~ s/\{//g;
            $maintenanceid = $output[$x-1];
            remmaint($maintenanceid);
        }
        $x++;
    }
    if(!$maintenanceid){
       print "WARNING - $hostname not found in maintenance for Zabbix.\n";
       exit(1);
    }
}
 
 
#################################################
# Subroutine to add maintenance window to Zabbix
#
sub addmaint{
    $hostid = shift;
    $duration = shift;
    $maintname = shift;
    my $start = time();
    my $end = ($start + $duration);
    # my $auth = newrequest($url, $apiuser, $apipassword);
   my $process = 'curl -k -s -i -X POST -H \'Content-Type: application/json-rpc\' -d "{
    \"jsonrpc\":\"2.0\",
    \"method\":\"maintenance.create\",
    \"params\":[{
        \"groupids\":[],
        \"hostids\":[\"'.$hostid.'\"],
        \"name\":\"000_Manually Maintenance Mode with ID '.$maintname.' - '.$start.'\",
        \"maintenance_type\":\"0\",
        \"description\":\"000_Manually Maintenance Mode for '.$hostname.' set by Linux-Admin\",
        \"active_since\":\"'.$start.'\",
        \"active_till\":\"'.$end.'\",
        \"timeperiods\": [{
            \"timeperiod_type\": 0,
            \"start_date\": \"'.$start.'\",
            \"period\": '.$duration.'}]
        }],
    \"auth\":\"'.$auth.'\",
    \"id\":3}" '.$url; 
    my $res = `$process`;
    chomp($res);
 
    my @output = split(/,/,$res);
 
    foreach(@output){
    if ($_ =~ m/\"error/){
            print "$_\n";
        exit(1);
        }
        print "$_\n" if ($_ =~ m/\"result/);
    }
 
}
#################################################
# Subroutine to remove maintenance window from Zabbix
#
sub remmaint{
    $maintenanceid = shift;
    my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
    "jsonrpc":"2.0",
    "method":"maintenance.delete",
    "params":["$maintenanceid"],
    "auth":"$auth",
    "id":2}' $url);
 
    my $res = `$process`;
    chomp($res);
 
    my @output = split(/,/,$res);
 
    foreach(@output){
        print "$_\n" if ($_ =~ m/\"error/);
        print "$_\n" if ($_ =~ m/\"result/);
    }
}




Einbindung in Zabbix Oberfläche

Unter

Administration => Scripts

habe ich folgende Skripte angelegt:

ClipCapIt-200220-154612.PNG

Im Detail:

ClipCapIt-200220-154656.PNG

Dadurch habe ich an jedem Host folgendes Menu (z.B. in der Problems-Ansicht):

ClipCapIt-200220-154902.PNG

So kann ich - falls ich mal wieder Updates einspiele und vergessen habe den Host in den Maintenance-Modus zu setzen - diese eben schnell nachholen.

Man kann das Skript auch natürlich auch aus anderen Programmen aufrufen - z.B. um aus dem Ticketsystem bei genehmigten Change die zugehörigen Systeme automatisch für den geplanten Zeitraum in den Wartungsmodus zu versetzen.


Groups

Dies ist das von mir abgeänderte Skript was mit Hostgroups funktioniert:

nano zabbix_main_group.pl
#!/usr/bin/perl
 
use strict;
use Getopt::Std;
use vars qw/ %opt /;
 
my $url = "http://localhost/api_jsonrpc.php"; # change <zabbix server> to your zabbix server
my $apiuser="username"; # API User's Username
my $apipassword="password"; # API User's password
my $maintenanceid;
 
#############
# Begin main
#
init();
my $groupname = $opt{s};
my $duration = $opt{d} || 10800;
my $maintname = $opt{n}; 


# Authenticate against Zabbix for API Maintenance addition
my $auth = newrequest($url, $apiuser, $apipassword);
my $groupid = getgroupid($groupname);

if($opt{r}){
    print "Removing maintenance for group $groupname\n";
    getmaintid($groupid,$maintname);
    exit(0);
}else{
    print "Adding maintenance for group $groupname\n";
    addmaint($groupid,$duration,$maintname);
}
exit(0);
 
#########################
# Get command line input
#
sub init(){
    my $opt_string = 'hrs:d:n:';
    getopts( "$opt_string", \%opt ) or usage();
    usage() if $opt{h};
    usage() if !$opt{s};
    usage() if !$opt{n};
}
#####################
# Print script usage
#
sub usage(){
    print STDERR << "EOF";
usage: $0 [-hr] -s groupname [-d duration] -n name
 -h           : This (help) message   
 -r           : Remove maintenance for specified host 
 -s groupname : Hostgroupname in Zabbix
 -d           : Duration of maintenance in seconds. Leave blank to use default.
                  300 =  5 minutes
                 1800 = 30 minutes
                 3600 =  1 hour
                10800 =  3 hour (default)
 -n name      : unique identifier

-s and -n are required
 
example: $0 -s groupname -d 3600 -n backup
example: $0 -s groupname -r -n backup
EOF
    exit;
}


#############################################
# Zabbix API requests require authentication
#
sub newrequest {
    my ($url, $user, $password) = @_;
 
    my $authenticate = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
      "params": {
          "password": "$password",
          "user": "$user"
      },
      "jsonrpc": "2.0",
      "method": "user.login",
      "id": 0
    }'  $url | grep result | head -n 1 | cut -d '"' -f 8);
    my $auth = `$authenticate`;
    chomp($auth);
    return $auth
 
}

###################################################
# Subroutine to query Zabbix to get host id
#
sub getgroupid{
    my $groupname = shift;
    my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
    "params": {
        "filter": {
            "name": "$groupname"
        }
    },
    "jsonrpc": "2.0",
    "method": "hostgroup.get",
    "auth": "$auth",
    "id": 2 }' $url);
    my $res = `$process`;
    chomp($res);

    # print "$res \n\n";
    my @output = split(/,/,$res);
    my $x=0;
    foreach(@output){
        if (($output[$x] =~ m/\"name\"/)&&($output[$x] =~ m/$groupname/)){
            $output[$x-1] =~ s/\[\{//g;
            $output[$x-1] =~ s/"//g;
            $output[$x-1] =~ s/groupid://g;
            $output[$x-1] =~ s/result://g;
            $output[$x-1] =~ s/\{//g;
            $groupid = $output[$x-1];
        }
        $x++;
    }
    if(!$groupid){
       print "WARNING - $groupname not found in maintenance for Zabbix.\n";
       exit(1);
    }
    print "Group ID: ".$groupid."\n";
    return $groupid
}


###################################################
# Subroutine to query Zabbix to get maintenance id
#
sub getmaintid{
    my $groupid = shift;
    my $maintname = shift;
    my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
    "params": {
        "output": "extend",
        "selectHosts": "refer",
        "selectGroups": "refer",
        "groupids": "$groupid"
    },
    "jsonrpc": "2.0",
    "method": "maintenance.get",
    "auth": "$auth",
    "id": 2 }' $url);
 
    my $res = `$process`;
    chomp($res);
 
    my @output = split(/,/,$res);
    my $x=0;
    foreach(@output){
        if (($output[$x] =~ m/\"name\"/)&&($output[$x] =~ m/ID $maintname/)){
            $output[$x-1] =~ s/\[\{//g;
            $output[$x-1] =~ s/"//g;
            $output[$x-1] =~ s/maintenanceid://g;
            $output[$x-1] =~ s/result://g;
            $output[$x-1] =~ s/\{//g;
            $maintenanceid = $output[$x-1];
            remmaint($maintenanceid);
        }
        $x++;
    }
    if(!$maintenanceid){
       print "WARNING - $groupname not found in maintenance for Zabbix.\n";
       exit(1);
    }
}
 
 
#################################################
# Subroutine to add maintenance window to Zabbix
#
sub addmaint{
    $groupid = shift;
    $duration = shift;
    $maintname = shift;
    my $start = time();
    my $end = ($start + $duration);
    # my $auth = newrequest($url, $apiuser, $apipassword);
   my $process = 'curl -k -s -i -X POST -H \'Content-Type: application/json-rpc\' -d "{
    \"jsonrpc\":\"2.0\",
    \"method\":\"maintenance.create\",
    \"params\":[{
        \"groupids\":[\"'.$groupid.'\"],
        \"hostids\":[],
        \"name\":\"000_Trigger Maintenance Mode with ID '.$maintname.' - '.$start.'\",
        \"maintenance_type\":\"0\",
        \"description\":\"000_Trigger Maintenance Mode for '.$groupname.' set by Action\",
        \"active_since\":\"'.$start.'\",
        \"active_till\":\"'.$end.'\",
        \"timeperiods\": [{
            \"timeperiod_type\": 0,
            \"start_date\": \"'.$start.'\",
            \"period\": '.$duration.'}]
        }],
    \"auth\":\"'.$auth.'\",
    \"id\":3}" '.$url; 
    my $res = `$process`;
    chomp($res);
 
    my @output = split(/,/,$res);
 
    foreach(@output){
    if ($_ =~ m/\"error/){
            print "$_\n";
        exit(1);
        }
        print "$_\n" if ($_ =~ m/\"result/);
    }
 
}
#################################################
# Subroutine to remove maintenance window from Zabbix
#
sub remmaint{
    $maintenanceid = shift;
    my $process = qq(curl -k -s -i -X POST -H 'Content-Type: application/json-rpc' -d '{
    "jsonrpc":"2.0",
    "method":"maintenance.delete",
    "params":["$maintenanceid"],
    "auth":"$auth",
    "id":2}' $url);
 
    my $res = `$process`;
    chomp($res);
 
    my @output = split(/,/,$res);
 
    foreach(@output){
        print "$_\n" if ($_ =~ m/\"error/);
        print "$_\n" if ($_ =~ m/\"result/);
    }
}




Nutzung in Actions

Das Gruppenskript nutze ich Actions um einen ganzen Standort in Wartung zu versetzen:

ClipCapIt-200220-155817.PNG

Im Detail ist das hier beschrieben:

https://znil.net/index.php?title=Zabbix_Standorte_Hostgruppen_bei_Nichterreichbarkeit_automatisch_in_den_Wartungsmodus_setzen_oder_daraus_entfernen



Mit oder ohne Datensammlung

In beiden Skripten gibt es eine Zeile

\"maintenance_type\":\"0\",

Die 0 bedeudet "With data collection". Wollt Ihr das ohne Datensammlung "Without data collection" so ändert die 0 auf eine 1:

\"maintenance_type\":\"1\",




Kommentare

Loading comments...