1package App::Netdisco::Worker::Plugin::Vlan::Core; 2 3use Dancer ':syntax'; 4use App::Netdisco::Worker::Plugin; 5use aliased 'App::Netdisco::Worker::Status'; 6 7use App::Netdisco::Transport::SNMP; 8use App::Netdisco::Util::Port ':all'; 9 10register_worker({ phase => 'early', driver => 'snmp' }, sub { 11 my ($job, $workerconf) = @_; 12 my ($device, $pn) = map {$job->$_} qw/device port/; 13 14 # snmp connect using rw community 15 my $snmp = App::Netdisco::Transport::SNMP->writer_for($device) 16 or return Status->defer("failed to connect to $device to update vlan/pvid"); 17 18 vars->{'iid'} = get_iid($snmp, vars->{'port'}) 19 or return Status->error("Failed to get port ID for [$pn] from $device"); 20 21 return Status->info("Vlan set can continue."); 22}); 23 24register_worker({ phase => 'main', driver => 'snmp' }, sub { 25 my ($job, $workerconf) = @_; 26 return unless defined vars->{'iid'}; 27 _action($job, 'pvid'); 28 return _action($job, 'vlan'); 29}); 30 31sub _action { 32 my ($job, $slot) = @_; 33 my ($device, $pn, $data) = map {$job->$_} qw/device port extra/; 34 35 my $getter = "i_${slot}"; 36 my $setter = "set_i_${slot}"; 37 38 # snmp connect using rw community 39 my $snmp = App::Netdisco::Transport::SNMP->writer_for($device) 40 or return Status->defer("failed to connect to $device to update $slot"); 41 42 my $rv = $snmp->$setter($data, vars->{'iid'}); 43 44 if (!defined $rv) { 45 return Status->error(sprintf 'Failed to set [%s] %s to [%s] on $device: %s', 46 $pn, $slot, $data, ($snmp->error || '')); 47 } 48 49 # confirm the set happened 50 $snmp->clear_cache; 51 my $state = ($snmp->$getter(vars->{'iid'}) || ''); 52 if (ref {} ne ref $state or $state->{ vars->{'iid'} } ne $data) { 53 return Status->error("Verify of [$pn] $slot failed on $device"); 54 } 55 56 # update netdisco DB 57 vars->{'port'}->update({$slot => $data}); 58 59 return Status->done("Updated [$pn] $slot on [$device] to [$data]"); 60} 61 62true; 63