view release on metacpan or search on metacpan
lib/App/Netdisco/DB/Result/DeviceVlan.pm view on Meta::CPAN
Link relationship for C<tagged_ports>, see below.
=cut
__PACKAGE__->has_many( port_vlans_tagged => 'App::Netdisco::DB::Result::DevicePortVlan',
sub {
my $args = shift;
return {
"$args->{foreign_alias}.ip" => { -ident => "$args->{self_alias}.ip" },
"$args->{foreign_alias}.vlan" => { -ident => "$args->{self_alias}.vlan" },
-not_bool => "$args->{foreign_alias}.native",
};
},
{ cascade_copy => 0, cascade_update => 0, cascade_delete => 0 }
);
=head2 port_vlans_untagged
Link relationship to support C<untagged_ports>, see below.
=cut
lib/App/Netdisco/JobQueue/PostgreSQL.pm view on Meta::CPAN
-and => [
{ 'me.started' => { '!=' => undef } },
{ 'me.finished' => { '!=' => undef } },
\[ q{ (me.finished - me.started) > ? ::interval }, param('duration') .' minutes'],
],
],
],
) : ()),
'me.log' => [
{ '=' => undef },
{ '-not_like' => 'duplicate of %' },
],
}, {
prefetch => 'target',
order_by => { -desc => [qw/entered device action/] },
rows => (setting('jobs_qdepth') || 50),
})->with_times->hri->all;
}
sub jq_userlog {
my $user = shift;
return schema(vars->{'tenant'})->resultset('Admin')->search({
username => $user,
log => { '-not_like' => 'duplicate of %' },
finished => { '>' => \"(CURRENT_TIMESTAMP - interval '5 seconds')" },
})->with_times->all;
}
sub jq_insert {
my $jobs = shift;
$jobs = [$jobs] if ref [] ne ref $jobs;
my $happy = false;
try {
lib/App/Netdisco/Web.pm view on Meta::CPAN
forward '/';
};
any '/t/*/**' => sub {
my ($tenant, $path) = splat;
var tenant => $tenant;
forward (join '/', '', @$path, (request->path =~ m{/$} ? '' : ()));
};
any qr{.*} => sub {
var('notfound' => true);
status 'not_found';
template 'index', {}, { layout => 'main' };
};
true;
lib/App/Netdisco/Web/API/Queue.pm view on Meta::CPAN
my @set = schema(vars->{'tenant'})->resultset('Admin')->search({
( param('device') ? ( device => param('device') ) : () ),
( param('port') ? ( port => param('port') ) : () ),
( param('action') ? ( action => param('action') ) : () ),
( param('status') ? ( status => param('status') ) : () ),
( param('username') ? ( username => param('username') ) : () ),
( param('userip') ? ( userip => param('userip') ) : () ),
( param('backend') ? ( backend => param('backend') ) : () ),
-or => [
{ 'log' => undef },
{ 'log' => { '-not_like' => 'duplicate of %' } },
],
}, {
order_by => { -desc => [qw/entered device action/] },
rows => (param('limit') || setting('jobs_qdepth') || 50),
})->with_times->hri->all;
return to_json \@set;
};
swagger_path {
lib/App/Netdisco/Web/Plugin/Device/Ports.pm view on Meta::CPAN
if (param('partial')) {
# change wildcard chars to SQL
$f =~ s/\*/%/g;
$f =~ s/\?/_/g;
# set wildcards at param boundaries
if ($f !~ m/[%_]/) {
$f =~ s/^\%*/%/;
$f =~ s/\%*$/%/;
}
# enable ILIKE op
$f = { (param('invert') ? '-not_ilike' : '-ilike') => $f };
}
elsif (param('invert')) {
$f = { '!=' => $f };
}
if (($prefer eq 'port') or not $prefer and
$set->search({-or => ['me.port' => $f, 'me.descr' => $f]})->count) {
$set = $set->search({
-or => [
lib/App/Netdisco/Web/Plugin/Search/Port.pm view on Meta::CPAN
get '/ajax/content/search/port' => require_login sub {
my $q = param('q');
send_error( 'Missing query', 400 ) unless $q;
my $rs;
if ($q =~ m/^[0-9]+$/ and $q < 4096) {
$rs = schema(vars->{'tenant'})->resultset('DevicePort')
->columns( [qw/ ip port name up up_admin speed /] )->search({
"port_vlans.vlan" => $q,
( param('uplink') ? () : (-or => [
{-not_bool => "properties.remote_is_discoverable"},
{-or => [
{-not_bool => "me.is_uplink"},
{"me.is_uplink" => undef},
]}
]) ),
( param('ethernet') ? ("me.type" => 'ethernetCsmacd') : () ),
},{ '+columns' => [qw/ device.dns device.name port_vlans.vlan /],
join => [qw/ properties port_vlans device /]
}
)->with_times;
}
else {
lib/App/Netdisco/Web/Plugin/Search/Port.pm view on Meta::CPAN
: { 'me.mac' => $mac->as_ieee }
),
{ "properties.remote_dns" => $likeclause },
( param('uplink') ? (
{ "me.remote_id" => $likeclause },
{ "me.remote_type" => $likeclause },
) : () ),
],
( param('uplink') ? () : (-or => [
{ "properties.remote_dns" => $likeclause },
{-not_bool => "properties.remote_is_discoverable"},
{-or => [
{-not_bool => "me.is_uplink"},
{"me.is_uplink" => undef},
]}
]) ),
( param('ethernet') ? ("me.type" => 'ethernetCsmacd') : () ),
]
},
{ '+columns' => [qw/ device.dns device.name /, {vlan_agg => q{array_to_string(array_agg(port_vlans.vlan), ', ')}} ],
join => [qw/ properties port_vlans device /],
group_by => [qw/me.ip me.port me.name me.up me.up_admin me.speed device.dns device.name device.last_discover device.uptime properties.remote_dns/],
}
lib/App/Netdisco/Worker/Plugin/Discover/Neighbors.pm view on Meta::CPAN
schema('netdisco')->txn_do(sub {
# clear manual topology flags
schema('netdisco')->resultset('DevicePort')
->search({ip => $device->ip})->update({manual_topo => \'false'});
# clear outdated manual topology links
my $old_links = schema('netdisco')->resultset('Topology')->search({
-or => [
{ dev1 => $device->ip,
port1 => { '-not_in' => $device->ports->get_column('port')->as_query } },
{ dev2 => $device->ip,
port2 => { '-not_in' => $device->ports->get_column('port')->as_query } },
],
})->delete;
debug sprintf ' [%s] neigh - removed %d outdated manual topology links',
$device->ip, $old_links;
my $topo_links = schema('netdisco')->resultset('Topology')
->search({-or => [dev1 => $device->ip, dev2 => $device->ip]});
debug sprintf ' [%s] neigh - setting manual topology links', $device->ip;
while (my $link = $topo_links->next) {
lib/App/Netdisco/Worker/Plugin/Expire.pm view on Meta::CPAN
register_worker({ phase => 'main' }, sub {
my ($job, $workerconf) = @_;
if (setting('expire_devices') and ref {} eq ref setting('expire_devices')) {
foreach my $acl (keys %{ setting('expire_devices') }) {
my $days = setting('expire_devices')->{$acl};
schema('netdisco')->txn_do(sub {
my @hostlist = schema('netdisco')->resultset('Device')->search({
-not_bool => 'is_pseudo',
last_discover => \[q/< (LOCALTIMESTAMP - ?::interval)/,
($days * 86400)],
})->get_column('ip')->all;
foreach my $ip (@hostlist) {
next unless acl_matches_only($ip, $acl);
jq_insert([{
device => $ip,
action => 'delete',
lib/App/Netdisco/Worker/Plugin/Expire.pm view on Meta::CPAN
schema('netdisco')->txn_do(sub {
my $freshness = ((defined setting('expire_nodeip_freshness'))
? setting('expire_nodeip_freshness') : setting('expire_nodes_archive'));
if ($freshness) {
schema('netdisco')->resultset('NodeIp')->search({
time_last => \[q/< (LOCALTIMESTAMP - ?::interval)/, ($freshness * 86400)],
})->delete();
}
schema('netdisco')->resultset('Node')->search({
-not_bool => 'active',
time_last => \[q/< (LOCALTIMESTAMP - ?::interval)/,
(setting('expire_nodes_archive') * 86400)],
})->delete();
});
}
# also have to clean up node_ip that have no correspoding node
schema('netdisco')->resultset('NodeIp')->search({
mac => { -in => schema('netdisco')->resultset('NodeIp')->search(
{ port => undef },
lib/App/Netdisco/Worker/Plugin/Macsuck/Nodes.pm view on Meta::CPAN
' [%s] macsuck %s - seen another device thru port %s - skipping.',
$device->ip, $mac, $port;
delete $cache->{$vlan}->{$port}->{$mac};
next MAC;
}
# check to see if the port is connected to another device
# and if we have that device in the database.
#Â carefully be aware: "uplink" here means "connected to another device"
#Â it does _not_ mean that the user wants nodes gathered on the remote dev.
# we have two ways to detect "uplink" port status:
# * a neighbor was discovered using CDP/LLDP
# * a mac addr is seen which belongs to any device port/interface
# allow to gather MACs on upstream (local) port for some kinds
# of device that do not expose MAC address tables via SNMP.
# relies on prefetched neighbors otherwise it would kill the DB
# with device lookups.
my $neigh_cannot_macsuck = eval { # can fail
acl_matches(($device_port->neighbor || "0 but true"), 'macsuck_unsupported') ||
match_to_setting($device_port->remote_type, 'macsuck_unsupported_type') };
#Â here, is_uplink comes from Discover::Neighbors finding LLDP remnants
if ($device_port->is_uplink) {
if ($neigh_cannot_macsuck) {
debug sprintf
' [%s] macsuck %s - port %s neighbor %s without macsuck support',
$device->ip, $mac, $port,
(eval { $device_port->neighbor->ip }
|| ($device_port->remote_ip
|| $device_port->remote_id || '?'));
# continue!!
}
elsif (my $neighbor = $device_port->neighbor) {
debug sprintf
lib/App/Netdisco/Worker/Plugin/Macsuck/Nodes.pm view on Meta::CPAN
' [%s] macsuck %s - port %s connects to self - skipping.',
$device->ip, $mac, $port;
delete $cache->{$vlan}->{$port}->{$mac};
next MAC;
}
debug sprintf ' [%s] macsuck %s - port %s is probably an uplink',
$device->ip, $mac, $port;
$device_port->update({is_uplink => \'true'});
if ($neigh_cannot_macsuck) {
# neighbor exists and Netdisco can speak to it, so we don't want
# its MAC address. however don't add to neighborport as that would
# clear all other MACs on the port.
delete $cache->{$vlan}->{$port}->{$mac};
next MAC;
}
# when there's no CDP/LLDP, we only want to gather macs at the
# topology edge, hence skip ports with known device macs.
if (not setting('macsuck_bleed')) {
lib/App/Netdisco/Worker/Plugin/PortControl.pm view on Meta::CPAN
my ($job, $workerconf) = @_;
my ($device, $pn) = map {$job->$_} qw/device port/;
# need to remove "-other" which appears for power/portcontrol
(my $sa = $job->subaction) =~ s/-\w+//;
$job->subaction($sa);
if ($sa eq 'bounce') {
$job->subaction('down');
my $status = _action($job);
return $status if $status->not_ok;
$job->subaction('up');
}
return _action($job);
});
sub _action {
my $job = shift;
my ($device, $pn, $data) = map {$job->$_} qw/device port subaction/;
lib/App/Netdisco/Worker/Status.pm view on Meta::CPAN
sub error { shift->_make_new('error', @_) } #Â <- jq_complete
=head2 is_ok
Returns true if status is C<done>.
=cut
sub is_ok { return $_[0]->status eq 'done' }
=head2 not_ok
Returns true if status is C<error>, C<defer>, or C<info>.
=cut
sub not_ok { return (not $_[0]->is_ok) }
=head2 level
A numeric constant for the status, to allow comparison.
=cut
sub level {
my $self = shift;
return (($self->status eq 'error') ? 4
share/python/netdisco/netdisco/util/status.py view on Meta::CPAN
@dataclass(frozen=True)
class StatusManager:
status: str = ''
log: str = ''
def is_ok(self) -> bool:
return True if self.status == 'done' else False
def not_ok(self) -> bool:
return not self.is_ok()
def level(self) -> int:
return (
4
if self.status == 'error'
else 3
if self.status == 'done'
else 2
if self.status == 'defer'