From 1ad547a47f16b4230762e752fbe48d460ed997e1 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 18 Sep 2012 02:18:04 -0700 Subject: [PATCH] export host selection per service, RT#17914 --- FS/FS.pm | 4 + FS/FS/Record.pm | 21 ++- FS/FS/Schema.pm | 31 ++++- FS/FS/part_export.pm | 160 +++++++++++++++++++++- FS/FS/part_export/acct_google.pm | 10 +- FS/FS/part_export/acct_http.pm | 1 + FS/FS/part_export/acct_plesk.pm | 8 +- FS/FS/part_export/acct_sql.pm | 12 +- FS/FS/part_export/acct_sql_status.pm | 1 + FS/FS/part_export/acct_xmlrpc.pm | 1 + FS/FS/part_export/amazon_ec2.pm | 1 + FS/FS/part_export/artera_turbo.pm | 1 + FS/FS/part_export/broadband_http.pm | 1 + FS/FS/part_export/broadband_nas.pm | 1 + FS/FS/part_export/broadband_shellcommands.pm | 1 + FS/FS/part_export/broadband_snmp.pm | 1 + FS/FS/part_export/broadband_sql.pm | 1 + FS/FS/part_export/broadband_sqlradius.pm | 1 + FS/FS/part_export/communigate_pro.pm | 1 + FS/FS/part_export/communigate_pro_singledomain.pm | 1 + FS/FS/part_export/cp.pm | 1 + FS/FS/part_export/cpanel.pm | 2 + FS/FS/part_export/cust_http.pm | 1 + FS/FS/part_export/cyrus.pm | 2 + FS/FS/part_export/dashcs_e911.pm | 1 + FS/FS/part_export/domain_sql.pm | 1 + FS/FS/part_export/everyone_net.pm | 2 + FS/FS/part_export/ez_prepaid.pm | 1 + FS/FS/part_export/forward_sql.pm | 1 + FS/FS/part_export/globalpops_voip.pm | 1 + FS/FS/part_export/http.pm | 1 + FS/FS/part_export/http_status.pm | 1 + FS/FS/part_export/ikano.pm | 1 + FS/FS/part_export/indosoft.pm | 1 + FS/FS/part_export/infostreet.pm | 1 + FS/FS/part_export/internal_diddb.pm | 1 + FS/FS/part_export/ldap.pm | 1 + FS/FS/part_export/netsapiens.pm | 9 +- FS/FS/part_export/null.pm | 1 + FS/FS/part_export/phone_shellcommands.pm | 1 + FS/FS/part_export/phone_sqlopensips.pm | 10 +- FS/FS/part_export/phone_sqlradius.pm | 9 +- FS/FS/part_export/postfix.pm | 1 + FS/FS/part_export/prizm.pm | 11 +- FS/FS/part_export/radiator.pm | 2 + FS/FS/part_export/router.pm | 1 + FS/FS/part_export/rt_ticket.pm | 1 + FS/FS/part_export/send_email.pm | 1 + FS/FS/part_export/shellcommands.pm | 30 +--- FS/FS/part_export/sqlmail.pm | 1 + FS/FS/part_export/sqlradius.pm | 1 + FS/FS/part_export/textradius.pm | 1 + FS/FS/part_export/trango.pm | 1 + FS/FS/part_export/vitelity.pm | 1 + FS/FS/part_export/vpopmail.pm | 1 + FS/FS/part_export/www_plesk.pm | 9 +- FS/FS/part_export/www_shellcommands.pm | 1 + FS/FS/part_export_machine.pm | 155 +++++++++++++++++++++ FS/FS/part_svc.pm | 2 +- FS/FS/svc_export_machine.pm | 111 +++++++++++++++ FS/MANIFEST | 4 + FS/t/part_export_machine.t | 5 + FS/t/svc_export_machine.t | 5 + httemplate/browse/part_export.cgi | 17 ++- httemplate/edit/part_export.cgi | 74 ++++++++-- httemplate/edit/process/part_export.cgi | 5 + 66 files changed, 668 insertions(+), 82 deletions(-) create mode 100644 FS/FS/part_export_machine.pm create mode 100644 FS/FS/svc_export_machine.pm create mode 100644 FS/t/part_export_machine.t create mode 100644 FS/t/svc_export_machine.t diff --git a/FS/FS.pm b/FS/FS.pm index 5ab3f71e5..2d963b54f 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -284,6 +284,10 @@ L - Agent payment gateway class L - Service class +L - Export hostname choice class + +L - Customer export hostname class + L - Customer package class L - Customer package option class diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 0ac269f4c..ca68c3596 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -2421,10 +2421,9 @@ sub ut_coordn { } - =item ut_domain COLUMN -Check/untaint host and domain names. +Check/untaint host and domain names. May not be null. =cut @@ -2432,11 +2431,27 @@ sub ut_domain { my( $self, $field ) = @_; #$self->getfield($field) =~/^(\w+\.)*\w+$/ $self->getfield($field) =~/^(([\w\-]+\.)*\w+)$/ - or return "Illegal (domain) $field: ". $self->getfield($field); + or return "Illegal (hostname) $field: ". $self->getfield($field); $self->setfield($field,$1); ''; } +=item ut_domainn COLUMN + +Check/untaint host and domain names. May be null. + +=cut + +sub ut_domainn { + my( $self, $field ) = @_; + if ( $self->getfield($field) =~ /^()$/ ) { + $self->setfield($field,''); + ''; + } else { + $self->ut_domain($field); + } +} + =item ut_name COLUMN Check/untaint proper names; allows alphanumerics, spaces and the following diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 4ef2a6352..6e3956a83 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1890,6 +1890,29 @@ sub tables_hashref { 'index' => [ [ 'svcnum' ], [ 'optionname' ] ], }, + 'svc_export_machine' => { + 'columns' => [ + 'svcexportmachinenum', 'serial', '', '', '', '', + 'svcnum', 'int', '', '', '', '', + 'machinenum', 'int', '', '', '', '', + ], + 'primary_key' => 'svcexportmachinenum', + 'unique' => [], + 'index' => [], + }, + + 'part_export_machine' => { + 'columns' => [ + 'machinenum', 'serial', '', '', '', '', + 'exportnum', 'int', '', '', '', '', + 'machine', 'varchar', 'NULL', $char_d, '', '', + 'disabled', 'char', 'NULL', 1, '', '', + ], + 'primary_key' => 'machinenum', + 'unique' => [ [ 'exportnum', 'machine' ] ], + 'index' => [ [ 'exportnum' ] ], + }, + 'part_pkg' => { 'columns' => [ 'pkgpart', 'serial', '', '', '', '', @@ -2623,11 +2646,11 @@ sub tables_hashref { 'part_export' => { 'columns' => [ - 'exportnum', 'serial', '', '', '', '', + 'exportnum', 'serial', '', '', '', '', 'exportname', 'varchar', 'NULL', $char_d, '', '', - 'machine', 'varchar', '', $char_d, '', '', - 'exporttype', 'varchar', '', $char_d, '', '', - 'nodomain', 'char', 'NULL', 1, '', '', + 'machine', 'varchar', 'NULL', $char_d, '', '', + 'exporttype', 'varchar', '', $char_d, '', '', + 'nodomain', 'char', 'NULL', 1, '', '', ], 'primary_key' => 'exportnum', 'unique' => [], diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index 45773e097..97394af18 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -4,10 +4,11 @@ use strict; use vars qw( @ISA @EXPORT_OK $DEBUG %exports ); use Exporter; use Tie::IxHash; -use base qw( FS::option_Common FS::m2m_Common ); # m2m for 'export_nas' +use base qw( FS::option_Common FS::m2m_Common ); use FS::Record qw( qsearch qsearchs dbh ); use FS::part_svc; use FS::part_export_option; +use FS::part_export_machine; use FS::export_svc; #for export modules, though they should probably just use it themselves @@ -108,6 +109,50 @@ otherwise returns false. If a hash reference of options is supplied, part_export_option records are created (see L). +=cut + +sub insert { + my $self = shift; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $self->SUPER::insert(@_); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + #kinda false laziness with process_m2name + my @machines = map { $_ =~ s/^\s+//; $_ =~ s/\s+$//; $_ } + grep /\S/, + split /[\n\r]{1,2}/, + $self->part_export_machine_textarea; + + foreach my $machine ( @machines ) { + + my $part_export_machine = new FS::part_export_machine { + 'exportnum' => $self->exportnum, + 'machine' => $machine, + }; + $error = $part_export_machine->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; +} + =item delete Delete this record from the database. @@ -117,13 +162,13 @@ Delete this record from the database. #foreign keys would make this much less tedious... grr dumb mysql sub delete { my $self = shift; + local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; local $SIG{QUIT} = 'IGNORE'; local $SIG{TERM} = 'IGNORE'; local $SIG{TSTP} = 'IGNORE'; local $SIG{PIPE} = 'IGNORE'; - my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; @@ -147,10 +192,103 @@ sub delete { } } - $dbh->commit or die $dbh->errstr if $oldAutoCommit; + foreach my $part_export_machine ( $self->part_export_machine ) { + my $error = $part_export_machine->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; +} + +=item replace [ OLD_RECORD ] [ HASHREF | OPTION => VALUE ... ] + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +If a list or hash reference of options is supplied, option records are created +or modified. + +=cut +sub replace { + my $self = shift; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $self->SUPER::replace(@_); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + if ( $self->part_export_machine_textarea ) { + + my %part_export_machine = map { $_->machine => $_ } + $self->part_export_machine; + + my @machines = map { $_ =~ s/^\s+//; $_ =~ s/\s+$//; $_ } + grep /\S/, + split /[\n\r]{1,2}/, + $self->part_export_machine_textarea; + + foreach my $machine ( @machines ) { + + if ( $part_export_machine{$machine} ) { + + if ( $part_export_machine{$machine}->disabled eq 'Y' ) { + $part_export_machine{$machine}->disabled(''); + $error = $part_export_machine{$machine}->replace; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + delete $part_export_machine{$machine}; #so we don't disable it below + + } else { + + my $part_export_machine = new FS::part_export_machine { + 'exportnum' => $self->exportnum, + 'machine' => $machine + }; + $error = $part_export_machine->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + } + + } + + + foreach my $part_export_machine ( values %part_export_machine ) { + $part_export_machine->disabled('Y'); + $error = $part_export_machine->replace; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; } =item check @@ -166,7 +304,7 @@ sub check { my $error = $self->ut_numbern('exportnum') || $self->ut_textn('exportname') - || $self->ut_domain('machine') + || $self->ut_domainn('machine') || $self->ut_alpha('exporttype') ; return $error if $error; @@ -233,6 +371,20 @@ sub cust_svc { $self->export_svc; } +=item part_export_machine + +Returns all machines as FS::part_export_machine objects (see +L). + +=cut + +sub part_export_machine { + my $self = shift; + map { $_ } #behavior of sort undefined in scalar context + sort { $a->machine cmp $b->machine } + qsearch('part_export_machine', { 'exportnum' => $self->exportnum } ); +} + =item export_svc Returns a list of associated FS::export_svc records. diff --git a/FS/FS/part_export/acct_google.pm b/FS/FS/part_export/acct_google.pm index afc45db81..d153728e9 100644 --- a/FS/FS/part_export/acct_google.pm +++ b/FS/FS/part_export/acct_google.pm @@ -16,10 +16,12 @@ tie my %options, 'Tie::IxHash', # admin logins. %info = ( - 'svc' => 'svc_acct', - 'desc' => 'Google hosted mail', - 'options' => \%options, - 'nodomain' => 'Y', + 'svc' => 'svc_acct', + 'desc' => 'Google hosted mail', + 'options' => \%options, + 'nodomain' => 'Y', + 'no_machine' => 1, + 'default_svc_class' => 'Email', 'notes' => <<'END' Export accounts to the Google Provisioning API. Requires REST::Google::Apps::Provisioning from CPAN. diff --git a/FS/FS/part_export/acct_http.pm b/FS/FS/part_export/acct_http.pm index b4c64ac62..23df7b37d 100644 --- a/FS/FS/part_export/acct_http.pm +++ b/FS/FS/part_export/acct_http.pm @@ -51,6 +51,7 @@ tie %options, 'Tie::IxHash', 'svc' => 'svc_acct', 'desc' => 'Send an HTTP or HTTPS GET or POST request, for accounts.', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Send an HTTP or HTTPS GET or POST to the specified URL on account addition, modification and deletion. For HTTPS support, diff --git a/FS/FS/part_export/acct_plesk.pm b/FS/FS/part_export/acct_plesk.pm index d8d70a30e..50b6faebf 100644 --- a/FS/FS/part_export/acct_plesk.pm +++ b/FS/FS/part_export/acct_plesk.pm @@ -15,9 +15,11 @@ tie my %options, 'Tie::IxHash', ; %info = ( - 'svc' => 'svc_acct', - 'desc' => 'Real-time export to Plesk managed mail service', - 'options'=> \%options, + 'svc' => 'svc_acct', + 'desc' => 'Real-time export to Plesk managed mail service', + 'options' => \%options, + 'no_machine' => 1, + 'default_svc_class' => 'Email', 'notes' => <<'END' Real-time export to Plesk managed server. diff --git a/FS/FS/part_export/acct_sql.pm b/FS/FS/part_export/acct_sql.pm index ffe39caa5..8163f2017 100644 --- a/FS/FS/part_export/acct_sql.pm +++ b/FS/FS/part_export/acct_sql.pm @@ -60,11 +60,13 @@ my $postfix_native_mailbox_map = keys %postfix_native_mailbox_map ); %info = ( - 'svc' => 'svc_acct', - 'desc' => 'Real-time export of accounts to SQL databases '. - '(vpopmail, Postfix+Courier IMAP, others?)', - 'options' => \%options, - 'nodomain' => '', + 'svc' => 'svc_acct', + 'desc' => 'Real-time export of accounts to SQL databases '. + '(vpopmail, Postfix+Courier IMAP, others?)', + 'options' => \%options, + 'nodomain' => '', + 'no_machine' => 1, + 'default_svc_class' => 'Email', 'notes' => < 'Mailbox status information from SQL', 'options' => \%options, 'nodomain' => '', + 'no_machine' => 1, 'notes' => < 'svc_acct', 'desc' => 'Configurable provisioning of accounts via the XML-RPC protocol', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END', Configurable, real-time export of accounts via the XML-RPC protocol.

diff --git a/FS/FS/part_export/amazon_ec2.pm b/FS/FS/part_export/amazon_ec2.pm index 0e65ca00c..06e2c238e 100644 --- a/FS/FS/part_export/amazon_ec2.pm +++ b/FS/FS/part_export/amazon_ec2.pm @@ -20,6 +20,7 @@ tie my %options, 'Tie::IxHash', 'desc' => 'Export to Amazon EC2', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Create instances in the Amazon EC2 (Elastic compute cloud). Install Net::Amazon::EC2 perl module. Advisable to set svc_external-skip_manual config diff --git a/FS/FS/part_export/artera_turbo.pm b/FS/FS/part_export/artera_turbo.pm index c006db9cd..e22bbf2af 100644 --- a/FS/FS/part_export/artera_turbo.pm +++ b/FS/FS/part_export/artera_turbo.pm @@ -37,6 +37,7 @@ tie my %options, 'Tie::IxHash', 'Real-time export to Artera Turbo Reseller API', 'options' => \%options, #'nodomain' => 'Y', + 'no_machine' => 1, 'notes' => <<'END' Real-time export to Artera Turbo Reseller API. Requires installation of diff --git a/FS/FS/part_export/broadband_http.pm b/FS/FS/part_export/broadband_http.pm index 9edfee5d3..c1ed7fca6 100644 --- a/FS/FS/part_export/broadband_http.pm +++ b/FS/FS/part_export/broadband_http.pm @@ -45,6 +45,7 @@ tie %options, 'Tie::IxHash', 'svc' => 'svc_broadband', 'desc' => 'Send an HTTP or HTTPS GET or POST request, for accounts.', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END'

Send an HTTP or HTTPS GET or POST to the specified URL on account addition, modification and deletion. For HTTPS support, diff --git a/FS/FS/part_export/broadband_nas.pm b/FS/FS/part_export/broadband_nas.pm index a160c9944..5a8ffac3b 100644 --- a/FS/FS/part_export/broadband_nas.pm +++ b/FS/FS/part_export/broadband_nas.pm @@ -43,6 +43,7 @@ FS::UID->install_callback( 'svc' => 'svc_broadband', 'desc' => 'Create a NAS entry in Freeside', 'options' => \%options, + 'no_machine' => 1, 'weight' => 10, 'notes' => <<'END'

Create an entry in the NAS (RADIUS client) table, inheriting the IP diff --git a/FS/FS/part_export/broadband_shellcommands.pm b/FS/FS/part_export/broadband_shellcommands.pm index c7f0fbb33..cf9c36c8f 100644 --- a/FS/FS/part_export/broadband_shellcommands.pm +++ b/FS/FS/part_export/broadband_shellcommands.pm @@ -107,3 +107,4 @@ sub ssh_cmd { #subroutine, not method ''; } +1; diff --git a/FS/FS/part_export/broadband_snmp.pm b/FS/FS/part_export/broadband_snmp.pm index cb1740efc..44b4dbabb 100644 --- a/FS/FS/part_export/broadband_snmp.pm +++ b/FS/FS/part_export/broadband_snmp.pm @@ -52,6 +52,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_broadband', 'desc' => 'Send SNMP requests to the service IP address', 'options' => \%options, + 'no_machine' => 1, 'weight' => 10, 'notes' => <<'END' Send one or more SNMP SET requests to the IP address registered to the service. diff --git a/FS/FS/part_export/broadband_sql.pm b/FS/FS/part_export/broadband_sql.pm index 697d3cdac..4f526c805 100644 --- a/FS/FS/part_export/broadband_sql.pm +++ b/FS/FS/part_export/broadband_sql.pm @@ -24,6 +24,7 @@ tie my %options, 'Tie::IxHash', 'desc' => 'Real-time export of broadband services to SQL databases ', 'options' => \%options, 'nodomain' => '', + 'no_machine' => 1, 'notes' => < 'svc_broadband', 'desc' => 'Real-time export to SQL-backed RADIUS (such as FreeRadius) for broadband services', 'options' => \%options, + 'no_machine' => 1, 'nas' => 'Y', 'notes' => <radcheck, radreply, and usergroup diff --git a/FS/FS/part_export/communigate_pro.pm b/FS/FS/part_export/communigate_pro.pm index a3ec5e0be..8b66225d2 100644 --- a/FS/FS/part_export/communigate_pro.pm +++ b/FS/FS/part_export/communigate_pro.pm @@ -36,6 +36,7 @@ tie %options, 'Tie::IxHash', 'svc' => [qw( svc_acct svc_domain svc_forward svc_mailinglist )], 'desc' => 'Real-time export of accounts, domains, mail forwards and mailing lists to a CommuniGate Pro mail server', 'options' => \%options, + 'default_svc_class' => 'Email', 'notes' => <<'END' Real time export of accounts, domains, mail forwards and mailing lists to a CommuniGate Pro diff --git a/FS/FS/part_export/communigate_pro_singledomain.pm b/FS/FS/part_export/communigate_pro_singledomain.pm index e25043fbb..cecea2826 100644 --- a/FS/FS/part_export/communigate_pro_singledomain.pm +++ b/FS/FS/part_export/communigate_pro_singledomain.pm @@ -16,6 +16,7 @@ tie my %options, 'Tie::IxHash', %FS::part_export::communigate_pro::options, 'Real-time export to a CommuniGate Pro mail server, one domain only', 'options' => \%options, 'nodomain' => 'Y', + 'default_svc_class' => 'Email', 'notes' => <<'END' Real time export to a CommuniGate Pro diff --git a/FS/FS/part_export/cp.pm b/FS/FS/part_export/cp.pm index 96fa43710..2ae97e12d 100644 --- a/FS/FS/part_export/cp.pm +++ b/FS/FS/part_export/cp.pm @@ -18,6 +18,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_acct', 'desc' => 'Real-time export to Critical Path Account Provisioning Protocol', 'options'=> \%options, + 'default_svc_class' => 'Email', 'notes' => <<'END' Real-time export to Critial Path Account Provisioning Protocol. diff --git a/FS/FS/part_export/cpanel.pm b/FS/FS/part_export/cpanel.pm index 0ad00df01..6c61e3d2b 100644 --- a/FS/FS/part_export/cpanel.pm +++ b/FS/FS/part_export/cpanel.pm @@ -190,3 +190,5 @@ sub cpanel_connect { $whm; } + +1; diff --git a/FS/FS/part_export/cust_http.pm b/FS/FS/part_export/cust_http.pm index e8b677be2..e834f93ea 100644 --- a/FS/FS/part_export/cust_http.pm +++ b/FS/FS/part_export/cust_http.pm @@ -55,6 +55,7 @@ tie %options, 'Tie::IxHash', 'svc' => 'cust_main', 'desc' => 'Send an HTTP or HTTPS GET or POST request, for customers.', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Send an HTTP or HTTPS GET or POST to the specified URL on customer addition, modification and deletion. For HTTPS support, diff --git a/FS/FS/part_export/cyrus.pm b/FS/FS/part_export/cyrus.pm index 84c9e5a30..246d5b3dc 100644 --- a/FS/FS/part_export/cyrus.pm +++ b/FS/FS/part_export/cyrus.pm @@ -17,6 +17,8 @@ tie my %options, 'Tie::IxHash', 'desc' => 'Real-time export to Cyrus IMAP server', 'options' => \%options, 'nodomain' => 'Y', + 'no_machine' => 1, #de facto... but "server" option should move to it + 'default_svc_class' => 'Email', 'notes' => <<'END' Integration with Cyrus IMAP Server. diff --git a/FS/FS/part_export/dashcs_e911.pm b/FS/FS/part_export/dashcs_e911.pm index 320d0a67b..2717233cf 100644 --- a/FS/FS/part_export/dashcs_e911.pm +++ b/FS/FS/part_export/dashcs_e911.pm @@ -20,6 +20,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_phone', 'desc' => 'Provision e911 services via Dash Carrier Services', 'notes' => 'Provision e911 services via Dash Carrier Services', + 'no_machine' => 1, 'options' => \%options, ); diff --git a/FS/FS/part_export/domain_sql.pm b/FS/FS/part_export/domain_sql.pm index 0749fec09..ff0d949f1 100644 --- a/FS/FS/part_export/domain_sql.pm +++ b/FS/FS/part_export/domain_sql.pm @@ -26,6 +26,7 @@ my $postfix_transport_static = 'desc' => 'Real time export of domains to SQL databases '. '(postfix, others?)', 'options' => \%options, + 'no_machine' => 1, 'notes' => < 'svc_acct', 'desc' => 'Real-time export to Everyone.net outsourced mail service', 'options'=> \%options, + 'no_machine' => 1, + 'default_svc_class' => 'Email', 'notes' => <<'END' Real-time export to Everyone.net via the XRC Remote API. diff --git a/FS/FS/part_export/ez_prepaid.pm b/FS/FS/part_export/ez_prepaid.pm index d171eb135..9f454df54 100644 --- a/FS/FS/part_export/ez_prepaid.pm +++ b/FS/FS/part_export/ez_prepaid.pm @@ -34,6 +34,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_external', 'desc' => 'Purchase EZ-Prepaid PIN', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END'

Export to the EZ-Prepaid PIN purchase service. If the purchase is allowed, the PIN will be stored as svc_external.id.

diff --git a/FS/FS/part_export/forward_sql.pm b/FS/FS/part_export/forward_sql.pm index 563efcc44..eb4137801 100644 --- a/FS/FS/part_export/forward_sql.pm +++ b/FS/FS/part_export/forward_sql.pm @@ -10,6 +10,7 @@ use FS::Record; 'desc' => 'Real-time export of forwards to SQL databases ', #.' (vpopmail, Postfix+Courier IMAP, others?)', 'options' => __PACKAGE__->sql_options, + 'no_machine' => 1, 'notes' => < 'svc_phone', 'desc' => 'Provision phone numbers to VoIP Innovations (formerly GlobalPOPs VoIP)', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Requires installation of Net::GlobalPOPs::MediaServicesAPI diff --git a/FS/FS/part_export/http.pm b/FS/FS/part_export/http.pm index 3749224ff..c35c89f12 100644 --- a/FS/FS/part_export/http.pm +++ b/FS/FS/part_export/http.pm @@ -43,6 +43,7 @@ tie %options, 'Tie::IxHash', 'svc' => 'svc_domain', 'desc' => 'Send an HTTP or HTTPS GET or POST request', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Send an HTTP or HTTPS GET or POST to the specified URL. For HTTPS support, Crypt::SSLeay diff --git a/FS/FS/part_export/http_status.pm b/FS/FS/part_export/http_status.pm index 5342106b4..6fbd3fbe6 100644 --- a/FS/FS/part_export/http_status.pm +++ b/FS/FS/part_export/http_status.pm @@ -17,6 +17,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_dsl', 'desc' => 'Retrieve status information via HTTP or HTTPS', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Fields from the service can be substituted in the URL as $field. END diff --git a/FS/FS/part_export/ikano.pm b/FS/FS/part_export/ikano.pm index eedc9d0ac..23917bf9e 100644 --- a/FS/FS/part_export/ikano.pm +++ b/FS/FS/part_export/ikano.pm @@ -31,6 +31,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_dsl', 'desc' => 'Provision DSL to Ikano', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Requires installation of Net::Ikano from CPAN. diff --git a/FS/FS/part_export/indosoft.pm b/FS/FS/part_export/indosoft.pm index b5734019b..02ae5efc5 100644 --- a/FS/FS/part_export/indosoft.pm +++ b/FS/FS/part_export/indosoft.pm @@ -17,6 +17,7 @@ tie my %options, 'Tie::IxHash', 'desc' => 'Export conferences to the Indosoft Conference Bridge', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Export conferences to the Indosoft conference bridge. Net::Indosoft::Voicebridge is required. diff --git a/FS/FS/part_export/infostreet.pm b/FS/FS/part_export/infostreet.pm index ef16c7c54..51f57605a 100644 --- a/FS/FS/part_export/infostreet.pm +++ b/FS/FS/part_export/infostreet.pm @@ -19,6 +19,7 @@ tie my %options, 'Tie::IxHash', 'desc' => 'Real-time export to InfoStreet streetSmartAPI', 'options' => \%options, 'nodomain' => 'Y', + 'no_machine' => 1, 'notes' => <<'END' Real-time export to InfoStreet streetSmartAPI. diff --git a/FS/FS/part_export/internal_diddb.pm b/FS/FS/part_export/internal_diddb.pm index a94e43e28..b51f63173 100644 --- a/FS/FS/part_export/internal_diddb.pm +++ b/FS/FS/part_export/internal_diddb.pm @@ -17,6 +17,7 @@ tie my %options, 'Tie::IxHash', 'desc' => 'Provision phone numbers from the internal DID database', 'notes' => 'After adding the export, DIDs may be imported under Tools -> Importing -> Import phone numbers (DIDs)', 'options' => \%options, + 'no_machine' => 1, ); sub rebless { shift; } diff --git a/FS/FS/part_export/ldap.pm b/FS/FS/part_export/ldap.pm index 838532021..fe634d230 100644 --- a/FS/FS/part_export/ldap.pm +++ b/FS/FS/part_export/ldap.pm @@ -41,6 +41,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_acct', 'desc' => 'Real-time export to LDAP', 'options' => \%options, + 'default_svc_class' => 'Email', 'notes' => <<'END' Real-time export to arbitrary LDAP attributes. Requires installation of Net::LDAP from CPAN. diff --git a/FS/FS/part_export/netsapiens.pm b/FS/FS/part_export/netsapiens.pm index 6e2ee8ae3..2e37d04b6 100644 --- a/FS/FS/part_export/netsapiens.pm +++ b/FS/FS/part_export/netsapiens.pm @@ -72,10 +72,11 @@ tie my %options, 'Tie::IxHash', ; %info = ( - 'svc' => [ 'svc_phone', ], # 'part_device', - 'desc' => 'Provision phone numbers to NetSapiens', - 'options' => \%options, - 'notes' => <<'END' + 'svc' => [ 'svc_phone', ], # 'part_device', + 'desc' => 'Provision phone numbers to NetSapiens', + 'options' => \%options, + 'no_machine' => 1, + 'notes' => <<'END' Requires installation of REST::Client from CPAN. diff --git a/FS/FS/part_export/null.pm b/FS/FS/part_export/null.pm index 0145af3a4..3a764883c 100644 --- a/FS/FS/part_export/null.pm +++ b/FS/FS/part_export/null.pm @@ -11,3 +11,4 @@ sub _export_insert {} sub _export_replace {} sub _export_delete {} +1; diff --git a/FS/FS/part_export/phone_shellcommands.pm b/FS/FS/part_export/phone_shellcommands.pm index 040af27a7..5c1ae0153 100644 --- a/FS/FS/part_export/phone_shellcommands.pm +++ b/FS/FS/part_export/phone_shellcommands.pm @@ -138,3 +138,4 @@ sub ssh_cmd { #subroutine, not method &Net::SSH::ssh_cmd( { @_ } ); } +1; diff --git a/FS/FS/part_export/phone_sqlopensips.pm b/FS/FS/part_export/phone_sqlopensips.pm index 3d01c1624..7b07ecf4a 100644 --- a/FS/FS/part_export/phone_sqlopensips.pm +++ b/FS/FS/part_export/phone_sqlopensips.pm @@ -21,10 +21,11 @@ tie %options, 'Tie::IxHash', ; %info = ( - 'svc' => 'svc_phone', - 'desc' => 'Export DIDs to OpenSIPs dr_rules table', - 'options' => \%options, - 'notes' => 'Export DIDs to OpenSIPs dr_rules table', + 'svc' => 'svc_phone', + 'desc' => 'Export DIDs to OpenSIPs dr_rules table', + 'options' => \%options, + 'no_machine' => 1, + 'notes' => 'Export DIDs to OpenSIPs dr_rules table', ); sub rebless { shift; } @@ -93,3 +94,4 @@ sub dr_reload { ''; } +1; diff --git a/FS/FS/part_export/phone_sqlradius.pm b/FS/FS/part_export/phone_sqlradius.pm index 6b14bed3c..46c372cb4 100644 --- a/FS/FS/part_export/phone_sqlradius.pm +++ b/FS/FS/part_export/phone_sqlradius.pm @@ -39,10 +39,11 @@ tie %options, 'Tie::IxHash', ; %info = ( - 'svc' => 'svc_phone', - 'desc' => 'Real-time export to SQL-backed RADIUS (FreeRADIUS, ICRADIUS) for phone provisioning and rating', - 'options' => \%options, - 'notes' => < 'svc_phone', + 'desc' => 'Real-time export to SQL-backed RADIUS (FreeRADIUS, ICRADIUS) for phone provisioning and rating', + 'options' => \%options, + 'no_machine' => 1, + 'notes' => <radcheck table to any SQL database for FreeRADIUS or ICRADIUS. diff --git a/FS/FS/part_export/postfix.pm b/FS/FS/part_export/postfix.pm index 4fd19ee61..9a8d617f3 100644 --- a/FS/FS/part_export/postfix.pm +++ b/FS/FS/part_export/postfix.pm @@ -22,6 +22,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_forward', 'desc' => 'Postfix text files', 'options' => \%options, + 'default_svc_class' => 'Email', 'notes' => <<'END' Batch export of Postfix aliases and virtual files. File::Rsync diff --git a/FS/FS/part_export/prizm.pm b/FS/FS/part_export/prizm.pm index 02e89c6d3..996448951 100644 --- a/FS/FS/part_export/prizm.pm +++ b/FS/FS/part_export/prizm.pm @@ -79,11 +79,12 @@ possibly harmful. EOT %info = ( - 'svc' => 'svc_broadband', - 'desc' => 'Real-time export to Northbound Interface', - 'options' => \%options, - 'nodomain' => 'Y', - 'notes' => $notes, + 'svc' => 'svc_broadband', + 'desc' => 'Real-time export to Northbound Interface', + 'options' => \%options, + 'nodomain' => 'Y', + 'no_machine' => 1, + 'notes' => $notes, ); sub prizm_command { diff --git a/FS/FS/part_export/radiator.pm b/FS/FS/part_export/radiator.pm index 2ac3edb22..f09d36abb 100644 --- a/FS/FS/part_export/radiator.pm +++ b/FS/FS/part_export/radiator.pm @@ -11,6 +11,8 @@ tie my %options, 'Tie::IxHash', %FS::part_export::sqlradius::options; 'desc' => 'Real-time export to RADIATOR', 'options' => \%options, 'nodomain' => '', + 'no_machine' => 1, + 'default_svc_class' => 'Internet', 'notes' => <<'END', Real-time export of the radusers table to any SQL database in Radiator-native format. diff --git a/FS/FS/part_export/router.pm b/FS/FS/part_export/router.pm index 6a1d676f4..3071ece74 100644 --- a/FS/FS/part_export/router.pm +++ b/FS/FS/part_export/router.pm @@ -87,6 +87,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_broadband', 'desc' => 'Send a command to a router.', 'options' => \%options, + 'no_machine' => 1, 'notes' => 'Installation of Net::Telnet from CPAN is required for telnet connections. This export will execute if the following virtual fields are set on the router: admin_user, admin_password, admin_address, admin_timeout, admin_prompt. Option virtual fields are: admin_cmd_insert, admin_cmd_replace, admin_cmd_delete, admin_cmd_suspend, admin_cmd_unsuspend. See the module documentation for a full list of required/supported router virtual fields.', ); diff --git a/FS/FS/part_export/rt_ticket.pm b/FS/FS/part_export/rt_ticket.pm index b53b7da8a..7ae6105a0 100644 --- a/FS/FS/part_export/rt_ticket.pm +++ b/FS/FS/part_export/rt_ticket.pm @@ -127,6 +127,7 @@ tie my %options, 'Tie::IxHash', ( 'Create an RT ticket', 'options' => \%options, 'nodomain' => '', + 'no_machine' => 1, 'notes' => ' Create a ticket in RT. The subject and body of the ticket will be generated from a message template.' diff --git a/FS/FS/part_export/send_email.pm b/FS/FS/part_export/send_email.pm index 05f623633..6ba131f18 100644 --- a/FS/FS/part_export/send_email.pm +++ b/FS/FS/part_export/send_email.pm @@ -85,6 +85,7 @@ tie my %options, 'Tie::IxHash', ( 'Send an email message', 'options' => \%options, 'nodomain' => '', + 'no_machine' => 1, 'notes' => ' Send an email message. The subject and body of the message will be generated from a message template.' diff --git a/FS/FS/part_export/shellcommands.pm b/FS/FS/part_export/shellcommands.pm index 20e909135..b9d6551db 100644 --- a/FS/FS/part_export/shellcommands.pm +++ b/FS/FS/part_export/shellcommands.pm @@ -97,12 +97,13 @@ tie my %options, 'Tie::IxHash', ; %info = ( - 'svc' => 'svc_acct', - 'desc' => + 'svc' => 'svc_acct', + 'desc' => 'Real-time export via remote SSH (i.e. useradd, userdel, etc.)', - 'options' => \%options, - 'nodomain' => 'Y', - 'notes' => <<'END' + 'options' => \%options, + 'nodomain' => 'Y', + 'svc_machine' => 1, + 'notes' => <<'END' Run remote commands via SSH. Usernames are considered unique (also see shellcommands_withdomain). You probably want this if the commands you are running will not accept a domain as a parameter. You will need to @@ -124,24 +125,7 @@ running will not accept a domain as a parameter. You will need to this.form.unsuspend_stdin.value=""; '>
  • - - Note: On FreeBSD versions before 5.3 and 4.10 (4.10 is after 4.9, not - 4.1!), due to deficient locking in pw(1), you must disable the chpass(1), - chsh(1), chfn(1), passwd(1), and vipw(1) commands, or replace them with - wrappers that prepend "lockf /etc/passwd.lock". Alternatively, apply the - patch in - FreeBSD PR#23501 - and use the "FreeBSD 4.10 / 5.3 or later" button below. -
  • - 'Real-time export to SQL-backed mail server', 'options' => \%options, 'nodomain' => '', + 'default_svc_class' => 'Email', 'notes' => <<'END' Database schema can be made to work with Courier IMAP, Exim and Dovecot. Others could work but are untested. (more detailed description from diff --git a/FS/FS/part_export/sqlradius.pm b/FS/FS/part_export/sqlradius.pm index 721396671..6760d09b7 100644 --- a/FS/FS/part_export/sqlradius.pm +++ b/FS/FS/part_export/sqlradius.pm @@ -110,6 +110,7 @@ END 'desc' => 'Real-time export to SQL-backed RADIUS (FreeRADIUS, ICRADIUS)', 'options' => \%options, 'nodomain' => 'Y', + 'no_machine' => 1, 'nas' => 'Y', # show export_nas selection in UI 'default_svc_class' => 'Internet', 'notes' => $notes1. diff --git a/FS/FS/part_export/textradius.pm b/FS/FS/part_export/textradius.pm index 869c7c7dc..07de87563 100644 --- a/FS/FS/part_export/textradius.pm +++ b/FS/FS/part_export/textradius.pm @@ -18,6 +18,7 @@ tie my %options, 'Tie::IxHash', 'desc' => 'Real-time export to a text /etc/raddb/users file (Livingston, Cistron)', 'options' => \%options, + 'default_svc_class' => 'Internet', 'notes' => <<'END' This will edit a text RADIUS users file in place on a remote server. Requires installation of diff --git a/FS/FS/part_export/trango.pm b/FS/FS/part_export/trango.pm index e7f1126dd..64d2cc4ec 100644 --- a/FS/FS/part_export/trango.pm +++ b/FS/FS/part_export/trango.pm @@ -68,6 +68,7 @@ tie my %options, 'Tie::IxHash', ( 'svc' => 'svc_broadband', 'desc' => 'Sends SNMP SETs to a Trango AP.', 'options' => \%options, + 'no_machine' => 1, 'notes' => 'Requires Net::SNMP. See the documentation for FS::part_export::trango for required virtual fields and usage information.', ); diff --git a/FS/FS/part_export/vitelity.pm b/FS/FS/part_export/vitelity.pm index 12c3a7fce..350a5ad48 100644 --- a/FS/FS/part_export/vitelity.pm +++ b/FS/FS/part_export/vitelity.pm @@ -26,6 +26,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_phone', 'desc' => 'Provision phone numbers to Vitelity', 'options' => \%options, + 'no_machine' => 1, 'notes' => <<'END' Requires installation of Net::Vitelity diff --git a/FS/FS/part_export/vpopmail.pm b/FS/FS/part_export/vpopmail.pm index 799a8e1c1..5fca1704c 100644 --- a/FS/FS/part_export/vpopmail.pm +++ b/FS/FS/part_export/vpopmail.pm @@ -23,6 +23,7 @@ tie my %options, 'Tie::IxHash', 'svc' => 'svc_acct', 'desc' => 'Real-time export to vpopmail text files', 'options' => \%options, + 'default_svc_class' => 'Email', 'notes' => <<'END' This export is currently unmaintained. See shellcommands_withdomain for an export that uses vpopmail CLI commands instead.
    diff --git a/FS/FS/part_export/www_plesk.pm b/FS/FS/part_export/www_plesk.pm index ccf9b3e17..a247f054e 100644 --- a/FS/FS/part_export/www_plesk.pm +++ b/FS/FS/part_export/www_plesk.pm @@ -18,10 +18,11 @@ tie my %options, 'Tie::IxHash', ; %info = ( - 'svc' => 'svc_www', - 'desc' => 'Real-time export to Plesk managed hosting service', - 'options'=> \%options, - 'notes' => <<'END' + 'svc' => 'svc_www', + 'desc' => 'Real-time export to Plesk managed hosting service', + 'options' => \%options, + 'no_machine' => 1, + 'notes' => <<'END' Real-time export to Plesk managed server. Requires installation of diff --git a/FS/FS/part_export/www_shellcommands.pm b/FS/FS/part_export/www_shellcommands.pm index d6116aba1..bef2e9470 100644 --- a/FS/FS/part_export/www_shellcommands.pm +++ b/FS/FS/part_export/www_shellcommands.pm @@ -188,3 +188,4 @@ sub ssh_cmd { #subroutine, not method ''; } +1; diff --git a/FS/FS/part_export_machine.pm b/FS/FS/part_export_machine.pm new file mode 100644 index 000000000..1598e0372 --- /dev/null +++ b/FS/FS/part_export_machine.pm @@ -0,0 +1,155 @@ +package FS::part_export_machine; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( dbh qsearch ); #qsearchs ); +use FS::part_export; +use FS::svc_export_machine; + +=head1 NAME + +FS::part_export_machine - Object methods for part_export_machine records + +=head1 SYNOPSIS + + use FS::part_export_machine; + + $record = new FS::part_export_machine \%hash; + $record = new FS::part_export_machine { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::part_export_machine object represents an export hostname choice. +FS::part_export_machine inherits from FS::Record. The following fields are +currently supported: + +=over 4 + +=item machinenum + +primary key + +=item exportnum + +Export, see L + +=item machine + +Hostname or IP address + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new record. To add the record to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +sub table { 'part_export_machine'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=cut + +sub delete { + my $self = shift; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $self->SUPER::delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $svc_export_machine ( $self->svc_export_machine ) { + my $error = $svc_export_machine->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + +} + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=item check + +Checks all fields to make sure this is a valid record. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('machinenum') + || $self->ut_foreign_key('exportnum', 'part_export', 'exportnum') + || $self->ut_domain('machine') + || $self->ut_enum('disabled', [ '', 'Y' ]) + ; + return $error if $error; + + $self->SUPER::check; +} + +=item svc_export_machine + +=cut + +sub svc_export_machine { + my $self = shift; + qsearch( 'svc_export_machine', { 'machinenum' => $self->machinenum } ); +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, L + +=cut + +1; + diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm index dd18e87f9..7f22411e0 100644 --- a/FS/FS/part_svc.pm +++ b/FS/FS/part_svc.pm @@ -591,7 +591,7 @@ sub _svc_defs { }; my $mod = $1; - if ( $mod =~ /^svc_[A-Z]/ or $mod =~ /^svc_acct_pop$/ ) { + if ( $mod =~ /^svc_[A-Z]/ or $mod =~ /^(svc_acct_pop|svc_export_machine)$/ ) { warn "skipping FS::$mod" if $DEBUG; next; } diff --git a/FS/FS/svc_export_machine.pm b/FS/FS/svc_export_machine.pm new file mode 100644 index 000000000..39629d8af --- /dev/null +++ b/FS/FS/svc_export_machine.pm @@ -0,0 +1,111 @@ +package FS::svc_export_machine; + +use strict; +use base qw( FS::Record ); +use FS::Record; # qw( qsearch qsearchs ); +use FS::cust_svc; +use FS::part_export_machine; + +=head1 NAME + +FS::svc_export_machine - Object methods for svc_export_machine records + +=head1 SYNOPSIS + + use FS::svc_export_machine; + + $record = new FS::svc_export_machine \%hash; + $record = new FS::svc_export_machine { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::svc_export_machine object represents a customer service export +hostname. FS::svc_export_machine inherits from FS::Record. The following +fields are currently supported: + +=over 4 + +=item svcexportmachinenum + +primary key + +=item svcnum + +Customer service, see L + +=item machinenum + +Export hostname, see L + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new record. To add the record to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +sub table { 'svc_export_machine'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=item check + +Checks all fields to make sure this is a valid record. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('svcexportmachinenum') + || $self->ut_foreign_key('svcnum', 'cust_svc', 'svcnum') + || $self->ut_foreign_key('machinenum', 'part_export_machine', 'machinenum' ) + ; + return $error if $error; + + $self->SUPER::check; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, L, L + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index bb10fb7b1..479dcad60 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -668,3 +668,7 @@ t/cust_bill_pkg_discount_void.t FS/Trace.pm FS/agent_pkg_class.pm t/agent_pkg_class.t +FS/part_export_machine.pm +t/part_export_machine.t +FS/svc_export_machine.pm +t/svc_export_machine.t diff --git a/FS/t/part_export_machine.t b/FS/t/part_export_machine.t new file mode 100644 index 000000000..792bb5092 --- /dev/null +++ b/FS/t/part_export_machine.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_export_machine; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/svc_export_machine.t b/FS/t/svc_export_machine.t new file mode 100644 index 000000000..5279be2ca --- /dev/null +++ b/FS/t/svc_export_machine.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::svc_export_machine; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/browse/part_export.cgi b/httemplate/browse/part_export.cgi index 8e28f4fc6..beed70887 100755 --- a/httemplate/browse/part_export.cgi +++ b/httemplate/browse/part_export.cgi @@ -36,10 +36,19 @@ function part_export_areyousure(href) { <% $part_export->exportnum %> -% if( $part_export->exportname ) { - <% $part_export->exportname %>:
    -% } -<% $part_export->exporttype %> to <% $part_export->machine %> (edit | delete) +% if( $part_export->exportname ) { + <% $part_export->exportname %>:
    +% } + <% $part_export->exporttype %> + <% $part_export->machine + ? 'to '. ( $part_export->machine eq '_SVC_MACHINE' + ? 'per-service hostname' + : $part_export->machine + ) + : '' + %> + (edit | delete) + <% itable() %> diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi index d7219b74a..0407ee77b 100644 --- a/httemplate/edit/part_export.cgi +++ b/httemplate/edit/part_export.cgi @@ -13,12 +13,6 @@ - Export host - - - - - Export <% $widget->html %> @@ -63,7 +57,7 @@ my $widget = new HTML::Widgets::SelectLayers( 'options' => \%layers, 'form_name' => 'dummy', 'form_action' => 'process/part_export.cgi', - 'form_text' => [qw( exportnum exportname machine )], + 'form_text' => [qw( exportnum exportname )], # 'form_checkbox' => [qw()], 'html_between' => "\n", 'layer_callback' => sub { @@ -71,9 +65,69 @@ my $widget = new HTML::Widgets::SelectLayers( my $html = qq!!. ntable("#cccccc",2); - $html .= 'Description'. - $exports->{$layer}{notes}. '' - if $layer; + if ( $layer ) { + $html .= 'Description'. + $exports->{$layer}{notes}. ''; + + if ( $exports->{$layer}{no_machine} ) { + $html .= ''. + ''; + } else { + $html .= 'Hostname or IP'; + my $machine = $part_export->machine; + if ( $exports->{$layer}{svc_machine} ) { + my( $N_CHK, $Y_CHK) = ( 'CHECKED', '' ); + my( $machine_DISABLED, $pem_DISABLED) = ( '', 'DISABLED' ); + my $part_export_machine = ''; + if ( $cgi->param('svc_machine') eq 'Y' + || $machine eq '_SVC_MACHINE' + ) + { + $Y_CHK = 'CHECKED'; + $N_CHK = 'CHECKED'; + $machine_DISABLED = 'DISABLED'; + $pem_DISABLED = ''; + $machine = ''; + $part_export_machine = + $cgi->param('part_export_machine') + || join "\n", + map $_->machine, + grep ! $_->disabled, + $part_export->part_export_machine; + } + my $oc = qq(onChange="${layer}_svc_machine_changed(this)"); + $html .= qq[ + + +
    + + Selected in each customer service from these choices + + + + ]; + } else { + $html .= qq(). + ''; + } + $html .= ""; + } + + } foreach my $option ( keys %{$exports->{$layer}{options}} ) { my $optinfo = $exports->{$layer}{options}{$option}; diff --git a/httemplate/edit/process/part_export.cgi b/httemplate/edit/process/part_export.cgi index 21150ef67..6432d6b15 100644 --- a/httemplate/edit/process/part_export.cgi +++ b/httemplate/edit/process/part_export.cgi @@ -28,6 +28,11 @@ my $new = new FS::part_export ( { } fields('part_export') } ); +if ( $cgi->param('svc_machine') eq 'Y' ) { + $new->machine('_SVC_MACHINE'); + $new->part_export_machine_textarea( $cgi->param('part_export_machine') ); +} + my $error; if ( $exportnum ) { #warn $old; -- 2.11.0