diff options
| -rw-r--r-- | FS/FS/Schema.pm | 1 | ||||
| -rw-r--r-- | FS/FS/nas.pm | 4 | ||||
| -rw-r--r-- | FS/FS/part_export/broadband_nas.pm | 145 | ||||
| -rwxr-xr-x | FS/FS/svc_broadband.pm | 12 | ||||
| -rw-r--r-- | httemplate/browse/nas.html | 10 | ||||
| -rw-r--r-- | httemplate/edit/nas.html | 4 | ||||
| -rw-r--r-- | httemplate/edit/part_export.cgi | 15 | ||||
| -rw-r--r-- | httemplate/edit/process/svc_broadband.cgi | 2 | ||||
| -rw-r--r-- | httemplate/edit/svc_broadband.cgi | 58 | ||||
| -rw-r--r-- | httemplate/view/svc_broadband.cgi | 22 | 
10 files changed, 253 insertions, 20 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 );      }    } diff --git a/httemplate/browse/nas.html b/httemplate/browse/nas.html index c9d57e8ed..5ce729b65 100644 --- a/httemplate/browse/nas.html +++ b/httemplate/browse/nas.html @@ -28,6 +28,14 @@  die "access denied"    unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); -my $link = [ $p.'edit/nas.html?', 'nasnum' ]; +my $link = sub { +  my $nas = shift; +  if ( $nas->svcnum ) { +    return [ $p.'view/svc_broadband.cgi?', 'svcnum' ]; +  } +  else { +    return [ $p.'edit/nas.html?', 'nasnum' ]; +  } +};  </%init> diff --git a/httemplate/edit/nas.html b/httemplate/edit/nas.html index 9d9b8e9fd..2e66fc3be 100644 --- a/httemplate/edit/nas.html +++ b/httemplate/edit/nas.html @@ -48,7 +48,9 @@ sub html_bottom {              'source_obj'    => $nas,              'link_table'    => 'export_nas',              'target_table'  => 'part_export', -            'hashref'       => { 'exporttype' => 'sqlradius' }, +            'hashref'       => { 'exporttype' =>  +                                  { op => 'LIKE', value => '%sqlradius' } +                                },              'name_callback' => sub { $_[0]->label },              'default'       => 'yes',              'target_link'   => $p.'edit/part_export.cgi?', diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi index 9a0e0bd29..1450ac3b3 100644 --- a/httemplate/edit/part_export.cgi +++ b/httemplate/edit/part_export.cgi @@ -51,8 +51,12 @@ $action ||= $part_export->exportnum ? 'Edit' : 'Add';  #my $exports = FS::part_export::export_info($svcdb);  my $exports = FS::part_export::export_info(); -my %layers = map { $_ => "$_ - ". $exports->{$_}{desc} } keys %$exports; -$layers{''}=''; +tie my %layers, 'Tie::IxHash', +  '' => '', +  map { $_ => "$_ - ". $exports->{$_}{desc} }  +  sort { $a cmp $b } +  keys %$exports; +;  my $widget = new HTML::Widgets::SelectLayers(    'selected_layer' => $part_export->exporttype, @@ -83,6 +87,13 @@ my $widget = new HTML::Widgets::SelectLayers(                        ? $optinfo->{default}                        : ''                      ); +      if ( $type eq 'title' ) { +        $html .= qq!<TR><TH COLSPAN=1 ALIGN="right"><FONT SIZE="+1">! . +                 $label . +                 '</FONT></TH></TR>'; +        next; +      } +        # 'freeform': disables table formatting of options.  Instead, each         # option can define "before" and "after" strings which are inserted         # around the selector. diff --git a/httemplate/edit/process/svc_broadband.cgi b/httemplate/edit/process/svc_broadband.cgi index 36c64d11a..4184f5fa6 100644 --- a/httemplate/edit/process/svc_broadband.cgi +++ b/httemplate/edit/process/svc_broadband.cgi @@ -1,6 +1,6 @@  <& elements/svc_Common.html,    table       => 'svc_broadband', -  fields      => [ fields('svc_broadband'), 'usergroup' ], +  fields      => [ fields('svc_broadband'), fields('nas'), 'usergroup' ],    precheck_callback => \&precheck,  &>  <%init> diff --git a/httemplate/edit/svc_broadband.cgi b/httemplate/edit/svc_broadband.cgi index ad4d6046d..b9e2fd2d9 100644 --- a/httemplate/edit/svc_broadband.cgi +++ b/httemplate/edit/svc_broadband.cgi @@ -3,7 +3,9 @@       'name'                 => 'broadband service',       'table'                => 'svc_broadband',       'fields'               => \@fields,  -     'field_callback'       => $callback, +     'field_callback'       => $field_callback, +     'svc_new_callback'     => $svc_edit_callback, +     'svc_edit_callback'    => $svc_edit_callback,       'dummy'                => $cgi->query_string,       'onsubmit'             => 'validate_coords',       'html_foot'            => $js, @@ -113,17 +115,57 @@ if ( $conf->exists('svc_broadband-radius') ) {    }  } -  my $fixedblock = ''; -my $callback = sub { -  my ($cgi, $object, $fieldref) = @_; +my $part_svc; + +my $svc_edit_callback = sub { +  my ($cgi, $svc_x, $part_svc_x, $cust_pkg, $fields, $opt) = @_; + +  $part_svc = $part_svc_x; #for field_callback to use -  my $svcpart = $object->svcnum ? $object->cust_svc->svcpart -                                : $cgi->param('svcpart'); +  $opt->{'labels'}{'block_label'} = 'Block'; -  my $part_svc = qsearchs( 'part_svc', { svcpart => $svcpart } ); -  die "No part_svc entry!" unless $part_svc; +  my ($nas_export) = $part_svc->part_export('broadband_nas'); +  #can we assume there's only one of these per part_svc? +  if ( $nas_export ) { +    my $nas; +    if ( $svc_x->svcnum ) { +      $nas = qsearchs('nas', { 'svcnum' => $svc_x->svcnum }); +    } +    $nas ||= $nas_export->default_nas; +    $svc_x->set($_, $nas->$_) foreach fields('nas'); + +    # duplicates the fields in httemplate/edit/nas.html (mostly) +    push @$fields, +      { type  => 'tablebreak-tr-title',  +        #value => 'Attached NAS', +        value => $nas_export->exportname, +        colspan => 2, +      }, +      { field=>'nasnum', type=>'hidden', }, +      { field=>'shortname', size=>16, maxlength=>32 }, +      { field=>'secret', size=>40, maxlength=>60, required=>1 }, +      { field=>'type', type=>'select', +        options=>[qw( cisco computone livingston max40xx multitech netserver +        pathras patton portslave tc usrhiper other )], +      }, +      { field=>'ports', size=>5 }, +      { field=>'server', size=>40, maxlength=>64 }, +      { field=>'community', size=>40, maxlength=>50 }, +    ; + +    $opt->{'labels'}{'shortname'} = 'Short name'; +    $opt->{'labels'}{'secret'}    = 'Shared secret'; +    $opt->{'labels'}{'type'}      = 'Type'; +    $opt->{'labels'}{'ports'}     = 'Ports'; +    $opt->{'labels'}{'server'}    = 'Server'; +    $opt->{'labels'}{'community'} = 'Community'; +  } +}; + +my $field_callback = sub { +  my ($cgi, $object, $fieldref) = @_;    my $columndef = $part_svc->part_svc_column($fieldref->{'field'});    if ($columndef->columnflag eq 'F') { diff --git a/httemplate/view/svc_broadband.cgi b/httemplate/view/svc_broadband.cgi index de39f6ae4..2e93d42fd 100644 --- a/httemplate/view/svc_broadband.cgi +++ b/httemplate/view/svc_broadband.cgi @@ -2,6 +2,7 @@    table   => 'svc_broadband',    labels  => \%labels,    fields  => \@fields, +  svc_callback => \&svc_callback,  &>  <%init> @@ -97,4 +98,25 @@ sub coordinates {      include('/elements/coord-links.html', $s->latitude, $s->longitude, $d);  } +sub svc_callback { +  # trying to move to the callback style +  my ($cgi, $svc_x, $part_svc, $cust_pkg, $fields, $opt) = @_; +  # again, we assume at most one of these exports per part_svc +  my ($nas_export) = $part_svc->part_export('broadband_nas'); +  if ( $nas_export ) { +    my $nas = qsearchs('nas', { 'svcnum' => $svc_x->svcnum }); +    if ( $nas ) { +      $svc_x->set($_, $nas->$_) foreach (fields('nas')); +      push @$fields, qw(shortname secret type ports server community); +      $opt->{'labels'}{'shortname'}  = 'Short name'; +      $opt->{'labels'}{'secret'}     = 'Shared secret'; +      $opt->{'labels'}{'type'}       = 'Type'; +      $opt->{'labels'}{'ports'}      = 'Ports'; +      $opt->{'labels'}{'server'}     = 'Server'; +      $opt->{'labels'}{'community'}  = 'Community'; +    } #if $nas +  } #$nas_export +}; + +  </%init> | 
