Administration Panel

<& SELF:err &> % if ($need_confirm) { <& SELF:confirm &> % } else { <& SELF:dev_control &> % } <& SELF:list_queue &>
<%args> $dev => undef $dev_text => undef $discover => undef $cmd => 'add' $debug => '' $action => '' @logs => () $nodes => '' $confirm => '' $old_jobs => '' $port => '' @act_ignore => () <%shared> my $user = $m->session->{user}; my $domain = $netdisco::CONFIG{domain}; my %actions = ( # action => [longname, confirm action,show] 'discover' => ['Discover Device',0,0], 'discover_run'=> ['Discover Whole Network Starting from Device',1,0], 'discover_new'=> ['Discover New Parts of Network from Device',1,0], 'arpnip' => ['ArpNip Device',0,1], 'delete' => ['Delete Device',1,1], 'macsuck' => ['MacSuck Device',0,1], 'nodes-del' => ['Delete Nodes',1,1], 'nodes-arc' => ['Archive Nodes',1,1], 'refresh' => ['Refresh Device',0,1], 'expire_ips' => ['Database Cleanup - Expire IPs [-I]',1,0], 'graph' => ['Regenerate Graph',1,0], 'arpwalk' => ['ArpNip whole network',1,0], 'macwalk' => ['MacSuck whole network',1,0], 'nbtwalk' => ['NBTWalk whole network',1,0], 'backup' => ['Run Nightly Backup',1,0], 'clean_nodes' => ['Database Cleanup - Nodes [-K]',1,0], 'clean_alias' => ['Database Cleanup - Aliases [-k]',1,0] ); # Globals my ($arg_dev,$arg_debug,$db_dev,$arg_act,$devices,$queue,$subaction,$action_types,$arg_dev_text,$arg_discover,$arg_cmd); my $arg_jobs; my $need_confirm = 0; my $commit = 0; my $odd = 0; my %logs = (); my $err = ''; my @act_ignore_default = qw/portcontrol test/; my @arg_ignore; %# %# <%init> # Enforce secure + admin $m->comp('admin.html:force_secure_admin'); # Move args to shared space for methods $arg_dev = $dev; $arg_act = $action; $arg_cmd = $cmd; @arg_ignore = @act_ignore; $arg_jobs = $old_jobs; $arg_debug = $debug; $arg_discover = $discover; @act_ignore = @act_ignore_default unless scalar @act_ignore ; %logs = map {$_ => 1} @logs; my @devs; #..................... Device Control ............................. # Load dev from db if given if ($dev){ if(ref($dev) eq "ARRAY"){ for my $i (@$dev){ my $dip=getip($i); push @devs,sql_hash('device',['ip','dns','layers'],{'ip'=>$dip}) if $dip; } } else { $dev = getip($dev); my $dns = hostname($dev); $dns =~ s/\Q$domain\E//; $arg_dev_text = $dns if (defined $dev and defined $dns); $db_dev = sql_hash('device',['ip','dns','layers'],{'ip'=>$dev}) if $dev; } } elsif ($dev_text){ # Resolve user entered device name to device_ip $dev=getip($dev_text); $arg_dev = $dev; $arg_dev_text = $dev_text if defined $dev; $db_dev = sql_hash('device',['ip','dns','layers'],{'ip'=>$dev}) if $dev; } # Confirm Given Action if required if ($cmd eq 'add' and $actions{$action}->[1] and $confirm ne 'ok') { # Selecting multiple devices currently not supported on commands needing confirmation if (@devs) { $err .= "Selecting multiple devices not supported with $actions{$action}->[0] action.
\n"; $action = undef; $arg_dev = $dev = undef; } else { $need_confirm++; } } # Maintenance Commands from admin.html if ($cmd eq 'add' and $action =~ /^(expire_ips|arpwalk|macwalk|nbtwalk|graph|backup|clean_nodes|clean_alias)$/ and !$need_confirm){ $dev = undef; $commit++; } # Refresh / MacSuck / Arpnip if ($cmd eq 'add' and $action =~ /^(refresh|macsuck|arpnip)$/ and !$need_confirm){ if(@devs){ my @devs_checked; for my $i (@devs){ my $layers = $i->{layers}; if ($action eq 'macsuck' and !&netdisco::has_layer($layers,2) ){ $err .= sprintf("Device %s does not support mac_sucking, skipping.
\n", $i->{ip}); } elsif ($action eq 'arpnip' and !&netdisco::has_layer($layers,3) ){ $err .= sprintf("Device %s does not support arp_niping, skipping.
\n", $i->{ip}); } else { push(@devs_checked, $i); } } # Add Entries to Queue @devs = @devs_checked; $commit += scalar @devs; @devs = $arg_dev = $dev = undef unless $commit; } else { # Verify device exists. unless (defined $db_dev->{ip}){ $err .= "Device ($dev) not found in Database.
\n"; $action = undef; $arg_dev = $dev = undef; } # Verify macsuck/arpnip is possible on device. my $layers = $db_dev->{layers}; if ($action eq 'macsuck' and !&netdisco::has_layer($layers,2) ){ $err .= "Device does not support mac_sucking.
\n"; $action = undef; $arg_dev = $dev = undef; } if ($action eq 'arpnip' and !&netdisco::has_layer($layers,3) ){ $err .= "Device does not support arp_niping.
\n"; $action = undef; $arg_dev = $dev = undef; } # Add Entry to Queue $commit++ unless $err; } } # Delete if ($cmd eq 'add' and $action eq 'delete' and $confirm eq 'ok'){ # Verify device exists. unless (defined $db_dev->{ip}){ $err .= "Device not found in Database.
\n"; $action = undef; } # Add to queue. unless ($err) { $err .= "Device $dev marked for deletion.
\n"; $action = $nodes eq 'ok' ? 'delete+nodes' : 'delete'; $commit++; } } # Archive/Delete Nodes if ($cmd eq 'add' and $action =~ /^nodes/ and $confirm eq 'ok'){ # Verify device exists. unless (defined $db_dev->{ip}){ $err .= "Device ($dev) not found in Database.
\n"; $action = undef; $arg_dev = $dev = undef; } # Port Only if ($port !~ /^\s*$/){ my $port = sql_hash('device_port',['port'],{'ip'=>$dev,'port'=>$port}); unless (defined $port and $port->{port}){ $err .= "$actions{$action}->[0] - $dev - Port $port not found!
\n"; $action = undef; $arg_dev = $dev = undef; } else { # Restict to Port $subaction = $port->{port}; } } $commit++ unless $err; } # Discover Devices if ($cmd eq 'add' and $action =~ /^(discover|discover_new|discover_run)$/ and !$need_confirm){ # Check input unless (defined $discover and length($discover)){ $err .= "Please enter the device IP or DNS name to discover.
\n"; $discover = $discover = undef; } else { $subaction = $discover; $dev = undef; $discover = $discover = undef; $commit++; } } # Add to Queue if ($commit) { if(@devs){ for my $i (@devs){ next unless defined $i; $err .= "Action Queued - $action"; $err .= " For Device $i->{ip}."; $err .= "
\n"; insert_or_update('admin',{}, {'device'=>$i->{ip},'action'=>$action, 'status' => 'queued', 'username' => $user, 'debug' => ($debug eq 'yes' ? 1 : 0), 'subaction' => $subaction } ); } } else { $err .= "Action Queued - $action"; $err .= " For Device $dev." if $dev; $err .= "
\n"; insert_or_update('admin',{}, {'device'=>$dev,'action'=>$action, 'status' => 'queued', 'username' => $user, 'debug' => ($debug eq 'yes' ? 1 : 0), 'subaction' => $subaction } ); } @devs=undef; $action = undef; $arg_dev = $dev = undef; } #............ Job Queue ............ # job queue is after device control in case we just added to it. # Load device list, unless device provided. $devices = sql_rows('device',['ip','dns'], undef, undef,'order by ip asc') if not defined $arg_dev; # Taint check (head between legs) $old_jobs = 5 unless ($old_jobs =~ /^\d+$/); # Fetch action types - Changed to static values, be sure to add new ones here $action_types = ['arpnip', 'arpwalk', 'delete', 'delete+nodes', 'discover', 'graph', 'macsuck', 'macwalk', 'nbtwalk', 'portcontrol', 'refresh']; # Create NOT IN list if we are ignoring certain types. my $where = {}; my @ignore = @act_ignore; $ignore[0] = "!$ignore[0]" if scalar @ignore; $where->{action} = [\@ignore] if scalar @ignore; # Fetch running jobs $where->{status} = [['queued','running']]; $queue = sql_rows('admin',['job','extract(epoch from entered) as entered','extract(epoch from finished) as finished', 'extract(epoch from started) as started','device','action','status','username'], $where); # Fetch done jobs. $where->{status} = [['done','error']]; my $done = sql_rows('admin',['job','extract(epoch from entered) as entered','extract(epoch from finished) as finished', 'extract(epoch from started) as started','device','action','status','username'], $where,undef,"order by admin.entered desc limit $old_jobs"); push (@$queue,@$done); # Log entries are fetched separately, as these can be rather large, and should # only be loaded if needed. foreach my $item (@$queue){ my $id = $item->{job}; if (defined $logs{$id}){ my $log = sql_scalar('admin',['log'],{'job'=>$id}); $item->{log} = $log; } } %# %# err() - Prints out the error string if it exists. %# <%method err> % return unless $err;

<%$err%>

%# %# confirm() - Creates a confirmation page for certain actions %# <%method confirm> % my $act = $actions{$arg_act}->[0];

Confirm <%$act%> <% $arg_dev ? "of $arg_dev" : ''%>

Check to Confirm - <%$act%> % if ($arg_dev) { - <%$arg_dev%> % }
%# Action specific check options: %# %# Delete Device - Checkbox to Delete Nodes too % if ($arg_act eq 'delete'){ Delete Nodes Too. % } %# Delete Nodes - Ability to select port % if ($arg_act =~ /^nodes/) { % my $ports = sql_rows('device_port',['port'],{'ip'=>$arg_dev}); Restrict <%$act%> to %}
> Debug Output

">

%# %# dev_control() - Prints out the device control menu form. %# <%method dev_control>

Device Control

Discover Devices

%# %# list_dev() - Create % foreach my $dev (sort {$a->{dns} cmp $b->{dns}} @$devices){ % my $view = defined $dev->{dns} ? $dev->{dns} : $dev->{ip}; % $view =~ s/\Q$domain\E//;