summaryrefslogtreecommitdiff
path: root/FS/FS/part_export/broadband_snmp_get.pm
blob: 35dcd31541e7f24c25cda8b5f0592737d3db6e44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package FS::part_export::broadband_snmp_get;

use strict;
use vars qw(%info $DEBUG);
use base 'FS::part_export';
use SNMP;
use Tie::IxHash;

tie my %snmp_version, 'Tie::IxHash',
  v1  => '1',
  v2c => '2c'
  # v3 unimplemented
;

tie my %options, 'Tie::IxHash',
  'snmp_version' => {
    label=>'SNMP version', 
    type => 'select',
    options => [ keys %snmp_version ],
   },
  'snmp_community' => { 'label'=>'Community', 'default'=>'public' },
  'snmp_timeout' => { label=>'Timeout (seconds)', 'default'=>1 },
  'snmp_oid' => { label=>'Object ID', multiple=>1 },
  'snmp_oid_name' => { label=>'Object Name', multiple=>1 },
;

%info = (
  'svc'     => 'svc_broadband',
  'desc'    => 'Enable interface display of realtime SNMP get requests to service IP address',
  'config_element' => '/edit/elements/part_export/broadband_snmp_get.html',
  'options' => \%options,
  'no_machine' => 1,
  'notes'   => <<'END',
Display broadband service status information via SNMP.  Timeout is
per object, and should be small enough for realtime use.  This export takes no action 
during provisioning itself;  it is expected that snmp will be separately
configured on the service machine.
END
);

sub export_insert { ''; }
sub export_replace { ''; }
sub export_delete { ''; }
sub export_suspend { ''; }
sub export_unsuspend { ''; }

=pod

=head1 NAME

FS::part_export::broadband_snmp_get

=head1 SYNOPSIS

Configuration for realtime snmp requests to svc_broadband IP address

=head1 METHODS

=cut

=over 4

=item snmp_results SVC

Request statistics from SVC ip address.  Returns an array of hashrefs with keys 

error - error message

objectID - dotted decimal fully qualified OID

label - leaf textual identifier (e.g., 'sysDescr')

values - arrayref of arrayrefs describing values, [<obj>, <iid>, <val>, <type>]

=cut

sub snmp_results {
  my ($self, $svc) = @_;
  my $host = $svc->ip_addr;
  my $comm = $self->option('snmp_community');
  my $vers = $self->option('snmp_version');
  my $time = ($self->option('snmp_timeout') || 1) * 1000000;
  my @oids = split("\n", $self->option('snmp_oid'));
  my @oidnames = split("\n", $self->option('snmp_oid_name'));
  my %connect = (
    'DestHost'  => $host,
    'Community' => $comm,
    'Version'   => $vers,
    'Timeout'   => $time,
  );
  my $snmp = new SNMP::Session(%connect);
  return { 'error' => 'Error creating SNMP session' } unless $snmp;
  return { 'error' => $snmp->{'ErrorStr'} } if $snmp->{'ErrorStr'};
  my @out;
  for (my $i=0; $i <= $#oids; $i++) {
    my $oid = $oids[$i];
    my $oidname = $oidnames[$i];
    $oid = $SNMP::MIB{$oid}->{'objectID'} if $SNMP::MIB{$oid};
    my @values;
    if ($vers eq '1') {
      my $varbind = new SNMP::Varbind [$oid];
      my $max = 1000; #sanity check
      while ($max > 0 and defined($snmp->getnext($varbind))) {
        last if $snmp->{'ErrorStr'};
        last unless $SNMP::MIB{$varbind->[0]}; # does this happen?
        my $nextoid = $SNMP::MIB{$varbind->[0]}->{'objectID'};
        last unless $nextoid =~ /^$oid/;
        $max--;
        push @values, [ @$varbind ];
      }
    } else {
      # not clear on what max-repeaters (25) does, plucked value from example code
      # but based on testing, it isn't capping number of returned values
      my ($values) = $snmp->bulkwalk(0,25,$oid);
      @values = @$values if $values;
    }
    if ($snmp->{'ErrorStr'} || !@values) {
      push @out, { 'error' => $snmp->{'ErrorStr'} || 'No values retrieved' };
      next;
    }
    my %result = map { $_ => $SNMP::MIB{$oid}{$_} } qw( objectID label );
    $result{'name'} = $oidname;
    # unbless @values, for ease of JSON encoding
    $result{'values'} = [];
    foreach my $value (@values) {
      push @{$result{'values'}}, [ map { $_ } @$value ];
    }
    push @out, \%result;
  }
  return @out;      
}

=back

=cut

1;