File Coverage

blib/lib/App/Manoc/Manifold/SNMP/Simple.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package App::Manoc::Manifold::SNMP::Simple;
2             #ABSTRACT: A simple client based on Net::SNMP
3              
4 1     1   6 use Moose;
  1         2  
  1         5  
5              
6             our $VERSION = '2.99.2'; ##TRIAL VERSION
7              
8              
9             with
10             'App::Manoc::ManifoldRole::Base',
11             'App::Manoc::ManifoldRole::Host',
12             'App::Manoc::ManifoldRole::Hypervisor',
13             'App::Manoc::Logger::Role';
14              
15              
16 1     1   5875 use Net::SNMP 6.0 qw( :snmp DEBUG_ALL ENDOFMIBVIEW );
  0            
  0            
17             use Carp qw(croak);
18             use Try::Tiny;
19              
20              
21             has 'community' => (
22             is => 'ro',
23             isa => 'Str',
24             lazy => 1,
25             builder => '_build_community',
26             );
27              
28              
29             has 'version' => (
30             is => 'ro',
31             isa => 'Str',
32             lazy => '1',
33             builder => '_build_version',
34             );
35              
36              
37             has 'snmp_session' => (
38             is => 'ro',
39             isa => 'Object',
40             writer => '_set_snmp_session',
41             );
42              
43             sub _build_community {
44             my $self = shift;
45              
46             return $self->credentials->{snmp_community} || 'public';
47             }
48              
49             sub _build_version {
50             my $self = shift;
51             my $version = $self->credentials->{snmp_version} || 2;
52              
53             my %version_map = (
54             '1' => 'snmpv1',
55             '2' => 'snmpv2c',
56             '2c' => 'snmpv2c',
57             '3' => 'snmpv3'
58             );
59             return $version_map{$version};
60             }
61              
62              
63             sub connect {
64             my ($self) = @_;
65             my $opts = shift || {};
66              
67             my $info;
68              
69             my %options;
70             $options{-hostname} = $self->host;
71              
72             my $extra_params = $self->extra_params;
73             $options{-version} = $self->version;
74             $options{-community} = $self->community;
75              
76             my @extra_options = qw( -port -timeout -retries
77             -localaddr -localport -username -authkey
78             -authpassword -authprotocol
79             -privkey -privpassword -privprotocol
80             );
81             foreach (@extra_options) {
82             $options{$_} = $extra_params->{$_} if exists $extra_params->{$_};
83             }
84              
85             # $options{-debug} = DEBUG_ALL
86             # if ( defined(_debug_level) && _debug_level > 1 );
87              
88             $options{-translate} = [
89             '-all' => 1,
90             '-octetstring' => 0,
91             '-null' => 1,
92             '-timeticks' => 0,
93             '-opaque' => 1,
94             '-nosuchobject' => 1,
95             '-nosuchinstance' => 1,
96             '-endofmibview' => 1,
97             '-unsigned' => 1,
98             ];
99              
100             my $session;
101             try {
102             $session = Net::SNMP->session(%options);
103             }
104             catch {
105             my $msg = "Could not connect to " . $self->host . " .$_";
106             $self->log->error($msg);
107             return;
108             };
109              
110             unless ($session) {
111             $self->log->error( "Could not connect to ", $self->host );
112             return;
113             }
114              
115             $self->_set_snmp_session($session);
116             return 1;
117             }
118              
119             #----------------------------------------------------------------------#
120             #
121             # SNMP scalar and table declaration
122             #
123             #----------------------------------------------------------------------#
124              
125              
126             sub has_snmp_scalar {
127             my ( $name, %options ) = @_;
128              
129             my $oid = $options{oid} or croak "oid attribute is required";
130             my $munger = $options{munger};
131              
132             my $attr_name = "snmp_$name";
133             my $builder_name = "_build_${attr_name}";
134              
135             has $attr_name => (
136             is => 'ro',
137             lazy => 1,
138             builder => "_build_${attr_name}"
139             );
140              
141             {
142             no strict 'refs';
143             *{$builder_name} = sub {
144             my $self = shift;
145             $self->_mib_read_scalar( $oid, $munger );
146             }
147             }
148             }
149              
150              
151             sub has_snmp_table {
152             my ( $name, %options ) = @_;
153             my $table_oid = $options{oid};
154             $table_oid or croak "Table $name has no oid";
155              
156             my $columns = $options{columns};
157             $columns or croak "Table $name has no columns definition";
158              
159             my @column_names = keys %$columns;
160             while ( my ( $col_name, $col_opts ) = each(%$columns) ) {
161             ref $col_opts eq 'ARRAY' or $col_opts = [$col_opts];
162             my ( $sub_id, $munger ) = @$col_opts;
163             my $col_oid = "$table_oid.1.$sub_id";
164              
165             my $attr_name = "snmp_$col_name";
166             my $builder_name = "_build_${attr_name}";
167              
168             has $attr_name => (
169             is => 'ro',
170             lazy => 1,
171             builder => $builder_name,
172             );
173              
174             {
175             no strict 'refs';
176             *{$builder_name} = sub {
177             my $self = shift;
178             $self->_mib_read_tablerow( $col_oid, $munger );
179             }
180             }
181             }
182             }
183              
184              
185             my $SNMPV2_MIB_OID = '1.3.6.1.2.1.1';
186              
187             has_snmp_scalar "sysDescr" => ( oid => "$SNMPV2_MIB_OID.1" );
188             has_snmp_scalar "sysObjectID" => ( oid => "$SNMPV2_MIB_OID.2" );
189             has_snmp_scalar "sysUpTime" => ( oid => "$SNMPV2_MIB_OID.3" );
190             has_snmp_scalar "sysName" => ( oid => "$SNMPV2_MIB_OID.5" );
191             has_snmp_scalar "sysLocation" => ( oid => "$SNMPV2_MIB_OID.6" );
192             has_snmp_scalar "sysServices" => ( oid => "$SNMPV2_MIB_OID.7" );
193              
194              
195             my $HOST_RESOURCES_MIB_OID = '1.3.6.1.2.1.25';
196             has_snmp_table 'hrSWInstalledTable' => (
197             oid => "$HOST_RESOURCES_MIB_OID.6.3",
198             columns => {
199             'hrSWInstalledIndex' => 1,
200             'hrSWInstalledName' => 2,
201             'hrSWInstalledID' => 3,
202             'hrSWInstalledType' => 4,
203             'hrSWInstalledDate' => [ 5, \&_munge_sw_installed_date ],
204             },
205             );
206              
207              
208             has_snmp_table 'hrDeviceTable' => (
209             oid => "$HOST_RESOURCES_MIB_OID.3.2",
210             index => 'hrDeviceIndex',
211             columns => {
212             'hrDeviceType' => 2,
213             'hrDeviceDescr' => 3,
214             'hrDeviceID' => 4,
215             'hrDeviceStatus' => [
216             5,
217             sub {
218             my $val = shift;
219             my @stati = qw(INVALID unknown running warning testing down);
220             return $stati[$val];
221             }
222             ],
223             'hrDeviceErrors' => 6,
224             },
225             );
226              
227              
228             has_snmp_table 'hrProcessorTable' => (
229             oid => "$HOST_RESOURCES_MIB_OID.3.3",
230             index => 'hrDeviceIndex',
231             columns => {
232             'hrProcessorLoad' => 2,
233             },
234             );
235              
236              
237             my $UCD_SNMP_MIB_OID = '.1.3.6.1.4.1.2021';
238             has_snmp_scalar 'memTotalReal' => ( oid => "${UCD_SNMP_MIB_OID}.4.5", );
239              
240              
241             my $VMWARE_SYSTEM_MIB = '.1.3.6.1.4.1.6876.1';
242             has_snmp_scalar 'vmwProdName' => ( oid => "${VMWARE_SYSTEM_MIB}.1", );
243             has_snmp_scalar 'vmwProdVersion' => ( oid => "${VMWARE_SYSTEM_MIB}.1", );
244              
245             my $VMWARE_VMINFO_MIB_OID = '.1.3.6.1.4.1.6876.2';
246             has_snmp_table 'vmwVmTable' => (
247             oid => "$VMWARE_VMINFO_MIB_OID.1",
248             index => "vmwVmIdx",
249             columns => {
250             vmwVmIdx => 1,
251             vmwVmDisplayName => 2,
252             vmwVmGuestOS => 4,
253             vmwVmMemSize => 5,
254             vmwVmState => 6,
255             vmwVmCpus => 9,
256             vmwVmUUID => 10
257             },
258             );
259              
260             #----------------------------------------------------------------------#
261              
262             sub _build_boottime {
263             my $self = shift;
264             return time() - int( $self->snmp_sysUpTime / 100 );
265             }
266              
267             sub _build_name {
268             my $self = shift;
269             return $self->snmp_sysName;
270             }
271              
272             sub _build_model {
273             my $self = shift;
274             warn "TODO";
275             return;
276             }
277              
278             sub _build_os {
279             my $self = shift;
280              
281             my $descr = $self->snmp_sysDescr;
282             my $vendor = $self->vendor;
283              
284             $vendor eq 'Microsoft' and $descr =~ /Software: Windows/ and return "Windows";
285              
286             if ( $vendor eq 'NetSNMP' ) {
287             my @fields = split /\s+/, $descr;
288             return $fields[0];
289             }
290              
291             if ( $vendor eq 'Cisco' ) {
292             return 'ios-xe' if ( $descr =~ /IOS-XE/ );
293             return 'ios-xr' if ( $descr =~ /IOS XR/ );
294             return 'ios' if ( $descr =~ /IOS/ );
295             return 'catalyst' if ( $descr =~ /catalyst/i );
296             return 'css' if ( $descr =~ /Content Switch SW/ );
297             return 'css-sca' if ( $descr =~ /Cisco Systems Inc CSS-SCA-/ );
298             return 'pix' if ( $descr =~ /Cisco PIX Security Appliance/ );
299             return 'asa' if ( $descr =~ /Cisco Adaptive Security Appliance/ );
300             return 'san-os' if ( $descr =~ /Cisco SAN-OS/ );
301             }
302              
303             if ( $vendor eq 'VMWare' ) {
304             my $prodname = $self->snmp_vmwProdName;
305             return $prodname if defined($prodname);
306             }
307              
308             return '';
309             }
310              
311             sub _build_os_ver {
312             my $self = shift;
313             my $descr = $self->snmp_sysDescr;
314             my $vendor = $self->vendor;
315              
316             $vendor eq 'Microsoft' and
317             $descr =~ /Windows Version\s+([\d\.]+)/ and
318             return $1;
319              
320             if ( $vendor eq 'NetSNMP' ) {
321             my @fields = split /\s+/, $descr;
322             return $fields[2];
323             }
324              
325             if ( $vendor eq 'Cisco' ) {
326             my $os = $self->os;
327              
328             if ( defined $os && defined $descr ) {
329             # Older Catalysts
330             if ( $os eq 'catalyst' && $descr =~ m/V(\d{1}\.\d{2}\.\d{2})/ ) {
331             return $1;
332             }
333              
334             if ( $os eq 'css' &&
335             $descr =~ m/Content Switch SW Version ([0-9\.\(\)]+) with SNMPv1\/v2c Agent/ )
336             {
337             return $1;
338             }
339              
340             if ( $os eq 'css-sca' &&
341             $descr =~ m/Cisco Systems Inc CSS-SCA-2FE-K9, ([0-9\.\(\)]+) Release / )
342             {
343             return $1;
344             }
345              
346             if ( $os eq 'pix' &&
347             $descr =~ m/Cisco PIX Security Appliance Version ([0-9\.\(\)]+)/ )
348             {
349             return $1;
350             }
351              
352             if ( $os eq 'asa' &&
353             $descr =~ m/Cisco Adaptive Security Appliance Version ([0-9\.\(\)]+)/ )
354             {
355             return $1;
356             }
357              
358             if ( $os =~ /^fwsm/ && $descr =~ m/Version (\d+\.\d+(\(\d+\)){0,1})/ ) {
359             return $1;
360             }
361              
362             if ( $os eq 'ios-xr' && $descr =~ m/Version (\d+[\.\d]+)/ ) {
363             return $1;
364             }
365              
366             }
367              
368             if ( $os =~ /^ace/ && $self->can('entPhysicalSoftwareRev') ) {
369             my $ver = $self->entPhysicalSoftwareRev->{1};
370             $ver and return $ver;
371             }
372              
373             # Newer Catalysts and IOS devices
374             if ( defined $descr and
375             $descr =~ m/Version (\d+\.\d+\([^)]+\)[^,\s]*)(,|\s)+/ )
376             {
377             return $1;
378             }
379             } # end of Cisco
380              
381             if ( $vendor eq 'VMWare' ) {
382             my $prodver = $self->snmp_vmwProdVersion;
383             return $prodver if defined($prodver);
384             }
385              
386             return '';
387             }
388              
389             sub _build_vendor {
390             my $self = shift;
391             my $info = $self->snmp_sysObjectID;
392             return _sysObjectID2vendor($info) || "";
393             }
394              
395             sub _build_serial {
396             my $self = shift;
397             return;
398             }
399              
400             sub _build_cpu_count {
401             my $self = shift;
402              
403             my $procLoad = $self->snmp_hrProcessorLoad;
404              
405             return scalar( keys(%$procLoad) );
406             }
407              
408             sub _build_cpu_model { "Unkown" }
409              
410             sub _build_ram_memory {
411             my $self = shift;
412             my $memTot = $self->snmp_memTotalReal;
413             $memTot eq 'noSuchObject' and return;
414             return int($memTot) / 1024;
415             }
416              
417             sub _build_kernel { undef }
418              
419             sub _build_kernel_ver { undef }
420              
421             has 'package_name_parser' => (
422             is => 'rw',
423             isa => 'Ref',
424             lazy => 1,
425             builder => '_build_package_name_parser',
426             );
427              
428             sub _build_package_name_parser {
429             my $self = shift;
430              
431             my $os = $self->os;
432              
433             if ( $os eq 'Linux' ) {
434             return sub {
435             my $pkg = shift;
436              
437             # redhat name, version release platform
438             $pkg =~ /^(.+)-([^-]+)-([^-]+)\.(.*)$/ and
439             return [ $1, $2 ];
440             return [ $pkg, undef ];
441             };
442             }
443              
444             return sub { [ shift, undef ] };
445             }
446              
447             sub _build_installed_sw {
448             my $self = shift;
449              
450             my $installed = $self->snmp_hrSWInstalledName;
451             my $parser = $self->package_name_parser;
452              
453             return [ map { $parser->($_) } values(%$installed) ];
454             }
455              
456             sub _build_virtual_machines {
457             my $self = shift;
458              
459             if ( $self->vendor eq 'VMWare' ) {
460             my @result;
461              
462             $self->log->warn("Using vmware MIB to retrieve vm list ");
463              
464             my $names = $self->snmp_vmwVmDisplayName;
465             my $uuids = $self->snmp_vmwVmUUID;
466             my $memsizes = $self->snmp_vmwVmMemSize;
467             my $vcpus = $self->snmp_vmwVmCpus;
468              
469             while ( my ( $idx, $uuid ) = each(%$uuids) ) {
470             my $vm_info = {};
471             $vm_info->{uuid} = $uuid;
472             $vm_info->{name} = $names->{$idx};
473             $vm_info->{vcpus} = $vcpus->{$idx};
474             $vm_info->{memsize} = $memsizes->{$idx};
475              
476             push @result, $vm_info;
477             }
478              
479             return \@result;
480             }
481             }
482              
483             #----------------------------------------------------------------------#
484             #
485             # SNMP gory details start here....
486             #
487             #----------------------------------------------------------------------#
488              
489             # Implements get_scalar using Net::SNMP session
490              
491             sub _get_scalar {
492             my ( $self, $oid ) = @_;
493              
494             my $session = $self->snmp_session;
495              
496             #add istance number to the oid
497             $oid .= '.0';
498              
499             $self->log->debug( $self->meta->name, "Fetching scalar $oid" );
500              
501             my $result = $session->get_request( '-varbindlist' => [$oid] );
502             $result or die "SNMP error " . $session->error();
503              
504             return $result->{$oid};
505             }
506              
507             # Implements get_subtree using Net::SNMP session
508              
509             sub _get_subtree {
510             my ( $self, $oid ) = @_;
511              
512             my @result;
513              
514             my $s = $self->snmp_session;
515             $oid eq '.' and $oid = '0';
516              
517             $self->log->debug( $self->meta->name, "Fetching subtree $oid" );
518              
519             my $last_oid = $oid;
520              
521             if ( $s->version() == SNMP_VERSION_1 ) {
522              
523             while ( defined $s->get_next_request( -varbindlist => [$last_oid] ) ) {
524             my $returned_oid = ( $s->var_bind_names() )[0];
525             if ( !oid_base_match( $last_oid, $returned_oid ) ) {
526             last;
527             }
528              
529             # store into result
530             push @result, [ $returned_oid, $s->var_bind_list()->{$returned_oid} ];
531              
532             $last_oid = $returned_oid;
533             }
534              
535             }
536             else {
537              
538             GET_BULK:
539             while (
540             defined $s->get_bulk_request(
541             -maxrepetitions => 1,
542             -varbindlist => [$last_oid]
543             )
544             )
545             {
546             my @oids = $s->var_bind_names();
547              
548             if ( !scalar @oids ) {
549             die('Received an empty varBindList');
550             }
551              
552             foreach my $returned_oid (@oids) {
553              
554             if ( !oid_base_match( $oid, $returned_oid ) ) {
555             last GET_BULK;
556             }
557              
558             # Make sure we have not hit the end of the MIB.
559             if ( $s->var_bind_types()->{$returned_oid} == ENDOFMIBVIEW ) {
560             last GET_BULK;
561             }
562              
563             push @result, [ $returned_oid, $s->var_bind_list()->{$returned_oid} ];
564              
565             $last_oid = $returned_oid;
566             }
567             }
568              
569             }
570              
571             return \@result;
572             }
573              
574             sub _mib_read_scalar {
575             my ( $self, $oid, $munger ) = @_;
576              
577             my $v = $self->_get_scalar($oid);
578             $munger and $v = $munger->($v);
579             return $v;
580             }
581              
582             sub _mib_read_tablerow {
583             my ( $self, $oid, $munger ) = @_;
584              
585             my $row = $self->_get_subtree($oid);
586              
587             my $ret = {};
588             foreach (@$row) {
589              
590             # Don't optimize this RE!
591             $_->[0] =~ /^$oid\.(.*)/ and $_->[0] = $1;
592             $munger and $_->[1] = $munger->( $_->[1] );
593              
594             $ret->{ $_->[0] } = $_->[1];
595             }
596              
597             return $ret;
598             }
599              
600             # Takes a BOOLEAN and makes it a nop|true|false string
601              
602             sub _munge_bool {
603             my $bool = shift;
604             my @ARR = qw ( nop false true);
605              
606             return $ARR[$bool];
607             }
608              
609             # Takes a binary IP and makes it dotted ASCII
610              
611             sub _munge_ipaddress {
612             my $ip = shift;
613             return join( '.', unpack( 'C4', $ip ) );
614             }
615              
616             # Takes an octet stream (HEX-STRING) and returns a colon separated
617             # ASCII hex string.
618              
619             sub _munge_macaddress {
620             my $mac = shift;
621             $mac or return "";
622             $mac = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $mac ) );
623             return $mac if $mac =~ /^([0-9A-F][0-9A-F]:){5}[0-9A-F][0-9A-F]$/i;
624             return "ERROR";
625             }
626              
627             sub _munge_sw_installed_date {
628             my $val = shift;
629              
630             my ( $y, $m, $d, $hour, $min, $sec ) = unpack( 'n C6 a C2', $val );
631              
632             return "$y-$m-$d $hour:$min:$sec";
633              
634             }
635              
636             my %ID_VENDOR_MAP = (
637             9 => 'Cisco',
638             11 => 'HP',
639             18 => 'BayRS',
640             42 => 'Sun',
641             43 => '3Com',
642             45 => 'Baystack',
643             171 => 'Dell',
644             207 => 'Allied',
645             244 => 'Lantronix',
646             311 => 'Microsoft',
647             318 => 'APC',
648             674 => 'Dell',
649             1872 => 'AlteonAD',
650             1916 => 'Extreme',
651             1991 => 'Foundry',
652             2021 => 'NetSNMP',
653             2272 => 'Passport',
654             2636 => 'Juniper',
655             2925 => 'Cyclades',
656             3076 => 'Altiga',
657             3224 => 'Netscreen',
658             3375 => 'F5',
659             3417 => 'BlueCoatSG',
660             4526 => 'Netgear',
661             5624 => 'Enterasys',
662             5951 => 'Netscaler',
663             6027 => 'Force10',
664             6486 => 'AlcatelLucent',
665             6527 => 'Timetra',
666             6876 => 'VMWare',
667             8072 => 'NetSNMP',
668             9303 => 'PacketFront',
669             10002 => 'Ubiquiti',
670             11898 => 'Orinoco',
671             12325 => 'Pf',
672             12356 => 'Fortinet',
673             12532 => 'Neoteris',
674             14179 => 'Airespace',
675             14525 => 'Trapeze',
676             14823 => 'Aruba',
677             14988 => 'Mikrotik',
678             17163 => 'Steelhead',
679             25506 => 'H3C',
680             26543 => 'IBMGbTor',
681             30065 => 'Arista',
682             35098 => 'Pica8',
683             );
684              
685             # Try to extract a vendor string from a sysObjectID.
686              
687             sub _sysObjectID2vendor {
688             my ($id) = @_;
689             defined $id or return "NO VENDOR";
690              
691             $id =~ /^\.?1\.3\.6\.1\.4\.1\.(\d+)/ and return $ID_VENDOR_MAP{$1};
692             return "UNKNOWN";
693             }
694              
695             no Moose;
696             __PACKAGE__->meta->make_immutable;
697              
698             # Local Variables:
699             # mode: cperl
700             # indent-tabs-mode: nil
701             # cperl-indent-level: 4
702             # cperl-indent-parens-as-block: t
703             # End:
704              
705             __END__
706              
707             =pod
708              
709             =head1 NAME
710              
711             App::Manoc::Manifold::SNMP::Simple - A simple client based on Net::SNMP
712              
713             =head1 VERSION
714              
715             version 2.99.2
716              
717             =head1 DESCRIPTION
718              
719             A simple SNMP client Manifold, entirely based on Net::SNMP avoiding
720             the need of any MIB file.
721              
722             =head1 CONSUMED ROLES
723              
724             =over 4
725              
726             =item *
727              
728             App::Manoc::ManifoldRole::Base
729              
730             =item *
731              
732             App::Manoc::ManifoldRole::Host
733              
734             =item *
735              
736             App::Manoc::ManifoldRole::Hypervisor
737              
738             =item *
739              
740             App::Manoc::Logger::Role
741              
742             =back
743              
744             =head1 ATTRIBUTES
745              
746             =head2 community
747              
748             SNMP community string
749              
750             =head2 version
751              
752             SNMP version: 1, 2c or 3.
753              
754             =head2 snmp_session
755              
756             The Net::SNMP session used by the manifold.
757              
758             =head1 METHODS
759              
760             =head2 connect
761              
762             Connect the manifold using Net::SNMP and set snmp_session.
763              
764             =head2 has_snmp_scalar($name, %attrs)
765              
766             Creates a snmp_<$name> attribute with _build_$name builder. The
767             %attrs arra must define the "oid" paramater and can set a "munger"
768             subroutine.
769              
770             =head2 has_snmp_table( $name, %options )
771              
772             Creates a snmp_<columnname> accessor for each defined column.
773              
774             =head1 SNMP ATTRIBUTES
775              
776             =head2 SNMPV2 MIB
777              
778             =over 4
779              
780             =item sysDescr
781              
782             =item sysObjectID
783              
784             =item sysName
785              
786             =item sysLocation
787              
788             =item sysServices
789              
790             =back
791              
792             =head2 HOST RESOURCES MIB
793              
794             =over 4
795              
796             =item hrSWInstalledTable with columns
797              
798             =over 4
799              
800             =item hrSWInstalledIndex
801              
802             =item hrSWInstalledName
803              
804             =item hrSWInstalledID
805              
806             =item hrSWInstalledTypem
807              
808             =item hrSWInstalledDate
809              
810             =back
811              
812             =item hrDeviceTable
813              
814             =over 4
815              
816             =item hrDeviceType
817              
818             =item hrDeviceDescr
819              
820             =item hrDeviceID
821              
822             =item hrDeviceStatus which can be one of these strings: INVALID unknown running warning testing down
823              
824             =back
825              
826             =item hrProcessorTable
827              
828             =over 4
829              
830             =item hrDeviceIndex
831              
832             =item hrProcessorLoad
833              
834             =back
835              
836             =back
837              
838             =head2 UCD SNMP MIB
839              
840             =over 4
841              
842             =item memTotalReal
843              
844             =back
845              
846             =head2 VMWare MIBs
847              
848             =over 4
849              
850             =item vmwProdName
851              
852             =item vmwProdVersion
853              
854             =item vmwVmTable
855              
856             =over 4
857              
858             =item vmwVmIdx
859              
860             =item vmwVmDisplayName
861              
862             =item vmwVmGuestOS
863              
864             =item vmwVmMemSize
865              
866             =item vmwVmState
867              
868             =item vmwVmCpus
869              
870             =item vmwVmUUID
871              
872             =back
873              
874             =back
875              
876             =head1 AUTHORS
877              
878             =over 4
879              
880             =item *
881              
882             Gabriele Mambrini <gmambro@cpan.org>
883              
884             =item *
885              
886             Enrico Liguori
887              
888             =back
889              
890             =head1 COPYRIGHT AND LICENSE
891              
892             This software is copyright (c) 2017 by Gabriele Mambrini.
893              
894             This is free software; you can redistribute it and/or modify it under
895             the same terms as the Perl 5 programming language system itself.
896              
897             =cut