From 29fe3a445dbbeca0889575cdddc6f3f8fd750ff1 Mon Sep 17 00:00:00 2001 From: Daniel Berteaud Date: Fri, 1 Jun 2018 10:34:40 +0200 Subject: [PATCH] Add basic scripts for PVE monitoring --- zabbix_conf/pve.conf | 10 +++++++ zabbix_scripts/check_pve_sudo | 62 ++++++++++++++++++++++++++++++++++++++ zabbix_scripts/disco_pve_sudo | 69 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 zabbix_conf/pve.conf create mode 100644 zabbix_scripts/check_pve_sudo create mode 100644 zabbix_scripts/disco_pve_sudo diff --git a/zabbix_conf/pve.conf b/zabbix_conf/pve.conf new file mode 100644 index 0000000..01f8ccf --- /dev/null +++ b/zabbix_conf/pve.conf @@ -0,0 +1,10 @@ +# Discover PVE items +# $1 can be nodes, guests, storage or pools +UserParameter=pve.discovery[*],/usr/bin/sudo /var/lib/zabbix/bin/disco_pve_sudo --what=$1 + +# Type: Agent or Agent (active) +# pve.check.all[type,id] +# Where type is what to monitor (pool, storage, node, cluster, guest) +# id is the id of the item to monitor. For a guest, it's his numerical ID, for a storage +# a node or a pool, its name. For the cluster, there's no ID +UserParameter=pve.check.all[*],/usr/bin/sudo /var/lib/zabbix/bin/check_pve_sudo --$1=$2 diff --git a/zabbix_scripts/check_pve_sudo b/zabbix_scripts/check_pve_sudo new file mode 100644 index 0000000..59d3d07 --- /dev/null +++ b/zabbix_scripts/check_pve_sudo @@ -0,0 +1,62 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; +use JSON; +use Getopt::Long; +use File::Which; +use Data::Dumper; + +my $pvesh = which('pvesh'); +my $json; +my $pretty = 0; +my ($cluster,$guest,$node,$storage,$pool) = undef; + +GetOptions( + 'cluster' => \$cluster, + 'guest=i' => \$guest, + 'node=s' => \$node, + 'storage=s' => \$storage, + 'pool=s' => \$pool, + 'pretty' => \$pretty +); + +if ($cluster){ + my $cluster = from_json(qx($pvesh get /cluster/status 2>/dev/null)); + foreach my $item (@{$cluster}){ + if ($item->{type} eq 'cluster'){ + $json->{$_} = $item->{$_} foreach (qw(quorate nodes name version)); + last; + } + } +} elsif ($node){ + foreach my $item (qw(status version subscription)){ + $json->{$item} = from_json(qx(pvesh get /nodes/$node/$item 2>/dev/null)); + } +} elsif ($guest){ + my $guests = from_json(qx($pvesh get /cluster/resources --type=vm 2>/dev/null)); + foreach my $g (@{$guests}){ + if ($g->{vmid} eq $guest){ + $json = from_json(qx($pvesh get /nodes/$g->{node}/$g->{type}/$guest/status/current 2>/dev/null)); + last; + } + } +} elsif ($pool){ + my $pool = from_json(qx($pvesh get /pools/$pool 2>/dev/null)); + $json->{comment} = $pool->{comment}; + foreach my $type (qw(qemu lxc)){ + $json->{$_}->{$type} = 0 foreach (qw(guests templates)); + } + foreach my $item (@{$pool->{members}}){ + if ($item->{type} =~ m/^(qemu|lxc)$/ and !$item->{template}){ + $json->{guests}->{$_} += $item->{$_} foreach (qw(cpu maxcpu diskread diskwrite maxdisk mem maxmem netin netout)); + $json->{guests}->{$item->{type}}++; + } + if ($item->{type} =~ m/^(qemu|lxc)$/ and $item->{template}){ + $json->{templates}->{$_} += $item->{$_} foreach (qw(maxdisk)); + $json->{templates}->{$item->{type}}++; + } + } +} + +print to_json($json, { pretty => $pretty }) . "\n"; diff --git a/zabbix_scripts/disco_pve_sudo b/zabbix_scripts/disco_pve_sudo new file mode 100644 index 0000000..e350d90 --- /dev/null +++ b/zabbix_scripts/disco_pve_sudo @@ -0,0 +1,69 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; +use JSON; +use Getopt::Long; +use File::Which; + +my $what = 'nodes'; +my $pretty = 0; + +GetOptions( + 'what=s' => \$what, + 'pretty' => \$pretty +); + +my $pvesh = which('pvesh'); +my $json = {}; +@{$json->{data}} = (); + +unless($pvesh){ + print to_json($json) . "\n"; + exit 0; +} + +if ($what eq 'nodes'){ + my $cluster_status = from_json(qx($pvesh get /cluster/status 2>/dev/null)); + foreach my $item (@{$cluster_status}){ + next unless ($item->{type} eq 'node'); + push @{$json->{data}}, { + '{#PVE_NODE_NAME}' => $item->{name}, + '{#PVE_NODE_IP}' => $item->{ip}, + '{#PVE_NODE_ID}' => $item->{nodeid}, + '{#PVE_NODE_LOCAL}' => $item->{local} + }; + } +} elsif ($what eq 'guests'){ + my $guests = from_json(qx($pvesh get /cluster/resources --type=vm 2>/dev/null)); + foreach my $guest (@{$guests}){ + push @{$json->{data}}, { + '{#PVE_GUEST_ID}' => $guest->{vmid}, + '{#PVE_GUEST_NODE}' => $guest->{node}, + '{#PVE_GUEST_TYPE}' => $guest->{type}, + '{#PVE_GUEST_NAME}' => $guest->{name}, + '{#PVE_GUEST_TEMPLATE}' => $guest->{template} + }; + } +} elsif ($what eq 'storage'){ + my $stores = from_json(qx($pvesh get /storage 2>/dev/null)); + foreach my $store (@{$stores}){ + push @{$json->{data}}, { + '{#PVE_STOR_ID}' => $store->{storage}, + '{#PVE_STOR_TYPE}' => $store->{type}, + '{#PVE_STOR_STATUS}' => ($store->{disabled} || 0), + '{#PVE_STOR_SHARED}' => ($store->{shared} || 0), + '{#PVE_STOR_CONTENT}' => $store->{content} + }; + } +} elsif ($what eq 'pools'){ + my $pools = from_json(qx($pvesh get /pools 2>/dev/null)); + foreach my $pool (@{$pools}){ + push @{$json->{data}}, { + '{#PVE_POOL_ID}' => $pool->{poolid}, + '{#PVE_POOL_DESC}' => $pool->{comment} + }; + } +} + +print to_json($json, { pretty => $pretty }) . "\n";