Ad Widget

Collapse

IT Services via Zabbix API (Perl)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Crypty
    Member
    • Jul 2012
    • 80

    #1

    IT Services via Zabbix API (Perl)

    Hi guys,

    I have configured testing IT services so I can prepare sth. for a real environment...

    I'm trying to obtain IT services via API (currently, via Perl script). It "works", but in the GUI, there is a "TREE" structure such as:

    Code:
    Network
    - Routers
             - Router-A
             - Router-B
    - Switches
             - Switch-1
             - Switch-2
    Now, I can read all relevant/configured SLAs, but I do not know how to read them following this tree structure, because I get the output where I do not know what is dependent on what...

    If I run API for services.get, there is "dependencies" field, but it's gonna be horrible to somehow generate this tree topology somehow in Perl and so on...

    Isn't here anything to make it simple? So that I can read it one by one following this tree structure?

    My script is as follows for now;

    Code:
    #!/usr/bin/perl
    
    use 5.010;
    use strict;
    use warnings;
    use JSON::RPC::Legacy::Client;
    use Data::Dumper;
    
    # Authenticate yourself
    my $client = new JSON::RPC::Legacy::Client;
    my $url = 'http://X.Y.Z.W/zabbix/api_jsonrpc.php';
    my $authID;
    my $response;
    
    my $json = {
    jsonrpc => "2.0",
    method => "user.login",
    params => {
    user => "Admin",
    password => "PASSWORD"
    },
    id => 1
    };
    
    $response = $client->call($url, $json);
    
    # Check if response was successful
    die "Authentication failed\n" unless $response->content->{'result'};
    
    $authID = $response->content->{'result'};
    print "Authentication successful. Auth ID: " . $authID . "\n\n";
    
    
    $json = {
    jsonrpc => '2.0',
    method => 'service.get',
    params => {
        output => 'extend',
        selectDependencies => 'extend',
        sortfield => 'name',
    },
    id => 2,
    auth => "$authID",
    };
    
    $response = $client->call($url, $json);
    
    # Check if response was successful
    die "service.get failed\n" unless $response->content->{'result'};
    
    print Dumper($response);
    
    my $slaID=1;
    my $json2;
    my $response2;
    
    print "List of IT Services (current 30 days SLA)\n--------------------------------------------------------------------------\n";
    foreach my $service (@{$response->content->{result}}) {
    
        $slaID = $service->{serviceid};
    
        $json2 = {
        jsonrpc => '2.0',
        method => 'service.getsla',
        params => {
                serviceids => $slaID,
                intervals => {
                        from => time()-2592000,
                        to => time(),
                },
        },
        id => 2,
        auth => "$authID",
        };
    
        $response2 = $client->call($url, $json2);
    
        # Check if response was successful
        die "service.getsla failed\n" unless $response2->content->{'result'};
    
    
        foreach my $slaLevel (@{$response2->content->{result}->{$slaID}->{sla}}) {
            print "IT service ID: ".$service->{serviceid}."\tName: ".$service->{name}."\t\tSLA: ".$slaLevel->{sla}."\n";
        }
    }
    
    # Logout
    $json = {
    jsonrpc => '2.0',
    method => 'user.logout',
    params => [],
    id => 3,
    auth => "$authID",
    };
    
    $response = $client->call($url, $json);
    # Check if response was successful
    die "user.logout failed\n" unless $response->content->{'result'};
    print "\nLogout successful\n"
    Btw using Zabbix 3.0.15... CentOS7, MySQL, ...
  • Crypty
    Member
    • Jul 2012
    • 80

    #2
    Here is my current script for 3 levels of IT services... I hope it helps others
    - there is a lot to improve!
    - the script creates just partial output of HTML page... from which I create PDF afterwards... See the Shell code afterwards...

    Code:
    #!/usr/bin/perl
    
    use 5.010;
    use strict;
    use warnings;
    use JSON::RPC::Legacy::Client;
    use Data::Dumper;
    
    sub JsonGetServiceSLA {
        my ($id, $auth, $from, $to) = @_;
        my $subJson = {
        jsonrpc => '2.0',
        method => 'service.getsla',
        params => {
                serviceids => $id,
                intervals => {
                        from => $from,
                        to => $to,
                },
        },
        id => 2,
        auth => "$auth",
        };
        return $subJson;
    }
    
    # last month
    my $from = `date -d \"\`date +%Y%m01\` -1 month\" +\"%s\"`;
    my $to = `date -d \"\`date +%Y%m01\` -1 second\" +\"%s\"`;
    
    my $month = `date -d \"\`date +%Y%m01\` -1 month\" +\"%B\"`;
    my $year = `date -d \"\`date +%Y%m01\` -1 month\" +\"%Y\"`;
    
    print "<div><h1>$month $year</h1></div>\n";
    print "<div>\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"6\">\n  <tr>\n";
    
    # Authenticate yourself
    my $client = new JSON::RPC::Legacy::Client;
    my $url = 'http://<IP_address>/zabbix/api_jsonrpc.php';
    my $authID;
    my $response;
    
    my $json = {
    jsonrpc => "2.0",
    method => "user.login",
    params => {
        user => "Admin",
        password => "password"
    },
    id => 1
    };
    
    $response = $client->call($url, $json);
    
    # Check if response was successful
    die "Authentication failed\n" unless $response->content->{'result'};
    
    $authID = $response->content->{'result'};
    # print "Authentication successful. Auth ID: " . $authID . "\n\n";
    
    $json = {
    jsonrpc => '2.0',
    method => 'service.get',
    params => {
        output => 'extend',
        selectDependencies => 'extend',
        selectParentDependencies => 'extend',
        sortfield => 'name',
    },
    id => 1,
    auth => "$authID",
    };
    
    $response = $client->call($url, $json);
    
    # Check if response was successful
    die "service.get failed\n" unless $response->content->{'result'};
    
    # print Dumper($response);
    
    my $json2;
    my $response2;
    my @roots;
    my @nodes;
    my @rootsNames;
    my @nodesNames;
    my @parents;
    my @slas;
    my $sla;
    my $name;
    my $slaPrint;
    my $json3;
    my $response3;
    my $json4;
    my $response4;
    my $json5;
    my $response5;
    
    my @alreadyTested;
    my @rootsGoodSLAs;
    my @nodesGoodSLAs;
    my $goodSLA;
    
    # create TREE topology
    foreach my $service (@{$response->content->{result}}) {
        if (@{$service->{parentDependencies}}) {
            # print "IT service Name: ".$service->{name}." is a NODE.\n";
            push @nodes, $service->{serviceid};
            push @nodesNames, $service->{name};
            push @nodesGoodSLAs, $service->{goodsla};
            foreach my $parent (@{$service->{parentDependencies}}) {
                push @parents, $parent->{serviceupid};
            }
        } elsif (@{$service->{dependencies}}) {
            # print "IT service Name: ".$service->{name}." is a ROOT.\n";
            push @roots, $service->{serviceid};
            push @rootsNames, $service->{name};
            push @rootsGoodSLAs, $service->{goodsla};
        }
    }
    
    # SLA for the ROOT level
    foreach my $root (@roots) {
        $json2 = JsonGetServiceSLA($root, $authID, $from, $to);
        $response2 = $client->call($url, $json2);
    
        # Check if response was successful
        die "service.getsla failed\n" unless $response2->content->{'result'};
    
        @slas = @{$response2->content->{result}->{$root}->{sla}};
    
        foreach my $sla (@slas) {
            $name = shift @rootsNames;
            $goodSLA = shift @rootsGoodSLAs;
            $slaPrint = sprintf "%.2f", $sla->{sla};
    
            if ($slaPrint < $goodSLA) {
                print "    <th>$name</th>\n    <th></th>\n    <th></th>\n    <th></th>\n    <th><font color=\"#BA0005\">$slaPrint \% </font></th>\n  </tr>\n";
            } else {
                print "    <th>$name</th>\n    <th></th>\n    <th></th>\n    <th></th>\n    <th><font color=\"#228B22\">$slaPrint \% </font></th>\n  </tr>\n";
            }
        }
    
        # SLA for nodes which depend on this root
        for my $i (0 .. $#nodes) {
    
            # if currently tested nodes has already been tested, skip
            if ($nodes[$i] ~~ @alreadyTested) {
                next;
            }
    
            if ($parents[$i] == $root) {
                $json3 = JsonGetServiceSLA($nodes[$i], $authID, $from, $to);
                $response3 = $client->call($url, $json3);
    
                # Check if response was successful
                die "service.getsla failed\n" unless $response3->content->{'result'};
    
                @slas = @{$response3->content->{result}->{$nodes[$i]}->{sla}};
    
                foreach my $sla (@slas) {
                    $slaPrint = sprintf "%.2f", $sla->{sla};
                    if ($slaPrint < $nodesGoodSLAs[$i]) {
                        print "  <tr>\n    <th></th>\n    <th>$nodesNames[$i]</th>\n    <th></th>\n    <th></th>\n    <th><font color=\"#BA0005\">$slaPrint \%</font></th>\n  </tr>\n";
                    } else {
                        print "  <tr>\n    <th></th>\n    <th>$nodesNames[$i]</th>\n    <th></th>\n    <th></th>\n    <th><font color=\"#228B22\">$slaPrint \%</font></th>\n  </tr>\n";
                    }
                }
    
                # add the node to alreadyTested ones so it's not tested more than once
                @alreadyTested = (@alreadyTested, $nodes[$i]);
    
                for my $j (0 .. $#nodes) {
    
                    # if currently tested nodes has already been tested, skip
                    if ($nodes[$j] ~~ @alreadyTested) {
                        next;
                            }        
    
                    if ($parents[$j] == $nodes[$i]) {
                        $json4 = JsonGetServiceSLA($nodes[$j], $authID, $from, $to);
                        $response4 = $client->call($url, $json4);
    
                        # Check if response was successful
                        die "service.getsla failed\n" unless $response4->content->{'result'};
    
                        @slas = @{$response4->content->{result}->{$nodes[$j]}->{sla}};
    
                        foreach my $sla (@slas) {
                            $slaPrint = sprintf "%.2f", $sla->{sla};
                                            if ($slaPrint < $nodesGoodSLAs[$j]) {    
                                print "  <tr>\n    <th></th>\n    <th></th>\n    <th>$nodesNames[$j]</th>\n    <th></th>\n    <th><font color=\"#BA0005\">$slaPrint \%</font></th>\n  </tr>\n";
                            } else {
                                print "  <tr>\n    <th></th>\n    <th></th>\n    <th>$nodesNames[$j]</th>\n    <th></th>\n    <th><font color=\"#228B22\">$slaPrint \%</font></th>\n  </tr>\n";
                            }
                        }
    
                        # add the node to alreadyTested ones so it's not tested more than once
                        @alreadyTested = (@alreadyTested, $nodes[$j]);
    
                        for my $k (0 .. $#nodes) {
    
                            # if currently tested nodes has already been tested, skip
                            if ($nodes[$k] ~~ @alreadyTested) {
                                next;
                                    }        
    
                            if ($parents[$k] == $nodes[$j]) {    
                                $json5 = JsonGetServiceSLA($nodes[$k], $authID, $from, $to);
                                $response5 = $client->call($url, $json5);
    
                                # Check if response was successful
                                die "service.getsla failed\n" unless $response5->content->{'result'};
    
                                @slas = @{$response5->content->{result}->{$nodes[$k]}->{sla}};
    
                                foreach my $sla (@slas) {
                                    $slaPrint = sprintf "%.2f", $sla->{sla};
                                                            if ($slaPrint < $nodesGoodSLAs[$k]) {
                                        print "  <tr>\n    <th></th>\n    <th></th>\n    <th></th>\n    <th>$nodesNames[$k]</th>\n    <th><font color=\"#BA0005\">$slaPrint \%</font></th>\n  </tr>\n";
                                    } else {
                                        print "  <tr>\n    <th></th>\n    <th></th>\n    <th></th>\n    <th>$nodesNames[$k]</th>\n    <th><font color=\"#228B22\">$slaPrint \%</font></th>\n  </tr>\n";
                                    }
                                }
    
                                # add the node to alreadyTested ones so it's not tested more than once
                                @alreadyTested = (@alreadyTested, $nodes[$k]);
                            }
                        }
                    }
                }
            }
        }
    }
    
    # Logout
    $json = {
    jsonrpc => '2.0',
    method => 'user.logout',
    params => [],
    id => 3,
    auth => "$authID",
    };
    
    $response = $client->call($url, $json);
    # Check if response was successful
    die "user.logout failed\n" unless $response->content->{'result'};
    # print "\nLogout successful\n"
    And shell code:
    - finish HTML page, create PDF, send email ...
    - can be run automatically via crontab

    Code:
    #!/bin/bash
    
    DIR="/home/zabbix-report/api"
    FILE="$DIR/report.html"
    
    rm $FILE 2> /dev/null
    touch $FILE
    
    cat $DIR/top.txt >> $FILE
    `$DIR/services_sla_tree.pl >> $FILE`
    cat $DIR/bottom.txt >> $FILE
    
    wkhtmltopdf --header-html $DIR/header.html --footer-html $DIR/footer.html $FILE $DIR/report.pdf
    
    echo "Monthly SLA report attached" | mutt -s "SLA report" -a "$DIR/report.pdf" -- [email protected]
    
    exit 0;

    Comment

    Working...