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')->{hosts_file} ||= '/etc/hosts';
setting('dns')->{no} ||= ['fe80::/64','169.254.0.0/16']; 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 # legacy config item names
config->{'devport_vlan_limit'} = config->{'devport_vlan_limit'} =

View File

@@ -55,12 +55,16 @@ sub set_canonical_ip {
my $revofname = ipv4_from_hostname($snmp->name); my $revofname = ipv4_from_hostname($snmp->name);
if (setting('reverse_sysname') and $revofname) { if (setting('reverse_sysname') and $revofname) {
if ($snmp->snmp_connect_ip( $new_ip )) {
$new_ip = $revofname; $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') if (scalar @{ setting('device_identity') }) {
and scalar @{ setting('device_identity') }) {
my @idmaps = @{ setting('device_identity') }; my @idmaps = @{ setting('device_identity') };
my $devips = $device->device_ips->order_by('alias'); my $devips = $device->device_ips->order_by('alias');
@@ -70,27 +74,27 @@ sub set_canonical_ip {
foreach my $map (@idmaps) { foreach my $map (@idmaps) {
next unless ref {} eq ref $map; next unless ref {} eq ref $map;
foreach my $key (keys %$map) { foreach my $key (sort keys %$map) {
# lhs matches device, rhs matches device_ip # lhs matches device, rhs matches device_ip
if (check_acl($device, $key) if (check_acl($device, $key)
and check_acl($alias, $map->{$key})) { and check_acl($alias, $map->{$key})) {
if ($snmp->snmp_connect_ip( $alias->alias )) {
$new_ip = $alias->alias; $new_ip = $alias->alias;
last 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; 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 { schema('netdisco')->txn_do(sub {
$device->renumber($new_ip) $device->renumber($new_ip)
or die "cannot renumber to: $new_ip"; # rollback or die "cannot renumber to: $new_ip"; # rollback

View File

@@ -607,16 +607,16 @@ for L</"ACCESS CONTROL LISTS">.
=head3 C<device_identity> =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 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" in Netdisco. For example if Netdisco discovers devices and uses the "wrong"
interface to identfy them (thereby confusing users) you can correct that here. 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 C<device_identity> setting is a dictionary where each key is an Access
the key is an Access Control List matching a device and the value is another Control List matching a device and the corresponding value is another Access
Access Control List matching one of the device's interfaces to use as the Control List matching one of the device's interfaces to use as the device
device canonical identity. The format of Access Control Lists is described in canonical identity. The format of Access Control Lists is described in
L</"ACCESS CONTROL LISTS">. L</"ACCESS CONTROL LISTS">.
In general, because the key of a dictionary must be a simple text string, you 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).*' - 'model:.*(?i:DCS7508).*'
device_identity: device_identity:
- 'group:backbone_devices': 'group:backbone_devices':
- !!perl/regexp ^.*\.backbone\.example\.com$ - !!perl/regexp ^.*\.backbone\.example\.com$
- '172.16.20.0/24' - '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> 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 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: have one), you could use:
device_identity: 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 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 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). match the device (as in the example above).
Note also that whatever interface you select as canonical for the device must 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> =head3 C<mibhome>