summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/Schema.pm1
-rw-r--r--FS/FS/nas.pm4
-rw-r--r--FS/FS/part_export/broadband_nas.pm145
-rwxr-xr-xFS/FS/svc_broadband.pm12
4 files changed, 155 insertions, 7 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index bd708a7b6..68a072f1a 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -2282,6 +2282,7 @@ sub tables_hashref {
'server', 'varchar', 'NULL', 64, '', '',
'community', 'varchar', 'NULL', 50, '', '',
'description', 'varchar', '', 200, 'RADIUS Client', '',
+ 'svcnum', 'int', 'NULL', '', '', '',
],
'primary_key' => 'nasnum',
'unique' => [ [ 'nasname' ], ],
diff --git a/FS/FS/nas.pm b/FS/FS/nas.pm
index af5a23a24..c7f245912 100644
--- a/FS/FS/nas.pm
+++ b/FS/FS/nas.pm
@@ -50,6 +50,7 @@ FS::Record. The following fields are currently supported:
=item description - a longer descriptive name
+=item svcnum - the L<FS::svc_broadband> record that 'owns' this device
=back
@@ -94,7 +95,7 @@ sub delete {
) || $self->SUPER::delete;
if ( $error ) {
- $dbh->rollback;
+ $dbh->rollback if $oldAutoCommit;
return $error;
}
@@ -159,6 +160,7 @@ sub check {
|| $self->ut_textn('server')
|| $self->ut_textn('community')
|| $self->ut_text('description')
+ || $self->ut_foreign_keyn('svcnum', 'svc_broadband', 'svcnum')
;
return $error if $error;
diff --git a/FS/FS/part_export/broadband_nas.pm b/FS/FS/part_export/broadband_nas.pm
new file mode 100644
index 000000000..a160c9944
--- /dev/null
+++ b/FS/FS/part_export/broadband_nas.pm
@@ -0,0 +1,145 @@
+package FS::part_export::broadband_nas;
+
+use strict;
+use vars qw(%info $DEBUG);
+use base 'FS::part_export';
+use FS::Record qw(qsearch qsearchs);
+use FS::nas;
+use FS::export_nas;
+use FS::svc_broadband;
+use FS::part_export::sqlradius;
+use Tie::IxHash;
+
+$DEBUG = 0;
+
+my $me = '['.__PACKAGE__.']';
+
+tie my %options, 'Tie::IxHash',
+ '1' => { type => 'title', label => 'Defaults' },
+ default_shortname => { label => 'Short name' },
+ default_secret => { label => 'Shared secret' },
+ default_type => { label => 'Type' },
+ default_ports => { label => 'Ports' },
+ default_server => { label => 'Virtual server' },
+ default_community => { label => 'Community' },
+ '2' => { type => 'title', label => 'Export to' },
+ # default export_nas entries will be inserted at runtime
+;
+
+FS::UID->install_callback(
+ sub {
+ #creating new options based on records in a table,
+ #has to be done after initialization
+ foreach ( FS::part_export::sqlradius->all_sqlradius ) {
+ my $name = 'exportnum' . $_->exportnum;
+ $options{$name} =
+ { type => 'checkbox', label => $_->exportnum . ': ' . $_->label };
+
+ }
+ }
+);
+
+%info = (
+ 'svc' => 'svc_broadband',
+ 'desc' => 'Create a NAS entry in Freeside',
+ 'options' => \%options,
+ 'weight' => 10,
+ 'notes' => <<'END'
+<p>Create an entry in the NAS (RADIUS client) table, inheriting the IP
+address and description of the broadband service. This can be used
+with 'sqlradius' or 'broadband_sqlradius' exports to maintain entries
+in the client table on a RADIUS server.</p>
+<p>Most broadband configurations should not use this, even if they use
+RADIUS for access control.</p>
+END
+);
+
+=item export_insert NEWSVC
+
+=item export_replace NEWSVC OLDSVC
+
+NEWSVC can contain pseudo-field entries for fields in nas. Those changes
+will be applied to the attached NAS record.
+
+=cut
+
+sub export_insert {
+ my $self = shift;
+ my $svc_broadband = shift;
+ my %hash = map { $_ => $svc_broadband->get($_) } FS::nas->fields;
+ my $nas = $self->default_nas(
+ %hash,
+ 'nasname' => $svc_broadband->ip_addr,
+ 'description' => $svc_broadband->description,
+ 'svcnum' => $svc_broadband->svcnum,
+ );
+
+ my $error =
+ $nas->insert()
+ || $nas->process_m2m('link_table' => 'export_nas',
+ 'target_table' => 'part_export',
+ 'params' => { $self->options });
+ die $error if $error;
+ return;
+}
+
+sub export_delete {
+ my $self = shift;
+ my $svc_broadband = shift;
+ my $svcnum = $svc_broadband->svcnum;
+ my $nas = qsearchs('nas', { 'svcnum' => $svcnum });
+ if ( !$nas ) {
+ # we were going to delete it anyway...
+ warn "linked NAS with svcnum $svcnum not found for deletion\n";
+ return;
+ }
+ my $error = $nas->delete; # will clean up export_nas records
+ die $error if $error;
+ return;
+}
+
+sub export_replace {
+ my $self = shift;
+ my ($new_svc, $old_svc) = (shift, shift);
+
+ my $svcnum = $new_svc->svcnum;
+ my $nas = qsearchs('nas', { 'svcnum' => $svcnum });
+ if ( !$nas ) {
+ warn "linked nas with svcnum $svcnum not found for update, creating new\n";
+ # then we should insert it
+ # (this happens if the nas table is wiped out, or if the broadband_nas
+ # export is newly applied to an existing svcpart)
+ return $self->export_insert($new_svc);
+ }
+
+ my %hash = $new_svc->hash;
+ foreach (FS::nas->fields) {
+ $nas->set($_, $hash{$_}) if exists($hash{$_});
+ }
+
+ $nas->nasname($new_svc->ip_addr); # this must always be true
+
+ my $error = $nas->replace;
+ die $error if $error;
+ return;
+}
+
+=item default_nas HASH
+
+Returns a new L<FS::nas> object containing the default values, plus anything
+in HASH.
+
+=cut
+
+sub default_nas {
+ my $self = shift;
+ FS::nas->new({
+ map( { $_ => $self->option("default_$_") }
+ qw(shortname type ports secret server community)
+ ),
+ @_
+ });
+}
+
+
+1;
diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm
index 1d1fa762c..a85fc5cb0 100755
--- a/FS/FS/svc_broadband.pm
+++ b/FS/FS/svc_broadband.pm
@@ -2,6 +2,8 @@ package FS::svc_broadband;
use strict;
use vars qw(@ISA $conf);
+
+use base qw(FS::svc_Radius_Mixin FS::svc_Tower_Mixin FS::svc_Common);
use NetAddr::IP;
use FS::Record qw( qsearchs qsearch dbh );
use FS::svc_Common;
@@ -10,8 +12,6 @@ use FS::addr_block;
use FS::part_svc_router;
use FS::tower_sector;
-@ISA = qw( FS::svc_Radius_Mixin FS::svc_Tower_Mixin FS::svc_Common );
-
$FS::UID::callback{'FS::svc_broadband'} = sub {
$conf = new FS::Conf;
};
@@ -398,11 +398,11 @@ sub check {
if ( $cust_pkg && ! $self->latitude && ! $self->longitude ) {
my $l = $cust_pkg->cust_location_or_main;
if ( $l->ship_latitude && $l->ship_longitude ) {
- $self->latitude = $l->ship_latitude;
- $self->longitude = $l->ship_longitude;
+ $self->latitude( $l->ship_latitude );
+ $self->longitude( $l->ship_longitude );
} elsif ( $l->latitude && $l->longitude ) {
- $self->latitude = $l->latitude;
- $self->longitude = $l->longitude;
+ $self->latitude( $l->latitude );
+ $self->longitude( $l->longitude );
}
}