From dac4bb8dc3fcdd36fdcaf445c12134103a9d599e Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 14 Oct 2011 08:56:14 +0000 Subject: [PATCH] maintain freeradius nas table, RT#14697 --- FS/FS/Schema.pm | 40 ++++++------ FS/FS/nas.pm | 96 +++++++++++++++-------------- FS/MANIFEST | 2 + httemplate/browse/nas.html | 33 ++++++++++ httemplate/edit/elements/edit.html | 2 + httemplate/edit/nas.html | 41 ++++++++++++ httemplate/edit/process/nas.html | 7 +++ httemplate/elements/menu.html | 5 +- httemplate/elements/tr-td-label.html | 4 +- httemplate/search/elements/search-html.html | 60 ++++++++---------- 10 files changed, 190 insertions(+), 100 deletions(-) create mode 100644 httemplate/browse/nas.html create mode 100644 httemplate/edit/nas.html create mode 100644 httemplate/edit/process/nas.html diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index ee434d76e..4fc0cfe69 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2242,29 +2242,31 @@ sub tables_hashref { 'nas' => { 'columns' => [ - 'nasnum', 'serial', '', '', '', '', - 'nas', 'varchar', '', $char_d, '', '', - 'nasip', 'varchar', '', 15, '', '', - 'nasfqdn', 'varchar', '', $char_d, '', '', - 'last', 'int', '', '', '', '', + 'nasnum', 'serial', '', '', '', '', + 'nasname', 'varchar', '', 128, '', '', + 'shortname', 'varchar', 'NULL', 32, '', '', + 'type', 'varchar', '', 30, 'other', '', + 'ports', 'int', 'NULL', '', '', '', + 'secret', 'varchar', '', 60, 'secret', '', + 'server', 'varchar', 'NULL', 64, '', '', + 'community', 'varchar', 'NULL', 50, '', '', + 'description', 'varchar', '', 200, 'RADIUS Client', '', ], 'primary_key' => 'nasnum', - 'unique' => [ [ 'nas' ], [ 'nasip' ] ], - 'index' => [ [ 'last' ] ], + 'unique' => [ [ 'nasname' ], ], + 'index' => [], }, -# 'session' => { -# 'columns' => [ -# 'sessionnum', 'serial', '', '', '', '', -# 'portnum', 'int', '', '', '', '', -# 'svcnum', 'int', '', '', '', '', -# 'login', @date_type, '', '', -# 'logout', @date_type, '', '', -# ], -# 'primary_key' => 'sessionnum', -# 'unique' => [], -# 'index' => [ [ 'portnum' ] ], -# }, + 'export_nas' => { + 'columns' => [ + 'exportnasnum', 'serial', '', '', '', '', + 'exportnum', 'int', '', '', '', '', + 'nasnum', 'int', '', '', '', '', + ], + 'primary_key' => 'exportnasnum', + 'unique' => [ [ 'exportnum', 'nasnum' ] ], + 'index' => [ [ 'exportnum' ], [ 'nasnum' ] ], + }, 'queue' => { 'columns' => [ diff --git a/FS/FS/nas.pm b/FS/FS/nas.pm index 97b0ea17d..7fb7db5e5 100644 --- a/FS/FS/nas.pm +++ b/FS/FS/nas.pm @@ -1,11 +1,8 @@ package FS::nas; use strict; -use vars qw( @ISA ); -use FS::Record qw(qsearchs); #qsearch); -use FS::UID qw( dbh ); - -@ISA = qw(FS::Record); +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs ); =head1 NAME @@ -16,11 +13,7 @@ FS::nas - Object methods for nas records use FS::nas; $record = new FS::nas \%hash; - $record = new FS::nas { - 'nasnum' => 1, - 'nasip' => '10.4.20.23', - 'nasfqdn' => 'box1.brc.nv.us.example.net', - }; + $record = new FS::nas { 'column' => 'value' }; $error = $record->insert; @@ -30,26 +23,49 @@ FS::nas - Object methods for nas records $error = $record->check; - $error = $record->heartbeat($timestamp); - =head1 DESCRIPTION -An FS::nas object represents an Network Access Server on your network, such as -a terminal server or equivalent. FS::nas inherits from FS::Record. The -following fields are currently supported: +An FS::nas object represents a RADIUS client. FS::nas inherits from +FS::Record. The following fields are currently supported: =over 4 -=item nasnum - primary key +=item nasnum + +primary key + +=item nasname + +nasname + +=item shortname + +shortname + +=item type + +type + +=item ports + +ports + +=item secret -=item nas - NAS name +secret -=item nasip - NAS ip address +=item server -=item nasfqdn - NAS fully-qualified domain name +server + +=item community + +community + +=item description + +description -=item last - timestamp indicating the last instant the NAS was in a known - state (used by the session monitoring). =back @@ -110,36 +126,26 @@ and replace methods. sub check { my $self = shift; - $self->ut_numbern('nasnum') - || $self->ut_text('nas') - || $self->ut_ip('nasip') - || $self->ut_domain('nasfqdn') - || $self->ut_numbern('last') - || $self->SUPER::check - ; -} - -=item heartbeat TIMESTAMP - -Updates the timestamp for this nas - -=cut - -sub heartbeat { - my($self, $timestamp) = @_; - my $dbh = dbh; - my $sth = - $dbh->prepare("UPDATE nas SET last = ? WHERE nasnum = ? AND last < ?"); - $sth->execute($timestamp, $self->nasnum, $timestamp) or die $sth->errstr; - $self->last($timestamp); + my $error = + $self->ut_numbern('nasnum') + || $self->ut_text('nasname') + || $self->ut_textn('shortname') + || $self->ut_text('type') + || $self->ut_numbern('ports') + || $self->ut_text('secret') + || $self->ut_textn('server') + || $self->ut_textn('community') + || $self->ut_text('description') + ; + return $error if $error; + + $self->SUPER::check; } =back =head1 BUGS -heartbeat method uses SQL directly and doesn't update history tables. - =head1 SEE ALSO L, schema.html from the base documentation. diff --git a/FS/MANIFEST b/FS/MANIFEST index 557e61279..eeca1b27b 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -612,3 +612,5 @@ FS/template_content.pm t/template_content.t FS/dsl_device.pm t/dsl_device.t +FS/export_nas.pm +t/export_nas.t diff --git a/httemplate/browse/nas.html b/httemplate/browse/nas.html new file mode 100644 index 000000000..c9d57e8ed --- /dev/null +++ b/httemplate/browse/nas.html @@ -0,0 +1,33 @@ +<& elements/browse.html, + 'title' => 'RADIUS clients', + 'name_singular' => 'RADIUS client', + 'query' => { 'table' => 'nas', }, + 'count_query' => 'SELECT COUNT(*) FROM nas', + 'header' => [ 'Hostname', 'Short name', #'Shared secret', + 'Type', 'Ports', 'Server', 'Community', + 'Description', + ], + 'fields' => [ 'nasname', + 'shortname', + #'secret', + 'type', + 'ports', + 'server', + 'community', + 'description', + ], + 'links' => [ $link, $link ], + 'align' => 'lllrlll', + 'add_link' => 1, + #'disableable' => 1, + #'disabled_statuspos' => 2, + #All options from /search/elements/search.html are available. +&> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $link = [ $p.'edit/nas.html?', 'nasnum' ]; + + diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html index d9843471f..6db54fd48 100644 --- a/httemplate/edit/elements/edit.html +++ b/httemplate/edit/elements/edit.html @@ -287,6 +287,7 @@ Example: % % #any? % 'colspan' => $f->{'colspan'}, +% 'required' => $f->{'required'}, % ); % % $include_common{$_} = $f->{$_} foreach grep exists($f->{$_}), @@ -755,6 +756,7 @@ my $fields = $opt{'fields'} || [ grep { $_ ne $pkey } fields($table) ]; #my @actualfields = map { ref($_) ? $_->{'field'} : $_ } @$fields; +#$m->comp('/elements/handle_uri_query'); if ( $cgi->param('redirect') ) { my $session = $cgi->param('redirect'); my $pref = $curuser->option("redirect$session"); diff --git a/httemplate/edit/nas.html b/httemplate/edit/nas.html new file mode 100644 index 000000000..64d722e52 --- /dev/null +++ b/httemplate/edit/nas.html @@ -0,0 +1,41 @@ +<& elements/edit.html, + 'name_singular' => 'RADIUS client', + 'table' => 'nas', + 'viewall_dir' => 'browse', + 'labels' => { 'nasnum' => 'NAS', + 'nasname' => 'Hostname', + 'shortname' => 'Short name', + 'secret' => 'Shared secret', + 'type' => 'Type', + 'ports' => 'Ports', + 'server' => 'Server', + 'community' => 'Community', + 'description' => 'Description', + }, + 'fields' => [ + { field=> 'nasname', required=>1, size=>40, maxlength=>128 }, + { 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 }, + { field=>'description', size=>100, maxlength=>200 }, + ], + 'html_bottom' => '* '. + emt('required fields'). '
', + 'new_hashref_callback' => sub { +{ 'type' => 'other', + 'secret' => 'secret', + 'description' => 'RADIUS Client', + }; + }, +&> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + + diff --git a/httemplate/edit/process/nas.html b/httemplate/edit/process/nas.html new file mode 100644 index 000000000..04b46a5c0 --- /dev/null +++ b/httemplate/edit/process/nas.html @@ -0,0 +1,7 @@ +<& elements/process.html, table=>'nas', viewall_dir=>'browse', &> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + + diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index cd9fe06a1..b59e43b91 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -549,8 +549,9 @@ $config_misc{'Inventory classes and inventory'} = [ $fsurl.'browse/inventory_cla $config_misc{'Hardware types'} = [ $fsurl.'browse/hardware_class.html', 'Set up hardware type catalog' ] if $curuser->access_right('Configuration'); -$config_misc{'RADIUS Groups'} = [ $fsurl.'browse/radius_group.html', 'Manage RADIUS groups' ] - if $curuser->access_right('Configuration'); +if ( $curuser->access_right('Configuration') ) { + $config_misc{'RADIUS Groups'} = [ $fsurl.'browse/radius_group.html', 'Manage RADIUS groups' ]; + $config_misc{'RADIUS Clients'} = [ $fsurl.'browse/nas.html', 'Manage RADIUS clients' ]; tie my %config_menu, 'Tie::IxHash'; if ( $curuser->access_right('Configuration' ) ) { diff --git a/httemplate/elements/tr-td-label.html b/httemplate/elements/tr-td-label.html index f8473891f..8125541c7 100644 --- a/httemplate/elements/tr-td-label.html +++ b/httemplate/elements/tr-td-label.html @@ -4,7 +4,7 @@ VALIGN = "<% $opt{'valign'} || 'top' %>" STYLE = "<% $style %>" ID = "<% $opt{label_id} || $opt{id}. '_label0' %>" - ><% $opt{label} %> + ><% $required %><% $opt{label} %> <%init> @@ -14,4 +14,6 @@ my $style = 'padding-top: 3px'; $style .= '; '. $opt{'cell_style'} if $opt{'cell_style'}; +my $required = $opt{'required'} ? '* ' : ''; + diff --git a/httemplate/search/elements/search-html.html b/httemplate/search/elements/search-html.html index 8e6546cf8..d1f4b2f1e 100644 --- a/httemplate/search/elements/search-html.html +++ b/httemplate/search/elements/search-html.html @@ -29,42 +29,36 @@ % } % } % -% if ( $type eq 'html-print' ) { - - <% $opt{nohtmlheader} - ? '' - : include( '/elements/header-popup.html', $opt{'title'} ) - %> - -% } elsif ( $type eq 'select' ) { - - <% $opt{nohtmlheader} - ? '' - : include( '/elements/header-popup.html', $opt{'title'} ) - %> - <% defined($opt{'html_init'}) - ? ( ref($opt{'html_init'}) - ? &{$opt{'html_init'}}() - : $opt{'html_init'} - ) - : '' - %> - -% } else { +% unless ( $opt{nohtmlheader} ) { % -% my @menubar = (); -% if ( $opt{'menubar'} ) { -% @menubar = @{ $opt{'menubar'} }; -% #} else { -% # @menubar = ( 'Main menu' => $p ); +% if ( $type eq 'html-print' ) { + <& /elements/header-popup.html, $opt{'title'} &> +% } else { +% if ( $type eq 'select' ) { + <&/elements/header-popup.html, $opt{'title'} &> +% } else { +% +% my @menubar = (); +% if ( $opt{'menubar'} ) { +% @menubar = @{ $opt{'menubar'} }; +% #} else { +% # @menubar = ( 'Main menu' => $p ); +% } + + <& /elements/header.html, $opt{'title'}, + include( '/elements/menubar.html', @menubar ) + &> + +% } % } +% +% } +% +% unless ( $type eq 'html-print' ) { - <% $opt{nohtmlheader} - ? '' - : include( '/elements/header.html', $opt{'title'}, - include( '/elements/menubar.html', @menubar ) - ) - %> +% if ( $opt{'add_link'} ) { #or after html_init? + Add a <% $opt{'name_singular'} %>

+% } <% defined($opt{'html_init'}) ? ( ref($opt{'html_init'}) -- 2.11.0