From 4b5d4c82766ef1869d03df63fa1e2f0dd050cb6a Mon Sep 17 00:00:00 2001 From: jeff Date: Sat, 27 Sep 2008 03:01:44 +0000 Subject: [PATCH] per address block ip auto assignment and auto router selection --- FS/FS/Conf.pm | 7 +++++ FS/FS/Schema.pm | 1 + FS/FS/addr_block.pm | 8 +++++- FS/FS/svc_broadband.pm | 24 +++++++++++++++-- httemplate/browse/addr_block.cgi | 10 ++++++++ httemplate/edit/process/addr_block/manual_flag.cgi | 30 ++++++++++++++++++++++ httemplate/edit/svc_broadband.cgi | 23 +++++++++++++++-- 7 files changed, 98 insertions(+), 5 deletions(-) create mode 100755 httemplate/edit/process/addr_block/manual_flag.cgi diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 274b109db..79e9feb3c 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -731,6 +731,13 @@ worry that config_items is freeside-specific and icky. }, { + 'key' => 'auto_router', + 'section' => '', + 'description' => 'Automatically choose the correct router/block based on supplied ip address when possible while provisioning broadband services', + 'type' => 'checkbox', + }, + + { 'key' => 'hidecancelledpackages', 'section' => 'UI', 'description' => 'Prevent cancelled packages from showing up in listings (though they will still be in the database)', diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 5c9f6248c..0b121db3e 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1586,6 +1586,7 @@ sub tables_hashref { 'ip_gateway', 'varchar', '', 15, '', '', 'ip_netmask', 'int', '', '', '', '', 'agentnum', 'int', 'NULL', '', '', '', + 'manual_flag', 'char', 'NULL', 1, '', '', ], 'primary_key' => 'blocknum', 'unique' => [ [ 'blocknum', 'routernum' ] ], diff --git a/FS/FS/addr_block.pm b/FS/FS/addr_block.pm index 9d523e1fc..0fe2476a2 100755 --- a/FS/FS/addr_block.pm +++ b/FS/FS/addr_block.pm @@ -48,6 +48,8 @@ block is assigned. =item ip_netmask - the netmask of the block, expressed as an integer. +=item manual_flag - prohibit automatic ip assignment from this block when true. + =item agentnum - optional agent number (see L) =back @@ -124,6 +126,7 @@ sub check { $self->ut_number('routernum') || $self->ut_ip('ip_gateway') || $self->ut_number('ip_netmask') + || $self->ut_enum('manual_flag', [ '', 'Y' ]) || $self->ut_agentnum_acl('agentnum', 'Broadband global configuration') ; return $error if $error; @@ -202,13 +205,16 @@ sub cidr { Returns a NetAddr::IP object corresponding to the first unassigned address in the block (other than the network, broadcast, or gateway address). If -there are no free addresses, returns false. +there are no free addresses, returns false. There are never free addresses +when manual_flag is true. =cut sub next_free_addr { my $self = shift; + return '' if $self->manual_flag; + my $conf = new FS::Conf; my @excludeaddr = $conf->config('exclude_ip_addr'); diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm index fa904370b..b808527a1 100755 --- a/FS/FS/svc_broadband.pm +++ b/FS/FS/svc_broadband.pm @@ -203,7 +203,7 @@ sub check { my $error = $self->ut_numbern('svcnum') - || $self->ut_foreign_key('blocknum', 'addr_block', 'blocknum') + || $self->ut_numbern('blocknum') || $self->ut_textn('description') || $self->ut_number('speed_up') || $self->ut_number('speed_down') @@ -231,7 +231,12 @@ sub check { return "Invalid pkgnum" unless $cust_pkg; } - if ($cust_pkg) { + if ($self->blocknum) { + $error = $self->ut_foreign_key('blocknum', 'addr_block', 'blocknum'); + return $error if $error; + } + + if ($cust_pkg && $self->blocknum) { my $addr_agentnum = $self->addr_block->agentnum; if ($addr_agentnum && $addr_agentnum != $cust_pkg->cust_main->agentnum) { return "Address block does not service this customer"; @@ -239,6 +244,8 @@ sub check { } if (not($self->ip_addr) or $self->ip_addr eq '0.0.0.0') { + return "Must supply either address or block" + unless $self->blocknum; my $next_addr = $self->addr_block->next_free_addr; if ($next_addr) { $self->ip_addr($next_addr->addr); @@ -247,6 +254,19 @@ sub check { } } + if (not($self->blocknum)) { + return "Must supply either address or block" + unless ($self->ip_addr and $self->ip_addr ne '0.0.0.0'); + my @block = grep { $_->NetAddr->contains($self->NetAddr) } + map { $_->addr_block } + $self->allowed_routers; + if (scalar(@block)) { + $self->blocknum($block[0]->blocknum); + }else{ + return "Address not with available block."; + } + } + # This should catch errors in the ip_addr. If it doesn't, # they'll almost certainly not map into the block anyway. my $self_addr = $self->NetAddr; #netmask is /32 diff --git a/httemplate/browse/addr_block.cgi b/httemplate/browse/addr_block.cgi index 945f8da01..241bb937f 100644 --- a/httemplate/browse/addr_block.cgi +++ b/httemplate/browse/addr_block.cgi @@ -13,6 +13,7 @@ 'Router', 'Action(s)', '', + '', ], 'fields' => [ 'NetAddr', sub { my $block = shift; @@ -26,11 +27,13 @@ }, $allocate_text, sub { shift->router ? '' : '(split)' }, + sub { '('. (shift->manual_flag ? 'allow' : 'prevent'). ' automatic ip assignment)' }, ], 'links' => [ '', '', [ 'javascript:void(0)', '' ], $split_link, + $autoassign_link, ], 'link_onclicks' => [ '', '', @@ -133,4 +136,11 @@ my $split_link = sub { $ref; }; +my $autoassign_link = sub { + my $block = shift; + my $url = "$path/manual_flag.cgi?manual_flag="; + $url .= $block->manual_flag ? '' : 'Y'; + [ "$url;blocknum=", 'blocknum' ]; +}; + diff --git a/httemplate/edit/process/addr_block/manual_flag.cgi b/httemplate/edit/process/addr_block/manual_flag.cgi new file mode 100755 index 000000000..dc0cbbbf5 --- /dev/null +++ b/httemplate/edit/process/addr_block/manual_flag.cgi @@ -0,0 +1,30 @@ +<% $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string ) %> +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Broadband configuration') + || $curuser->access_right('Broadband global configuration'); + +my $error = ''; +$cgi->param('blocknum') =~ /^(\d+)$/ or die "invalid blocknum"; +my $blocknum = $1; + +my $addr_block = qsearchs({ 'table' => 'addr_block', + 'hashref' => { blocknum => $blocknum }, + 'extra_sql' => ' AND '. $curuser->agentnums_sql( + 'null_right' => 'Broadband global configuration' + ), + }) + or $error = "Unknown blocknum: $blocknum"; + +$addr_block->manual_flag($cgi->param('manual_flag')) + unless $error; + +$error ||= $addr_block->replace; + +$cgi->param('error', $error) + if $error; + + diff --git a/httemplate/edit/svc_broadband.cgi b/httemplate/edit/svc_broadband.cgi index 25fb009ac..e60c76c90 100644 --- a/httemplate/edit/svc_broadband.cgi +++ b/httemplate/edit/svc_broadband.cgi @@ -8,7 +8,7 @@ 'speed_down' => 'Download speed', 'speed_up' => 'Upload speed', 'blocknum' => 'Router/Block', - 'block_disp' => 'Router/Block', + 'block_label' => 'Router/Block', 'mac_addr' => 'MAC address', 'latitude' => 'Latitude', 'longitude' => 'Longitude', @@ -29,12 +29,16 @@ die "access denied" # If it's stupid but it works, it's still stupid. # -Kristian +my $conf = new FS::Conf; + my @fields = ( qw( description ip_addr speed_down speed_up blocknum ), { field=>'block_label', type=>'fixed' }, qw( mac_addr latitude longitude altitude vlan_profile authkey ) ); +my $fixedblock = ''; + my $callback = sub { my ($cgi, $object, $fieldref) = @_; @@ -48,6 +52,8 @@ my $callback = sub { if ($columndef->columnflag eq 'F') { $fieldref->{'type'} = 'fixed'; $fieldref->{'value'} = $columndef->columnvalue; + $fixedblock = $fieldref->{value} + if $fieldref->{field} eq 'blocknum'; } if ($object->svcnum) { @@ -60,9 +66,22 @@ my $callback = sub { } else { - $fieldref->{type} = 'hidden' if $fieldref->{field} eq 'block_label'; + if ($fieldref->{field} eq 'block_label') { + if ($fixedblock) { + $object->blocknum($fixedblock); + $fieldref->{value} = $object->addr_block->label; + }else{ + $fieldref->{type} = 'hidden'; + } + } if ($fieldref->{field} eq 'blocknum') { + if ( $fixedblock or $conf->exists('auto_router') ) { + $fieldref->{type} = 'hidden'; + $fieldref->{value} = $fixedblock; + return; + } + my $cust_pkg = qsearchs( 'cust_pkg', {pkgnum => $cgi->param('pkgnum')} ); die "No cust_pkg entry!" unless $cust_pkg; -- 2.11.0