support list or dict for device_identity

This commit is contained in:
Oliver Gorwits
2017-05-29 16:11:39 +01:00
parent 5daf1805c7
commit efe669c0e6
3 changed files with 55 additions and 34 deletions

View File

@@ -66,6 +66,12 @@ if (exists setting('workers')->{interactives}
setting('dns')->{hosts_file} ||= '/etc/hosts';
setting('dns')->{no} ||= ['fe80::/64','169.254.0.0/16'];
# support unordered dictionary as if it were a single item list
if (ref {} eq ref setting('device_identity')) {
config->{'device_identity'} = [ setting('device_identity') ];
}
else { config->{'device_identity'} ||= [] }
# legacy config item names
config->{'devport_vlan_limit'} =

View File

@@ -55,12 +55,16 @@ sub set_canonical_ip {
my $revofname = ipv4_from_hostname($snmp->name);
if (setting('reverse_sysname') and $revofname) {
if ($snmp->snmp_connect_ip( $new_ip )) {
$new_ip = $revofname;
}
else {
debug sprintf ' [%s] device - cannot renumber to %s - SNMP connect failed',
$old_ip, $revofname;
}
}
if (ref [] eq ref setting('device_identity')
and scalar @{ setting('device_identity') }) {
if (scalar @{ setting('device_identity') }) {
my @idmaps = @{ setting('device_identity') };
my $devips = $device->device_ips->order_by('alias');
@@ -70,27 +74,27 @@ sub set_canonical_ip {
foreach my $map (@idmaps) {
next unless ref {} eq ref $map;
foreach my $key (keys %$map) {
foreach my $key (sort keys %$map) {
# lhs matches device, rhs matches device_ip
if (check_acl($device, $key)
and check_acl($alias, $map->{$key})) {
if ($snmp->snmp_connect_ip( $alias->alias )) {
$new_ip = $alias->alias;
last ALIAS;
}
else {
debug sprintf ' [%s] device - cannot renumber to %s - SNMP connect failed',
$old_ip, $alias->alias;
}
}
}
}
} # ALIAS
}
return if $new_ip eq $old_ip;
if (not $snmp->snmp_connect_ip( $new_ip )) {
# should be warning or error?
debug sprintf ' [%s] device - cannot change IP to %s - SNMP connect failed',
$old_ip, $device->ip;
return;
}
schema('netdisco')->txn_do(sub {
$device->renumber($new_ip)
or die "cannot renumber to: $new_ip"; # rollback

View File

@@ -607,16 +607,16 @@ for L</"ACCESS CONTROL LISTS">.
=head3 C<device_identity>
Value: List of Access Control List mappings. Default: None.
Value: Dictionary of Access Control List mappings. Default: None.
This setting allows you to control the canonical name or identity of devices
in Netdisco. For example if Netdisco discovers devices and uses the "wrong"
interface to identfy them (thereby confusing users) you can correct that here.
The C<device_identity> setting is a list of dictionaries. For each dictionary,
the key is an Access Control List matching a device and the value is another
Access Control List matching one of the device's interfaces to use as the
device canonical identity. The format of Access Control Lists is described in
The C<device_identity> setting is a dictionary where each key is an Access
Control List matching a device and the corresponding value is another Access
Control List matching one of the device's interfaces to use as the device
canonical identity. The format of Access Control Lists is described in
L</"ACCESS CONTROL LISTS">.
In general, because the key of a dictionary must be a simple text string, you
@@ -631,10 +631,10 @@ placed in a C<host_groups> entry and referenced by name. For example:
- 'model:.*(?i:DCS7508).*'
device_identity:
- 'group:backbone_devices':
'group:backbone_devices':
- !!perl/regexp ^.*\.backbone\.example\.com$
- '172.16.20.0/24'
- 'vendor:cisco': '192.0.2.0/24'
'vendor:cisco': '192.0.2.0/24'
During "discover" jobs, Netdisco will find all entries in C<device_identity>
where the I<key> matches the device in some way. For those entries, the
@@ -649,7 +649,7 @@ all Arista devices to the IP and host name of their Mgmt1 interface (if they
have one), you could use:
device_identity:
- 'vendor:arista': 'port:(?i)mgmt1'
'vendor:arista': 'port:(?i)mgmt1'
Once a device is renumbered, its new identity is "sticky". That is, you could
remove the C<device_identity> configuration and the next "discover" job will
@@ -662,7 +662,18 @@ together with the "C<op:and>" modifier to require that all items in the list
match the device (as in the example above).
Note also that whatever interface you select as canonical for the device must
be reachable by SNMP. This is tested and the renumber aborted if not possible.
be reachable by SNMP. A failed connection to a matching interfaces does not
abort the whole process - other interfaces are still teted.
Netdisco will evaluate clauses in C<device_identity> in a random order. If you
need to control this sequence, pass a list of single-key dictionaries instead
of one multi-key dictionary. The above example could then become:
device_identity:
- 'group:backbone_devices':
- !!perl/regexp ^.*\.backbone\.example\.com$
- '172.16.20.0/24'
- 'vendor:cisco': '192.0.2.0/24'
=head3 C<mibhome>