* Add macsuck worker to collect various PortAccessEntity (NAC) attributes * Incorporate PAE feedback on #937 * missing Result/Device.pm column added * pae_is... columns instead of pae_capabilities * moved most code to Util/PortAccessEntity.pm so the update can be done in discover and macsuck * Refactor PAE attributes during discover as separate Plugin * PortAccessEntity: don't use device->dns in log string * Fix "Experimental keys on scalar is now forbidden" test failure * Revamp pae_control and add missing attribute - device.pae_control (text) is now device.pae_is_enabled (bool) - also store pae_authconfig_port_control (port mode auto/force(un)Auth) * Fix "Experimental keys on scalar is now forbidden" test failure - ... again because of botched merge - at least perlgolfed away a set of curly braces * Update PortAccessEntity.pm * Incorporate @ollyg PR feedback * allow actions without transport to run when there are also no creds * initial refactor for separate gather, process, store phases for macsuck * factor out the vlan sanity check * additional help with log of action workers * cleanup logic in check macsuck * refactor to make main phases only * some fixes * implement file slurp. amazingly the whole thing works * remove outdated noop from test * treat error as critical, use cancel to suppress further drivers * big refactor to share mac sanity code to both paths * fix inverted logic on vlan sanity filter * some code tidy * fix error in default value * fix for vlan 0 nodes input from cli * ensure imported MACs are IEEE format * add api endpoint, no useful return status yet * exit status if error from nodes PUT * suppress other networked workers when direct workers are active * better log showing worker * fix status recording to get first error or last done message * implement arpnip API PUT * avoid package redeclaration error * make sure write API methods require admin status * add doc for passing JSON data to arpnip and macsuck * update manifest * remove option to do jobs in web handler; all by queue now * use job entry timestamp for offline queued jobs * fix store username and IP on api PUT * never de-duplicate user-submitted jobs; never reset DeviceSkip for offline jobs * myworker no longer needed * make logic cleaner Co-authored-by: Christian Ramseyer <ramseyer@netnea.com>
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| #!/usr/bin/env perl
 | |
| 
 | |
| use strict; use warnings;
 | |
| 
 | |
| BEGIN { $ENV{DANCER_ENVDIR} = '/dev/null'; }
 | |
| 
 | |
| use Test::More 0.88;
 | |
| use Test::File::ShareDir::Dist { 'App-Netdisco' => 'share/' };
 | |
| 
 | |
| use lib 'xt/lib';
 | |
| 
 | |
| use App::Netdisco;
 | |
| use App::Netdisco::DB; # fake device row
 | |
| use App::Netdisco::Backend::Job;
 | |
| 
 | |
| use Try::Tiny;
 | |
| use Dancer qw/:moose :script !pass/;
 | |
| 
 | |
| # configure logging to force console output
 | |
| my $CONFIG = config();
 | |
| $CONFIG->{logger} = 'console';
 | |
| $CONFIG->{log} = ($ENV{'DANCER_DEBUG'} ? 'debug' : 'error');
 | |
| Dancer::Logger->init('console', $CONFIG);
 | |
| 
 | |
| {
 | |
|   package MyWorker;
 | |
|   use Moo;
 | |
|   with 'App::Netdisco::Worker::Runner';
 | |
| }
 | |
| 
 | |
| # clear user device_auth and set our own
 | |
| config->{'device_auth'} = [{driver => 'snmp'}, {driver => 'cli'}];
 | |
| 
 | |
| # TESTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| my $j1 = do_job('TestOne');
 | |
| is($j1->status, 'done', 'status is done');
 | |
| is($j1->log, 'OK: SNMP driver is successful.',
 | |
|   'workers are run in decreasing priority until done');
 | |
| 
 | |
| my $j2 = do_job('TestTwo');
 | |
| is($j2->status, 'done', 'status is done');
 | |
| is($j2->log, 'OK: CLI driver is successful.',
 | |
|   'lower priority driver not run if higher is successful');
 | |
| 
 | |
| config->{'device_auth'} = [];
 | |
| 
 | |
| my $j3 = do_job('TestOne');
 | |
| is($j3->status, 'defer', 'status is defer');
 | |
| is($j3->log, 'deferred job with no device creds',
 | |
|   'no matching config for workers');
 | |
| 
 | |
| config->{'device_auth'} = [{driver => 'snmp'}];
 | |
| 
 | |
| my $j4 = do_job('TestThree');
 | |
| is($j4->status, 'done', 'status is done');
 | |
| is($j4->log, 'OK: SNMP driver is successful.',
 | |
|   'respect user config filtering the driver');
 | |
| 
 | |
| config->{'device_auth'} = [
 | |
|   {driver => 'snmp', action => 'testthree'},
 | |
|   {driver => 'cli',  action => 'foo'},
 | |
| ];
 | |
| 
 | |
| my $j5 = do_job('TestThree');
 | |
| is($j5->status, 'done', 'status is done');
 | |
| is($j5->log, 'OK: SNMP driver is successful.',
 | |
|   'respect user config filtering the action');
 | |
| 
 | |
| config->{'device_auth'} = [
 | |
|   {driver => 'snmp', action => 'testthree::_base_'},
 | |
|   {driver => 'cli',  action => 'testthree::foo'},
 | |
| ];
 | |
| 
 | |
| my $j6 = do_job('TestThree');
 | |
| is($j6->status, 'done', 'status is done');
 | |
| is($j6->log, 'OK: SNMP driver is successful.',
 | |
|   'respect user config filtering the namespace');
 | |
| 
 | |
| config->{'device_auth'} = [{driver => 'snmp'}];
 | |
| 
 | |
| my $j7 = do_job('TestFour');
 | |
| is($j7->status, 'done', 'status is done');
 | |
| is($j7->log, 'OK: custom driver is successful.',
 | |
|   'override an action');
 | |
| 
 | |
| config->{'device_auth'} = [{driver => 'snmp'}];
 | |
| 
 | |
| my $j8 = do_job('TestFive');
 | |
| is($j8->status, 'done', 'status is done');
 | |
| is((scalar @{$j8->_statuslist}), 2, 'two workers ran');
 | |
| is($j8->_last_priority, 100, 'priority is for snmp');
 | |
| is($j8->log, 'OK: SNMP driver is successful.',
 | |
|   'add to an action');
 | |
| 
 | |
| config->{'device_auth'} = [];
 | |
| 
 | |
| my $j9 = do_job('TestSix');
 | |
| is($j9->status, 'done', 'status is done');
 | |
| is((scalar @{$j9->_statuslist}), 3, 'three workers ran');
 | |
| is($j9->_last_priority, 0, 'priority is for driverless action');
 | |
| is($j9->log, 'OK: second driverless action is successful.',
 | |
|   'driverless actions always run');
 | |
| 
 | |
| my $j9 = do_job('TestSeven');
 | |
| is($j9->best_status, 'error', 'status is error');
 | |
| is((scalar @{$j9->_statuslist}), 2, 'two workers ran');
 | |
| is($j9->_last_priority, 1000000, 'priority is for direct action');
 | |
| 
 | |
| done_testing;
 | |
| 
 | |
| # TESTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| sub do_job {
 | |
|   my $pkg = shift;
 | |
| 
 | |
|   # include local plugins
 | |
|   config->{'extra_worker_plugins'} = ["X::${pkg}"];
 | |
| 
 | |
|   my $job = App::Netdisco::Backend::Job->new({
 | |
|     job => 0,
 | |
|     device => App::Netdisco::DB->resultset('Device')->new_result({ip => '192.0.2.1'}),
 | |
|     action => lc($pkg),
 | |
|   });
 | |
| 
 | |
|   try {
 | |
|     #info sprintf 'test: started at %s', scalar localtime;
 | |
|     MyWorker->new()->run($job);
 | |
|     #info sprintf 'test: %s: %s', $job->status, $job->log;
 | |
|   }
 | |
|   catch {
 | |
|     $job->status('error');
 | |
|     $job->log("error running job: $_");
 | |
|   };
 | |
| 
 | |
|   return $job;
 | |
| }
 |