source: community/nibbler/api_snmp.pl @ 197

Revision 197, 8.4 KB checked in by nelsonab, 22 months ago (diff)

Added another script from nibbler which uses the api to add snmp
switches. Script in Perl.

Line 
1#!/usr/bin/perl
2
3use JSON;
4use LWP::UserAgent;
5use strict;
6use warnings;
7
8my ($url, $user, $pass, $debug, $template_basename, $api_version, 
9        $hostname_only, $snmpgroup, $templategroup);
10my (%stats, %prog_api_version);
11
12#$url = "http://localhost/zabbix-1.8.1";
13#$url = "http://localhost/zabbix-1.8.2";
14#$url = "http://localhost/zabbix-10922"; 
15#$url = "http://localhost/zabbix-10994";
16$url=$ARGV[0];
17
18$user = "admin";
19$pass = "zabbix";
20$snmpgroup = "SNMP Devices";   
21$templategroup = "Templates";   # must exist   
22$hostname_only=1;
23$debug = 2; # 0 none, 1 some debug prints, 2 includes json strings (multiline)
24$template_basename = "Template_auto_";
25
26# supported API versions
27$prog_api_version{"1.1"}=1; # zabbix 1.8.1
28$prog_api_version{"1.2"}=1; # zabbix 1.8.2
29
30sub snmp { # adds nonexistant items for host arg1 to template-id arg2
31        my ($switch, $template_name) = @_;
32        my ($formula, $delay, $history, $trends, $priority, $community);
33        my (%oid, %delta, %description, %triggerDsc, %triggerXp);
34
35        $delay=180;
36        $history=365;
37        $trends=730;
38        $formula=1;
39        $priority=4;
40        $community="public";
41
42        $delta{'ifOperStatus'}="1";
43        $description{'ifOperStatus'}="Interface oper status on ";
44
45        $delta{'ifSpeed'}="1";
46        $description{'ifSpeed'}="Interface speed on ";
47
48        $oid{'snVLanByPortStpTopChanges'}="1.3.6.1.4.1.1991.1.1.3.2.1.1.20";
49        $delta{'snVLanByPortStpTopChanges'}="2";
50        $description{'snVLanByPortStpTopChanges'}="STP Topology Change on VLAN #";
51
52        $delta{'ifInErrors'}="1";
53        $description{'ifInErrors'}="Interface input errors on ";
54
55        $delta{'ifOutErrors'}="1";
56        $description{'ifOutErrors'}="Interface output errors on ";
57
58        $delta{'ifInOctets'}="1";
59        $description{'ifInOctets'}="Interface in octets on ";
60
61        $delta{'ifOutOctets'}="1";
62        $description{'ifOutOctets'}="Interface outoctets on ";
63
64        $oid{'ifCollision'}="1.3.6.1.2.1.16.1.1.1.13";
65        $delta{'ifCollision'}="2";
66        $description{'ifCollision'}="Interface collisions on ";
67
68        $triggerDsc{'ifOperStatus'}="ifOperStatus on {HOSTNAME} changed on if SUBME";
69        $triggerXp{'ifOperStatus'}="{{HOSTNAME}:ifOperStatus.SUBME.diff(0)}=1";
70
71        $triggerDsc{'ifSpeed'}="ifSpeed on {HOSTNAME} changed on if SUBME";
72        $triggerXp{'ifSpeed'}="{{HOSTNAME}:ifSpeed.SUBME.diff(0)}=1";
73
74        $triggerDsc{'ifInErrors'}="ifInErrors on {HOSTNAME} too high on if SUBME";
75        $triggerXp{'ifInErrors'}="{{HOSTNAME}:ifInErrors.SUBME.diff(0)}=1";
76
77        $triggerDsc{'ifOutErrors'}="ifOutErrors on {HOSTNAME} too high on if SUBME";
78        $triggerXp{'ifOutErrors'}="{{HOSTNAME}:ifOutErrors.SUBME.diff(0)}=1";
79
80        $triggerDsc{'snVLanByPortStpTopChanges'}="STP Topology Change occured on {HOSTNAME} on VLAN #SUBME";
81        $triggerXp{'snVLanByPortStpTopChanges'}="{{HOSTNAME}:snVLanByPortStpTopChanges.SUBME.last(0)}>0";
82
83        $triggerDsc{'ifCollision'}="Too many collisions occured on {HOSTNAME} on if SUBME";
84        $triggerXp{'ifCollision'}="{{HOSTNAME}:ifCollision.SUBME.last(0)}>10";
85
86# END OF USERCONFIG - DON'T TOUCH BELOW HERE!
87
88        # get configured item keys and trigger expressions, hash, optionally skip .oO
89        # or maybe just accept an json error on creation ....
90        $stats{Hosts}++;
91        my $template_id = gettemplateid($template_name);
92        my %keys;
93        my $items = apicall('Item.get', {hostids => $template_id, output => 'extend'});
94        for my $i (0..$#$items){
95                $keys{$items->[$i]->{key_}} = 1;
96        }
97        $stats{'Items preexisting'} += keys %keys;
98        print "   read ".(keys %keys)." items from database\n" if $debug;       
99        my ($key, $tree);
100        foreach $key (keys %description){
101                $tree=$key;
102                if($oid{$tree}) { $tree = $oid{$tree}; }
103                foreach(`/usr/bin/snmpwalk -v1 -cpublic -On $switch $tree`){
104                        /\.(.*\.)(\d+)/;
105                        my $oid=$1;
106                        my $if=$2;
107                        if ($keys{$key.".".$if}) {
108                                $stats{'Items skipped'}++;
109                                print "      skipping preexisting item ($stats{'Items skipped'})\n" if $debug;
110                                next;
111                        }
112                        print "      create item desc: $description{$key}port $if delta: $delta{$key} oid: $oid$if\n" if $debug;
113                        apicall('Item.create', {description => $description{$key}."port ".$if, 
114                                                key_ => $key.".".$if, 
115                                                hostid => $template_id, 
116                                                delay => $delay,
117                                                history => $history,
118                                                trends => $trends,
119                                                status => 0,            # default, active
120                                                type => 1,              # SNMPv1
121                                                snmp_community => $community,
122                                                snmp_oid => $oid.$if,
123                                                value_type => 3,        # numeric unsigend
124                                                data_type => 0,         # decimal, default
125                                                snmp_port => 161,
126                                                delta => 1              # 0=simple 1=delta/second 2=delta
127                                });                     
128                        $stats{'Items created'}++;
129                        if( !$triggerXp{$key} ){ next; }
130                        my $desc=$triggerDsc{$key};
131                        my $xp=$triggerXp{$key};
132                        $desc =~ s/SUBME/$if/g;
133                        $xp =~ s/SUBME/$if/g;
134                        $xp =~ s/\{HOSTNAME\}/$template_name/g;
135                        print "      create trigger descc: $desc xpression: $xp\n" if $debug;
136                        apicall('Trigger.create', { description => $desc,
137                                                        expression => $xp,
138                                                        type => 0,
139                                                        priority => $priority,
140                                                        status => 0,    # 0=enabled, default=disabled
141                                                        comments => '',
142                                                        url => '',
143                                                        templateid => 0 # mapped to template via item
144                                });
145                        $stats{'Triggers created'}++;
146                }
147        }
148}
149
150sub apicall {
151        my ($method , $params) = @_;
152        print "$method:\n" if $debug;
153        our ($mreq, $mres, $mua, $auth); 
154        if (!$mreq){
155                print "   setting up LWP... \n" if $debug;
156                $mua = LWP::UserAgent->new;
157                $mua->agent("swZBXAPI/0.1 ");
158                $mreq = HTTP::Request->new(POST => "$url/api_jsonrpc.php");
159                $mreq->content_type('application/json-rpc');
160        }
161        my $obj = {jsonrpc => '2.0',
162                        method => $method,
163                        params => $params,
164                        auth => $auth,
165                        id => $stats{'API calls'}++
166                  };
167        if (defined &to_json){          # there is different JSON.pm around....
168                $obj = to_json($obj);
169        } else {
170                $obj = objToJson($obj);
171        }
172        $mreq->content($obj);
173        print "    >".$mreq->content ."\n" if $debug > 1;
174        $mres = $mua->request($mreq);
175        if (!$mres->is_success) {print $mres->status_line, "\n";}
176        print "    <".$mres->content ."\n" if $debug > 1;
177        if (defined &from_json){        # there is different JSON.pm around....
178                $mres = from_json($mres->content);
179        } else {
180                $mres = jsonToObj($mres->content);
181        }
182        if($mres->{result}) {
183                print "   ".$mres->{result}."\n" if $debug;
184        } else {
185                die $mres->{error}->{message}." ".$mres->{error}->{data}." in $method\n";
186        }
187        if($method eq "user.authenticate") { $auth = $mres->{result} ;}
188        return $mres->{result} ;
189}
190
191sub gettemplateid { # returns id of the template, creates it if necessary
192        my ($template_name) = @_;
193        my $groupid_template = apicall('HostGroup.getObjects', { name => $templategroup})->[0]->{groupid};
194        my $template = apicall('Template.getObjects', { template => $template_name}) if ($api_version eq "1.1");
195        my $template = apicall('Template.getObjects', { host => $template_name}) if ($api_version eq "1.2"); 
196        my $templateid = 0;
197        if ($template =~ /HASH/){ # zabbix bug workaround (ZBX-2205)
198                for (keys %$template) { 
199                        $templateid = $template->{$_}->{templateid};
200                }
201        } else {   # should never be called, array is only returned if no template is found....
202                $templateid = $template->[0]->{templateid};
203        }
204        if (!$templateid) {  # create hostspecific template
205                $stats{'Templates created'}++;
206                my $res = apicall('Template.create', { host => $template_name,
207                                                groups => $groupid_template
208                                });
209                for (keys %$res) { # should be one and one only
210                        $templateid = $_ if ($api_version eq "1.1");
211                        $templateid = $res->{templateids}->[0] if ($api_version eq "1.2"); 
212                }
213        }
214        return $templateid;
215}
216
217
218apicall('user.authenticate',{password => $pass, user => $user}); 
219$api_version = apicall('APIInfo.version', { foo => 1}); 
220if (!$prog_api_version{$api_version}) { die "unsupported API version: $api_version\n"; }
221my $groupid = apicall('HostGroup.getObjects', { name => $snmpgroup})->[0]->{groupid};
222my $hostarray = apicall('Host.get', {groupids => $groupid, extendoutput => 1});
223for my $i (0..$#$hostarray){
224        print $hostarray->[$i]->{hostid}.",".$hostarray->[$i]->{dns}.",".$hostarray->[$i]->{ip}."\n" if $debug;
225        my $hostname = $hostarray->[$i]->{host};
226        if ( $hostname =~ /[a-zA-Z]/ && $hostname_only ) { $hostname =~ s/\..*//g;}
227        my $template_name = $template_basename.$hostname;
228        my $templateid = gettemplateid($template_name);
229        apicall('Template.linkTemplates', {templates => { templateid => $templateid }, hosts => { hostid => $hostarray->[$i]->{hostid}}}) if ($api_version eq "1.1");
230        apicall('Template.massAdd', {templates => $templateid, hosts => $hostarray->[$i]->{hostid}}) if ($api_version eq "1.2"); 
231        snmp ($hostarray->[$i]->{ip}, $template_name);
232}
233
234print "\n+---------------------+-------+\n";
235foreach (keys %stats){
236        printf "| %-20s|%6d |\n",$_,$stats{$_};
237}
238print "+---------------------+-------+\n";
Note: See TracBrowser for help on using the repository browser.