summaryrefslogtreecommitdiff
path: root/FS/FS/part_export/broadband_nas.pm
blob: d52ccae88c7bb8ae8b842be9069513945a648667 (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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
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,
  'no_machine' => 1,
  '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>The checkboxes at the bottom of this page correspond to RADIUS server
databases that Freeside knows about (i.e. 'sqlradius' or 'broadband_sqlradius'
exports that you have configured).  Check the box for each server that you 
want the NAS entries to be exported to.  Do not create multiple broadband_nas
exports for the same service definition; this will fail.</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 = (
    'nasname'     => $svc_broadband->ip_addr,
    'description' => $svc_broadband->description,
    'svcnum'      => $svc_broadband->svcnum,
  );
  foreach (FS::nas->fields) {
    if ( length($svc_broadband->get($_)) ) {
      $hash{$_} = $svc_broadband->get($_);
    }
  }
  # if there's somehow a completely identical NAS in the table already,
  # use that one.
  my $nas = qsearchs('nas', \%hash);
  my $error;
  if ($nas) {
    # propagate the export message
    foreach my $part_export ($nas->part_export) {
      $error = $part_export->export_nas_insert($nas);
      die $error if $error;
    }
  } else {
    $nas = $self->default_nas( %hash );
    $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;