diff options
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/Record.pm | 23 | ||||
-rw-r--r-- | FS/FS/Schema.pm | 4 | ||||
-rw-r--r-- | FS/FS/part_export/prizm.pm | 351 | ||||
-rwxr-xr-x | FS/FS/svc_broadband.pm | 9 |
4 files changed, 380 insertions, 7 deletions
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 29f2dc618..c25b9beb0 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -84,6 +84,7 @@ FS::Record - Database record objects $value = $record->unique('column'); $error = $record->ut_float('column'); + $error = $record->ut_floatn('column'); $error = $record->ut_number('column'); $error = $record->ut_numbern('column'); $error = $record->ut_snumber('column'); @@ -1285,11 +1286,29 @@ sub ut_float { $self->setfield($field,$1); ''; } +=item ut_floatn COLUMN + +Check/untaint floating point numeric data: 1.1, 1, 1.1e10, 1e10. May be +null. If there is an error, returns the error, otherwise returns false. + +=cut + +sub ut_floatn { + my($self,$field)=@_ ; + ($self->getfield($field) =~ /^(\d*)$/ || + $self->getfield($field) =~ /^(-?\d+\.\d+)$/ || + $self->getfield($field) =~ /^(-?\d+)$/ || + $self->getfield($field) =~ /^(-?\d+\.\d+e\d+)$/ || + $self->getfield($field) =~ /^(-?\d+e\d+)$/) + or return "Illegal or empty (float) $field: ". $self->getfield($field); + $self->setfield($field,$1); + ''; +} =item ut_snumber COLUMN -Check/untaint signed numeric data (whole numbers). May not be null. If there -is an error, returns the error, otherwise returns false. +Check/untaint signed numeric data (whole numbers). If there is an error, +returns the error, otherwise returns false. =cut diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 2f289941d..255b34406 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1149,9 +1149,11 @@ sub tables_hashref { 'speed_down', 'int', '', '', '', '', 'ip_addr', 'varchar', '', 15, '', '', 'mac_addr', 'varchar', 'NULL', 12, '', '', + 'authkey', 'varchar', 'NULL', 32, '', '', 'latitude', 'decimal', 'NULL', '', '', '', 'longitude', 'decimal', 'NULL', '', '', '', - 'vlan', 'int', 'NULL', '', '', '', + 'altitude', 'decimal', 'NULL', '', '', '', + 'vlan_profile', 'varchar', 'NULL', $char_d, '', '', ], 'primary_key' => 'svcnum', 'unique' => [], diff --git a/FS/FS/part_export/prizm.pm b/FS/FS/part_export/prizm.pm new file mode 100644 index 000000000..7ff8b4fcb --- /dev/null +++ b/FS/FS/part_export/prizm.pm @@ -0,0 +1,351 @@ +package FS::part_export::prizm; + +use vars qw(@ISA %info %options $DEBUG); +use Tie::IxHash; +use FS::Record qw(fields); +use FS::part_export; + +@ISA = qw(FS::part_export); +$DEBUG = 1; + +tie %options, 'Tie::IxHash', + 'url' => { label => 'Northbound url', default=>'https://localhost:8443/prizm/nbi' }, + 'user' => { label => 'Northbound username', default=>'nbi' }, + 'password' => { label => 'Password', default => '' }, +; + +%info = ( + 'svc' => 'svc_broadband', + 'desc' => 'Real-time export to Northbound Interface', + 'options' => \%options, + 'nodomain' => 'Y', + 'notes' => 'These are notes.' +); + +sub prizm_command { + my ($self,$namespace,$method) = (shift,shift,shift); + + eval "use Net::Prizm qw(CustomerInfo PrizmElement);"; + die $@ if $@; + + my $prizm = new Net::Prizm ( + namespace => $namespace, + url => $self->option('url'), + user => $self->option('user'), + password => $self->option('password'), + ); + + $prizm->$method(@_); +} + +sub _export_insert { + my( $self, $svc ) = ( shift, shift ); + + my $cust_main = $svc->cust_svc->cust_pkg->cust_main; + + my $err_or_som = $self->prizm_command(CustomerIfService, 'getCustomers', + ['import_id'], + [$cust_main->custnum], + ['='], + ); + return $err_or_som + unless ref($err_or_som); + + my $pre = ''; + if ( defined $cust_main->dbdef_table->column('ship_last') ) { + $pre = $cust_main->ship_last ? 'ship_' : ''; + } + my $name = $pre ? $cust_main->ship_name : $cust_main->name; + my $location = join(" ", map { my $method = "$pre$_"; $cust_main->$method } + qw (address1 address2 city state zip) + ); + my $contact = join(" ", map { my $method = "$pre$_"; $cust_main->$method } + qw (daytime night) + ); + + my $pcustomer; + if ($err_or_som->result->[0]) { + $pcustomer = $err_or_som->result->[0]->customerId; + }else{ + my $chashref = $cust_main->hashref; + my $customerinfo = { + importId => $cust_main->custnum, + customerName => $name, + customerType => 'freeside', + address1 => $chashref->{"${pre}address1"}, + address2 => $chashref->{"${pre}address2"}, + city => $chashref->{"${pre}city"}, + state => $chashref->{"${pre}state"}, + zipCode => $chashref->{"${pre}zip"}, + workPhone => $chashref->{"${pre}daytime"}, + homePhone => $chashref->{"${pre}night"}, + email => @{[$cust_main->invoicing_list_emailonly]}[0], + extraFieldNames => [ 'country', 'freesideId', + ], + extraFieldValues => [ $chashref->{"${pre}country"}, $cust_main->custnum, + ], + }; + + $err_or_som = $self->prizm_command('CustomerIfService', 'addCustomer', + $customerinfo); + return $err_or_som + unless ref($err_or_som); + + $pcustomer = $err_or_som->result; + } + warn "multiple prizm customers found for $cust_main->custnum" + if scalar(@$pcustomer) > 1; + + #kinda big question/expensive + $err_or_som = $self->prizm_command('NetworkIfService', 'getPrizmElements', + ['Network Default Gateway Address'], + [$svc->addr_block->ip_gateway], + ['='], + ); + return $err_or_som + unless ref($err_or_som); + + return "No elements in network" unless exists $err_or_som->result->[0]; + + my $networkid = 0; + for (my $i = 0; $i < $err_or_som->result->[0]->attributeNames; $i++) { + if ($err_or_som->result->[0]->attributeNames->[$i] eq "Network.ID"){ + $networkid = $err_or_som->result->[0]->attributeValues->[$i]; + last; + } + } + + $err_or_som = $self->prizm_command('NetworkIfService', 'addProvisionedElement', + $networkid, + $svc->mac_addr, + $name, + $location, + $contact, + sprintf("%032X", $svc->authkey), + $svc->cust_svc->cust_pkg->part_pkg->pkg, + $svc->vlan_profile, + 1, + ); + return $err_or_som + unless ref($err_or_som); + + my (@names) = ('Management IP', + 'GPS Latitude', + 'GPS Longitude', + 'GPS Altitude', + 'Site Name', + 'Site Location', + 'Site Contact', + ); + my (@values) = ($svc->ip_addr, + $svc->latitude, + $svc->longitude, + '', + $name, + $location, + $contact, + ); + $element = $err_or_som->result->elementId; + $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfig', + [ $element ], + \@names, + \@values, + 0, + 1, + ); + return $err_or_som + unless ref($err_or_som); + + $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet', + [ $element ], + $svc->vlan_profile, + 0, + 1, + ); + return $err_or_som + unless ref($err_or_som); + + $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet', + [ $element ], + $svc->cust_svc->cust_pkg->part_pkg->pkg, + 0, + 1, + ); + return $err_or_som + unless ref($err_or_som); + + $err_or_som = $self->prizm_command('NetworkIfService', + 'activateNetworkElements', + [ $element ], + 1, + 1, + ); + + return $err_or_som + unless ref($err_or_som); + + $err_or_som = $self->prizm_command('CustomerIfService', + 'addElementToCustomer', + 0, + $cust_main->custnum, + 0, + $svc->mac_addr, + ); + + return $err_or_som + unless ref($err_or_som); + + ''; +} + +sub _export_delete { + my( $self, $svc ) = ( shift, shift ); + + my $custnum = $svc->cust_svc->cust_pkg->cust_main->custnum; + + my $err_or_som = $self->prizm_command('NetworkIfService', 'getPrizmElements', + ['MAC Address'], + [$svc->mac_addr], + ['='], + ); + return $err_or_som + unless ref($err_or_som); + + return "Can't find prizm element for " . $svc->mac_addr + unless $err_or_som->result->[0]; + + $err_or_som = $self->prizm_command('NetworkIfService', + 'suspendNetworkElements', + [$err_or_som->result->[0]->elementId], + 1, + 1, + ); + + return $err_or_som + unless ref($err_or_som); + + $err_or_som = $self->prizm_command('CustomerIfService', + 'removeElementFromCustomer', + 0, + $custnum, + 0, + $svc->mac_addr, + ); + + return $err_or_som + unless ref($err_or_som); + + ''; +} + +sub _export_replace { + my( $self, $new, $old ) = ( shift, shift, shift ); + + my $err_or_som = $self->prizm_command('NetworkIfService', 'getPrizmElements', + [ 'MAC Address' ], + [ $old->mac_addr ], + [ '=' ], + ); + return $err_or_som + unless ref($err_or_som); + + return "Can't find prizm element for " . $old->mac_addr + unless $err_or_som->result->[0]; + + my %freeside2prizm = ( mac_addr => 'MAC Address', + ip_addr => 'Management IP', + latitude => 'GPS Latitude', + longitude => 'GPS Longitude', + altitude => 'GPS Altitude', + authkey => 'Authentication Key', + ); + + my (@values); + my (@names) = map { push @values, $new->$_; $freeside2prizm{$_} } + grep { $old->$_ ne $new->$_ } + grep { exists($freeside2prizm{$_}) } + fields( 'svc_broadband' ); + + my $element = $err_or_som->result->[0]->elementId; + my $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfig', + [ $element ], + \@names, + \@values, + 0, + 1, + ); + return $err_or_som + unless ref($err_or_som); + + $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet', + [ $element ], + $new->vlan_profile, + 0, + 1, + ) + if $old->vlan_profile ne $new->vlan_profile; + + return $err_or_som + unless ref($err_or_som); + + ''; + +} + +sub _export_suspend { + my( $self, $svc ) = ( shift, shift ); + + my $err_or_som = $self->prizm_command('NetworkIfService', 'getPrizmElements', + [ 'MAC Address' ], + [ $svc->mac_addr ], + [ '=' ], + ); + return $err_or_som + unless ref($err_or_som); + + return "Can't find prizm element for " . $svc->mac_addr + unless $err_or_som->result->[0]; + + $err_or_som = $self->prizm_command('NetworkIfService', + 'suspendNetworkElements', + [ $err_or_som->result->[0]->elementId ], + 1, + 1, + ); + + return $err_or_som + unless ref($err_or_som); + + ''; + +} + +sub _export_unsuspend { + my( $self, $svc ) = ( shift, shift ); + + my $err_or_som = $self->prizm_command('NetworkIfService', 'getPrizmElements', + [ 'MAC Address' ], + [ $svc->mac_addr ], + [ '=' ], + ); + return $err_or_som + unless ref($err_or_som); + + return "Can't find prizm element for " . $svc->mac_addr + unless $err_or_som->result->[0]; + + $err_or_som = $self->prizm_command('NetworkIfService', + 'activateNetworkElements', + [ $err_or_som->result->[0]->elementId ], + 1, + 1, + ); + + return $err_or_som + unless ref($err_or_som); + + ''; + +} + +1; diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index f4cc79403..5c9fe5e12 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -155,16 +155,17 @@ sub check { || $self->ut_number('speed_down') || $self->ut_ipn('ip_addr') || $self->ut_hexn('mac_addr') - || $self->ut_numbern('vlan') + || $self->ut_hexn('auth_key') + || $self->ut_floatn('latitude') + || $self->ut_floatn('longitude') + || $self->ut_floatn('altitude') + || $self->ut_textn('vlan_profile') ; return $error if $error; if($self->speed_up < 0) { return 'speed_up must be positive'; } if($self->speed_down < 0) { return 'speed_down must be positive'; } - if($self->vlan < 0 || $self->vlan > 4096) { # apropos? - return 'vlan is out of range'; } - if($self->latitude < -90 || $self->latitude > 90) { return 'latitude must be between -90 and 90'; } |