my
$clean
=
sub
{
my
$device
=
shift
;
my
$gone
=
$device
->modules->
delete
;
debug
sprintf
' [%s] modules - removed %d chassis modules'
,
$device
->ip,
$gone
;
$device
->modules->update_or_create({
ip
=>
$device
->ip,
index
=> 1,
parent
=> 0,
name
=>
'chassis'
,
class
=>
'chassis'
,
pos
=> -1,
sw_ver
=>
$device
->os_ver,
serial
=>
$device
->serial,
model
=>
$device
->model,
fru
=> \
'false'
,
last_discover
=> \
'LOCALTIMESTAMP'
,
});
};
register_worker({
phase
=>
'main'
,
driver
=>
'snmp'
},
sub
{
my
(
$job
,
$workerconf
) =
@_
;
my
$device
=
$job
->device;
return
unless
$device
->in_storage;
if
(acl_matches(
$device
,
'skip_modules'
) or not setting(
'store_modules'
)) {
schema(
'netdisco'
)->txn_do(
$clean
,
$device
);
return
Status->info(
sprintf
' [%s] modules - store_modules is disabled (added one pseudo for chassis)'
,
$device
->ip);
}
my
$snmp
= App::Netdisco::Transport::SNMP->reader_for(
$device
)
or
return
Status->defer(
"discover failed: could not SNMP connect to $device"
);
my
$e_index
=
$snmp
->e_index;
if
(!
defined
$e_index
) {
schema(
'netdisco'
)->txn_do(
$clean
,
$device
);
return
Status->info(
sprintf
' [%s] modules - 0 chassis components (added one pseudo for chassis)'
,
$device
->ip);
}
my
$e_descr
=
$snmp
->e_descr;
my
$e_type
=
$snmp
->e_type;
my
$e_parent
=
$snmp
->e_parent;
my
$e_name
=
$snmp
->e_name;
my
$e_class
=
$snmp
->e_class;
my
$e_pos
=
$snmp
->e_pos;
my
$e_hwver
=
$snmp
->e_hwver;
my
$e_fwver
=
$snmp
->e_fwver;
my
$e_swver
=
$snmp
->e_swver;
my
$e_model
=
$snmp
->e_model;
my
$e_serial
=
$snmp
->e_serial;
my
$e_fru
=
$snmp
->e_fru;
my
(
@modules
,
%seen_idx
);
foreach
my
$entry
(
keys
%$e_index
) {
next
unless
defined
$e_index
->{
$entry
};
next
if
$seen_idx
{
$e_index
->{
$entry
} }++;
if
(
$e_index
->{
$entry
} !~ m/^[0-9]+$/) {
debug
sprintf
' [%s] modules - index %s is not an integer'
,
$device
->ip,
$e_index
->{
$entry
};
next
;
}
push
@modules
, {
index
=>
$e_index
->{
$entry
},
type
=>
$e_type
->{
$entry
},
parent
=>
$e_parent
->{
$entry
},
name
=> Encode::decode(
'UTF-8'
,
$e_name
->{
$entry
}),
class
=>
$e_class
->{
$entry
},
pos
=>
$e_pos
->{
$entry
},
hw_ver
=> Encode::decode(
'UTF-8'
,
$e_hwver
->{
$entry
}),
fw_ver
=> Encode::decode(
'UTF-8'
,
$e_fwver
->{
$entry
}),
sw_ver
=> Encode::decode(
'UTF-8'
,
$e_swver
->{
$entry
}),
model
=> Encode::decode(
'UTF-8'
,
$e_model
->{
$entry
}),
serial
=> Encode::decode(
'UTF-8'
,
$e_serial
->{
$entry
}),
fru
=>
$e_fru
->{
$entry
},
description
=> Encode::decode(
'UTF-8'
,
$e_descr
->{
$entry
}),
last_discover
=> \
'LOCALTIMESTAMP'
,
};
}
foreach
my
$m
(
@modules
){
if
(
$m
->{parent} and not
exists
$seen_idx
{
$m
->{parent} }){
debug
sprintf
' [%s] Entity %s (%s) has invalid parent %s - attaching as root entity instead'
,
$device
->ip, (
$m
->{
index
} ||
'"unknown index"'
), (
$m
->{name} ||
'"unknown name"'
),
$m
->{parent};
$m
->{parent} =
undef
;
}
}
schema(
'netdisco'
)->txn_do(
sub
{
my
$gone
=
$device
->modules->
delete
;
debug
sprintf
' [%s] modules - removed %d chassis modules'
,
$device
->ip,
$gone
;
$device
->modules->populate(\
@modules
);
return
Status->info(
sprintf
' [%s] modules - added %d new chassis modules'
,
$device
->ip,
scalar
@modules
);
});
});
true;