App-Netdisco

 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'



( run in 0.760 second using v1.01-cache-2.11-cpan-cc502c75498 )