From 07e8520bace698a17e8a5af0802c1a705f917336 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 4 Jul 2022 22:02:47 +0100 Subject: [PATCH] #881 new addpseudodevice worker action --- bin/netdisco-do | 2 +- .../Netdisco/Worker/Plugin/AddPseudoDevice.pm | 74 +++++++++++++++++++ share/config.yml | 1 + 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 lib/App/Netdisco/Worker/Plugin/AddPseudoDevice.pm diff --git a/bin/netdisco-do b/bin/netdisco-do index 8d3c12a7..7ef24aa3 100755 --- a/bin/netdisco-do +++ b/bin/netdisco-do @@ -124,7 +124,7 @@ if (scalar @hostlist > 512) { foreach my $host (@hostlist) { my $dev = $host ? get_device($host->addr) : undef; - if ($dev and not (blessed $dev and $dev->in_storage) and $action !~ m/^discover/) { + if ($dev and not (blessed $dev and $dev->in_storage) and $action !~ m/^(?:discover|addpseudodevice)/) { info sprintf "%s: error - Don't know device: %s", $action, $host->addr; next; } diff --git a/lib/App/Netdisco/Worker/Plugin/AddPseudoDevice.pm b/lib/App/Netdisco/Worker/Plugin/AddPseudoDevice.pm new file mode 100644 index 00000000..43fa7712 --- /dev/null +++ b/lib/App/Netdisco/Worker/Plugin/AddPseudoDevice.pm @@ -0,0 +1,74 @@ +package App::Netdisco::Worker::Plugin::AddPseudoDevice; + +use Dancer ':syntax'; +use Dancer::Plugin::DBIC; +use App::Netdisco::Worker::Plugin; +use aliased 'App::Netdisco::Worker::Status'; + +use App::Netdisco::Util::DNS 'hostname_from_ip'; +use App::Netdisco::Util::Statistics 'pretty_version'; +use NetAddr::IP::Lite ':lower'; + +register_worker({ phase => 'check' }, sub { + my ($job, $workerconf) = @_; + my $devip = $job->device->ip; + my $name = $job->extra; + my $ports = $job->port; + + return Status->error('Missing or invalid device name (-e).') + unless $name + and $name =~ m/^[[:print:]]+$/ + and $name !~ m/[[:space:]]/; + + my $ip = NetAddr::IP::Lite->new($devip); + return Status->error('Missing or invalid device IP (-d).') + unless ($ip and $ip->addr ne '0.0.0.0'); + + return Status->error('Missing or invalid number of device ports (-p).') + unless $ports + and $ports =~ m/^[[:digit:]]+$/; + + return Status->done('Pseudo Devive can be added'); +}); + +register_worker({ phase => 'main' }, sub { + my ($job, $workerconf) = @_; + my $devip = $job->device->ip; + my $name = $job->extra; + my $ports = $job->port; + + schema('netdisco')->txn_do(sub { + my $device = schema('netdisco')->resultset('Device') + ->create({ + ip => $devip, + dns => (hostname_from_ip($devip) || ''), + name => $name, + vendor => 'netdisco', + model => 'pseudodevice', + num_ports => $ports, + os => 'netdisco', + os_ver => pretty_version($App::Netdisco::VERSION, 3), + layers => '00000100', + last_discover => \'now()', + is_pseudo => \'true', + }); + return unless $device; + + $device->ports->populate([ + [qw/port type descr/], + map {["Port$_", 'other', "Port$_"]} @{[1 .. $ports]}, + ]); + + # device_ip table is used to show whether topo is "broken" + schema('netdisco')->resultset('DeviceIp') + ->create({ + ip => $devip, + alias => $devip, + }); + }); + + return Status->done( + sprintf "Pseudo Devive %s (%s) added", $devip, $name); +}); + +true; diff --git a/share/config.yml b/share/config.yml index 64fb3248..24c2a543 100644 --- a/share/config.yml +++ b/share/config.yml @@ -396,6 +396,7 @@ job_prio: - stats worker_plugins: + - 'AddPseudoDevice' - 'Arpnip' - 'Arpnip::Hooks' - 'Arpnip::Nodes'