summaryrefslogtreecommitdiff
path: root/FS/FS/part_export/trango.pm
diff options
context:
space:
mode:
Diffstat (limited to 'FS/FS/part_export/trango.pm')
-rw-r--r--FS/FS/part_export/trango.pm434
1 files changed, 0 insertions, 434 deletions
diff --git a/FS/FS/part_export/trango.pm b/FS/FS/part_export/trango.pm
deleted file mode 100644
index e7f1126..0000000
--- a/FS/FS/part_export/trango.pm
+++ /dev/null
@@ -1,434 +0,0 @@
-package FS::part_export::trango;
-
-=head1 FS::part_export::trango
-
-This export sends SNMP SETs to a router using the Net::SNMP package. It requires the following custom fields to be defined on a router. If any of the required custom fields are not present, then the export will exit quietly.
-
-=head1 Required custom fields
-
-=over 4
-
-=item trango_address - IP address (or hostname) of the Trango AP.
-
-=item trango_comm - R/W SNMP community of the Trango AP.
-
-=item trango_ap_type - Trango AP Model. Currently 'access5830' is the only supported option.
-
-=back
-
-=head1 Optional custom fields
-
-=over 4
-
-=item trango_baseid - Base ID of the Trango AP. See L</"Generating SU IDs">.
-
-=item trango_apid - AP ID of the Trango AP. See L</"Generating SU IDs">.
-
-=back
-
-=head1 Generating SU IDs
-
-This export will/must generate a unique SU ID for each service exported to a Trango AP. It can be done such that SU IDs are globally unique, unique per Base ID, or unique per Base ID/AP ID pair. This is accomplished by setting neither trango_baseid and trango_apid, only trango_baseid, or both trango_baseid and trango_apid, respectively. An SU ID will be generated if the FS::svc_broadband virtual field specified by suid_field export option is unset, otherwise the existing value will be used.
-
-=head1 Device Support
-
-This export has been tested with the Trango Access5830 AP.
-
-
-=cut
-
-
-use strict;
-use vars qw(@ISA %info $me $DEBUG $trango_mib $counter_dir);
-
-use FS::UID qw(dbh datasrc);
-use FS::Record qw(qsearch qsearchs);
-use FS::part_export::snmp;
-
-use Tie::IxHash;
-use File::CounterFile;
-use Data::Dumper qw(Dumper);
-
-@ISA = qw(FS::part_export::snmp);
-
-tie my %options, 'Tie::IxHash', (
- 'suid_field' => {
- 'label' => 'Trango SU ID field',
- 'default' => 'trango_suid',
- 'notes' => 'Name of the FS::svc_broadband virtual field that will contain the SU ID.',
- },
- 'mac_field' => {
- 'label' => 'Trango MAC address field',
- 'default' => '',
- 'notes' => 'Name of the FS::svc_broadband virtual field that will contain the SU\'s MAC address.',
- },
-);
-
-%info = (
- 'svc' => 'svc_broadband',
- 'desc' => 'Sends SNMP SETs to a Trango AP.',
- 'options' => \%options,
- 'notes' => 'Requires Net::SNMP. See the documentation for FS::part_export::trango for required virtual fields and usage information.',
-);
-
-$me= '[' . __PACKAGE__ . ']';
-$DEBUG = 1;
-
-$trango_mib = {
- 'access5830' => {
- 'snmpversion' => 'snmpv1',
- 'varbinds' => {
- 'insert' => [
- { # sudbDeleteOrAddID
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.1',
- 'type' => 'INTEGER',
- 'value' => \&_trango_access5830_sudbDeleteOrAddId,
- },
- { # sudbAddMac
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.2',
- 'type' => 'HEX_STRING',
- 'value' => \&_trango_access5830_sudbAddMac,
- },
- { # sudbAddSU
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.7',
- 'type' => 'INTEGER',
- 'value' => 1,
- },
- ],
- 'delete' => [
- { # sudbDeleteOrAddID
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.1',
- 'type' => 'INTEGER',
- 'value' => \&_trango_access5830_sudbDeleteOrAddId,
- },
- { # sudbDeleteSU
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.8',
- 'type' => 'INTEGER',
- 'value' => 1,
- },
- ],
- 'replace' => [
- { # sudbDeleteOrAddID
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.1',
- 'type' => 'INTEGER',
- 'value' => \&_trango_access5830_sudbDeleteOrAddId,
- },
- { # sudbDeleteSU
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.8',
- 'type' => 'INTEGER',
- 'value' => 1,
- },
- { # sudbDeleteOrAddID
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.1',
- 'type' => 'INTEGER',
- 'value' => \&_trango_access5830_sudbDeleteOrAddId,
- },
- { # sudbAddMac
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.2',
- 'type' => 'HEX_STRING',
- 'value' => \&_trango_access5830_sudbAddMac,
- },
- { # sudbAddSU
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.7',
- 'type' => 'INTEGER',
- 'value' => 1,
- },
- ],
- 'suspend' => [
- { # sudbDeleteOrAddID
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.1',
- 'type' => 'INTEGER',
- 'value' => \&_trango_access5830_sudbDeleteOrAddId,
- },
- { # sudbDeleteSU
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.8',
- 'type' => 'INTEGER',
- 'value' => 1,
- },
- ],
- 'unsuspend' => [
- { # sudbDeleteOrAddID
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.1',
- 'type' => 'INTEGER',
- 'value' => \&_trango_access5830_sudbDeleteOrAddId,
- },
- { # sudbAddMac
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.2',
- 'type' => 'HEX_STRING',
- 'value' => \&_trango_access5830_sudbAddMac,
- },
- { # sudbAddSU
- 'oid' => '1.3.6.1.4.1.5454.1.20.3.5.7',
- 'type' => 'INTEGER',
- 'value' => 1,
- },
- ],
- },
- },
-};
-
-
-sub _field_prefix { 'trango'; }
-
-sub _req_router_fields {
- map {
- $_[0]->_field_prefix . '_' . $_
- } (qw(address comm ap_type suid_field));
-}
-
-sub _get_cmd_sub {
-
- return('FS::part_export::snmp::snmp_cmd');
-
-}
-
-sub _prepare_args {
-
- my ($self, $action, $router) = (shift, shift, shift);
- my ($svc_broadband) = shift;
- my $old = shift if $action eq 'replace';
- my $field_prefix = $self->_field_prefix;
- my $error;
-
- my $ap_type = $router->getfield($field_prefix . '_ap_type');
-
- unless (exists $trango_mib->{$ap_type}) {
- return "Unsupported Trango AP type '$ap_type'";
- }
-
- $error = $self->_check_suid(
- $action, $router, $svc_broadband, ($old) ? $old : ()
- );
- return $error if $error;
-
- $error = $self->_check_mac(
- $action, $router, $svc_broadband, ($old) ? $old : ()
- );
- return $error if $error;
-
- my $ap_mib = $trango_mib->{$ap_type};
-
- my $args = [
- '-hostname' => $router->getfield($field_prefix.'_address'),
- '-version' => $ap_mib->{'snmpversion'},
- '-community' => $router->getfield($field_prefix.'_comm'),
- ];
-
- my @varbindlist = ();
-
- foreach my $oid (@{$ap_mib->{'varbinds'}->{$action}}) {
- warn "[debug]$me Processing OID '" . $oid->{'oid'} . "'" if $DEBUG;
- my $value;
- if (ref($oid->{'value'}) eq 'CODE') {
- eval {
- $value = &{$oid->{'value'}}(
- $self, $action, $router, $svc_broadband,
- (($old) ? $old : ()),
- );
- };
- return "While processing OID '" . $oid->{'oid'} . "':" . $@
- if $@;
- } else {
- $value = $oid->{'value'};
- }
-
- warn "[debug]$me Value for OID '" . $oid->{'oid'} . "': " if $DEBUG;
-
- if (defined $value) { # Skip OIDs with undefined values.
- push @varbindlist, ($oid->{'oid'}, $oid->{'type'}, $value);
- }
- }
-
-
- push @$args, ('-varbindlist', @varbindlist);
-
- return('', $args);
-
-}
-
-sub _check_suid {
-
- my ($self, $action, $router, $svc_broadband) = (shift, shift, shift, shift);
- my $old = shift if $action eq 'replace';
- my $error;
-
- my $suid_field = $self->option('suid_field');
- unless (grep {$_ eq $suid_field} $svc_broadband->fields) {
- return "Missing Trango SU ID field. "
- . "See the trango export options for more info.";
- }
-
- my $suid = $svc_broadband->getfield($suid_field);
- if ($action eq 'replace') {
- my $old_suid = $old->getfield($suid_field);
-
- if ($old_suid ne '' and $old_suid ne $suid) {
- return 'Cannot change Trango SU ID';
- }
- }
-
- if (not $suid =~ /^\d+$/ and $action ne 'delete') {
- my $new_suid = eval { $self->_get_next_suid($router); };
- return "Error while getting next Trango SU ID: $@" if ($@);
-
- warn "[debug]$me Got new SU ID: $new_suid" if $DEBUG;
- $svc_broadband->set($suid_field, $new_suid);
-
- #FIXME: Probably a bad hack.
- # We need to update the SU ID field in the database.
-
- my $oldAutoCommit = $FS::UID::AutoCommit;
- local $FS::svc_Common::noexport_hack = 1;
- local $FS::UID::AutoCommit = 0;
- my $dbh = dbh;
-
- my $svcnum = $svc_broadband->svcnum;
-
- my $old_svc = qsearchs('svc_broadband', { svcnum => $svcnum });
- unless ($old_svc) {
- return "Unable to retrieve svc_broadband with svcnum '$svcnum";
- }
-
- my $svcpart = $svc_broadband->svcpart
- ? $svc_broadband->svcpart
- : $svc_broadband->cust_svc->svcpart;
-
- my $new_svc = new FS::svc_broadband {
- $old_svc->hash,
- $suid_field => $new_suid,
- svcpart => $svcpart,
- };
-
- $error = $new_svc->check;
- if ($error) {
- $dbh->rollback if $oldAutoCommit;
- return "Error while updating the Trango SU ID: $error" if $error;
- }
-
- warn "[debug]$me Updating svc_broadband with SU ID '$new_suid'...\n" .
- &Dumper($new_svc) if $DEBUG;
-
- $error = eval { $new_svc->replace($old_svc); };
-
- if ($@ or $error) {
- $error ||= $@;
- $dbh->rollback if $oldAutoCommit;
- return "Error while updating the Trango SU ID: $error" if $error;
- }
-
- $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-
- }
-
- return '';
-
-}
-
-sub _check_mac {
-
- my ($self, $action, $router, $svc_broadband) = (shift, shift, shift, shift);
- my $old = shift if $action eq 'replace';
-
- my $mac_field = $self->option('mac_field');
- unless (grep {$_ eq $mac_field} $svc_broadband->fields) {
- return "Missing Trango MAC address field. "
- . "See the trango export options for more info.";
- }
-
- my $mac_addr = $svc_broadband->getfield($mac_field);
- unless (length(join('', $mac_addr =~ /[0-9a-fA-F]/g)) == 12) {
- return "Invalid Trango MAC address: $mac_addr";
- }
-
- return('');
-
-}
-
-sub _get_next_suid {
-
- my ($self, $router) = (shift, shift);
-
- my $counter_dir = '/usr/local/etc/freeside/export.'. datasrc . '/trango';
- my $baseid = $router->getfield('trango_baseid');
- my $apid = $router->getfield('trango_apid');
-
- my $counter_file_suffix = '';
- if ($baseid ne '') {
- $counter_file_suffix .= "_B$baseid";
- if ($apid ne '') {
- $counter_file_suffix .= "_A$apid";
- }
- }
-
- my $counter_file = $counter_dir . '/SUID' . $counter_file_suffix;
-
- warn "[debug]$me Using SUID counter file '$counter_file'";
-
- my $suid = eval {
- mkdir $counter_dir, 0700 unless -d $counter_dir;
-
- my $cf = new File::CounterFile($counter_file, 0);
- $cf->inc;
- };
-
- die "Error generating next Trango SU ID: $@" if (not $suid or $@);
-
- return($suid);
-
-}
-
-
-
-# Trango-specific subroutines for generating varbind values.
-#
-# All subs should die on error, and return undef to decline. OIDs that
-# decline will not be added to varbinds.
-
-sub _trango_access5830_sudbDeleteOrAddId {
-
- my ($self, $action, $router) = (shift, shift, shift);
- my ($svc_broadband) = shift;
- my $old = shift if $action eq 'replace';
-
- my $suid = $svc_broadband->getfield($self->option('suid_field'));
-
- # Sanity check.
- unless ($suid =~ /^\d+$/) {
- if ($action eq 'delete') {
- # Silently ignore. If we don't have a valid SU ID now, we probably
- # never did.
- return undef;
- } else {
- die "Invalid Trango SU ID '$suid'";
- }
- }
-
- return ($suid);
-
-}
-
-sub _trango_access5830_sudbAddMac {
-
- my ($self, $action, $router) = (shift, shift, shift);
- my ($svc_broadband) = shift;
- my $old = shift if $action eq 'replace';
-
- my $mac_addr = $svc_broadband->getfield($self->option('mac_field'));
- $mac_addr = join('', $mac_addr =~ /[0-9a-fA-F]/g);
-
- # Sanity check.
- die "Invalid Trango MAC address '$mac_addr'" unless (length($mac_addr)==12);
-
- return($mac_addr);
-
-}
-
-
-=head1 BUGS
-
-Plenty, I'm sure.
-
-=cut
-
-
-1;