App-Netdisco

 view release on metacpan or  search on metacpan

lib/App/Netdisco/Worker/Plugin/Discover/Neighbors.pm  view on Meta::CPAN

            $device->ip, $port;
          next NEIGHBOR;
      }

      my $remote_ip   = $c_ip_entry;
      my $remote_port = undef;
      my $remote_type = Encode::decode('UTF-8', $c_platform->{$entry} || '');
      my $remote_id   = Encode::decode('UTF-8', $c_id->{$entry});
      my $remote_cap  = $c_cap->{$entry} || [];

      next NEIGHBOR unless $remote_ip;
      my $r_netaddr = NetAddr::IP::Lite->new($remote_ip);

      if ($r_netaddr and ($r_netaddr->addr ne $remote_ip)) {
        debug sprintf ' [%s] neigh - IP on %s: using %s as canonical form of %s',
          $device->ip, $port, $r_netaddr->addr, $remote_ip;
        $remote_ip = $r_netaddr->addr;
      }

      if ($remote_ip and acl_matches($remote_ip, 'group:__LOCAL_ADDRESSES__')) {
          debug sprintf ' [%s] neigh - %s is a non-unique local address - skipping',
            $device->ip, $remote_ip;
          next NEIGHBOR;
      }

      if ($remote_type and match_to_setting($remote_type, 'neighbor_no_type')) {
          debug sprintf ' [%s] neigh - %s has type %s matching neighbor_no_type - skipping',
            $device->ip, $remote_ip, $remote_type;
          next NEIGHBOR;
      }

      # a bunch of heuristics to search known devices if we do not have a
      # useable remote IP...

      if ((! $r_netaddr) or ($remote_ip eq '0.0.0.0') or
        acl_matches($remote_ip, 'group:__LOOPBACK_ADDRESSES__')) {

          if ($remote_id) {
              my $devices = schema('netdisco')->resultset('Device');

              debug sprintf
                ' [%s] neigh - bad address %s on port %s, searching for %s instead',
                $device->ip, $remote_ip, $port, $remote_id;
              my $neigh_rs = $devices->search_rs({name => $remote_id});
              my $neigh = ($neigh_rs->count == 1 ? $neigh_rs->first : undef);

              if (!defined $neigh and $neigh_rs->count) {
                  debug sprintf ' [%s] neigh - multiple devices claim to be %s (port %s) - skipping',
                    $device->ip, $remote_id, $port;
                  next NEIGHBOR;
              }

              if (!defined $neigh) {
                  my $mac = NetAddr::MAC->new(mac => ($remote_id || ''));
                  if ($mac and not $mac->errstr) {
                      $neigh = $devices->single({mac => $mac->as_ieee});
                  }
              }

              # some HP switches send 127.0.0.1 as remote_ip if no ip address
              # on default vlan for HP switches remote_ip looks like
              # "myswitchname(012345-012345)"
              if (!defined $neigh) {
                  (my $tmpid = $remote_id) =~ s/.*\(([0-9a-f]{6})-([0-9a-f]{6})\).*/$1$2/;
                  my $mac = NetAddr::MAC->new(mac => ($tmpid || ''));
                  if ($mac and not $mac->errstr) {
                      debug sprintf
                        ' [%s] neigh - trying to find neighbor %s by MAC %s',
                        $device->ip, $remote_id, $mac->as_ieee;
                      $neigh = $devices->single({mac => $mac->as_ieee});
                  }
              }

              if (!defined $neigh) {
                  (my $shortid = $remote_id) =~ s/\..*//;
                  $neigh = $devices->single({name => { -ilike => "${shortid}%" }});
              }

              if ($neigh) {
                  $remote_ip = $neigh->ip;
                  debug sprintf ' [%s] neigh - found %s with IP %s',
                    $device->ip, $remote_id, $remote_ip;
              }
              else {
                  debug sprintf ' [%s] neigh - could not find %s, skipping',
                    $device->ip, $remote_id;
                  next NEIGHBOR;
              }
          }
          else {
              debug sprintf ' [%s] neigh - skipping unuseable address %s on port %s',
                $device->ip, $remote_ip, $port;
              next NEIGHBOR;
          }
      }

      if (++$success_with_index{$entry} > 1) {
          debug sprintf ' [%s] neigh - port for IID:%s already got a neighbor, skipping',
            $device->ip, $entry;
          next NEIGHBOR;
      }

      # what we came here to do.... discover the neighbor
      debug sprintf ' [%s] neigh - %s with ID [%s] on %s',
        $device->ip, $remote_ip, ($remote_id || ''), $port;

      if (is_discoverable($remote_ip, $remote_type, $remote_cap)) {
          push @to_discover, [$remote_ip, $remote_id];
      }
      else {
          debug sprintf
            ' [%s] neigh - skip: %s of type [%s] excluded by discover_* config',
            $device->ip, $remote_ip, ($remote_type || '');
      }

      $remote_port = $c_port->{$entry};
      if (defined $remote_port) {
          # clean weird characters
          $remote_port =~ s/[^\d\s\/\.,"()\w:-]+//gi;
      }
      else {



( run in 0.726 second using v1.01-cache-2.11-cpan-39bf76dae61 )