zabbix-agent-addons/zabbix_scripts/disco_unifi

142 lines
4.0 KiB
Perl
Executable File

#!/usr/bin/perl -w
use strict;
use warnings;
use JSON;
use Getopt::Long;
use LWP::UserAgent;
use HTTP::Cookies;
use URI;
use Data::Dumper;
umask 077;
my $user = 'zabbix';
my $pass = 'secret';
my $site = 'default';
my $url = 'https://localhost:8443';
my $certcheck = 1;
my $what = 'devices';
my $type = 'all';
my $pretty = 0;
my $json = {};
@{$json->{data}} = ();
GetOptions (
'user=s' => \$user,
'password|p=s' => \$pass,
'site=s' => \$site,
'url=s' => \$url,
'cert-check!' => \$certcheck,
'what=s' => \$what,
'type:s' => \$type,
'pretty' => \$pretty
);
# An empty type is the same as all
$type = 'all' if ($type eq '');
# If connecting to localhost, no need to check certificate
my $uri = URI->new($url);
if ($uri->host =~ m/^localhost|127\.0\.0/){
$certcheck = 0;
}
my $site_id;
my $resp;
my $username = $ENV{LOGNAME} || $ENV{USER} || getpwuid($<);
my $cj = HTTP::Cookies->new(
file => "/tmp/.unifi_$username.txt",
autosave => 1,
ignore_discard => 1
);
my $sslopts = {};
if (not $certcheck){
$sslopts = { verify_hostname => 0, SSL_verify_mode => 0 }
}
my $ua = LWP::UserAgent->new(
ssl_opts => $sslopts,
cookie_jar => $cj
);
# Check if we need to login
$resp = $ua->get($url . '/api/self/sites');
if ($resp->is_error){
# Login on the API
$resp = $ua->post(
$url . '/api/login',
Content => to_json({ username => $user, password => $pass }),
Content_Type => 'application/json;charset=UTF-8'
);
die "Login failed: " . $resp->message . "\n" if $resp->is_error;
$resp = $ua->get($url . '/api/self/sites');
die $resp->message . "\n" if $resp->is_error;
}
foreach (@{from_json($resp->decoded_content)->{data}}){
if ($_->{name} eq $site || $_->{desc} eq $site){
$site_id = $_->{_id};
# If site is referenced by description, translate it to name
$site = $_->{name} if ($_->{name} ne $site);
last;
}
}
die "Site $site not found\n" unless ($site_id);
if ($what eq 'devices'){
$resp = $ua->get($url . '/api/s/' . $site . '/stat/device');
die $resp->message . "\n" if $resp->is_error;
foreach my $entry (@{from_json($resp->decoded_content)->{data}}){
next if ($type ne 'all' && $entry->{type} ne $type);
push @{$json->{data}}, {
'{#UNIFI_DEV_ID}' => $entry->{device_id},
'{#UNIFI_DEV_ADOPTED}' => $entry->{adopted},
'{#UNIFI_DEV_MODEL}' => $entry->{model},
'{#UNIFI_DEV_NAME}' => $entry->{name} || $entry->{mac},
'{#UNIFI_DEV_MAC}' => $entry->{mac},
'{#UNIFI_DEV_TYPE}' => $entry->{type}
};
}
} elsif ($what eq 'stations'){
$resp = $ua->get($url . '/api/s/' . $site . '/stat/sta');
die $resp->message . "\n" if $resp->is_error;
foreach my $entry (@{from_json($resp->decoded_content)->{data}}){
# Ignore other sites
next if ($entry->{site_id} ne $site_id);
next if ($type eq 'wireless' and $entry->{is_wired} == JSON::true);
next if ($type eq 'wired' and $entry->{is_wired} == JSON::false);
push @{$json->{data}}, {
'{#UNIFI_STA_ID}' => $entry->{_id},
'{#UNIFI_STA_NAME}' => (defined $entry->{hostname}) ? $entry->{hostname} : $entry->{mac},
'{#UNIFI_STA_MAC}' => $entry->{mac}
};
}
} elsif ($what eq 'networks'){
$resp = $ua->get($url . '/api/s/' . $site . '/rest/networkconf');
die $resp->message . "\n" if $resp->is_error;
foreach my $entry (@{from_json($resp->decoded_content)->{data}}){
# Ignore other sites
next if ($entry->{site_id} ne $site_id);
next if ($type ne 'all' and $entry->{purpose} ne $type);
push @{$json->{data}}, {
'{#UNIFI_NET_ID}' => $entry->{_id},
'{#UNIFI_NET_NAME}' => $entry->{name}
};
}
} elsif ($what eq 'wlan') {
$resp = $ua->get($url . '/api/s/' . $site . '/rest/wlanconf');
die $resp->message . "\n" if $resp->is_error;
foreach my $entry (@{from_json($resp->decoded_content)->{data}}){
push @{$json->{data}}, {
'{#UNIFI_WLAN_ID}' => $entry->{_id},
'{#UNIFI_WLAN_NAME}' => $entry->{name}
};
}
}
print to_json($json, { pretty => $pretty });