Skip to content

Commit

Permalink
feat: Refacto NetDisco-Devices target storage
Browse files Browse the repository at this point in the history
Store deviceid defined during ESX inventory
Update ESX task to reuse stored deviceid on next netscan
This avoid inventory files duplication in local target folder
  • Loading branch information
g-bougard committed Oct 4, 2023
1 parent f9bbdde commit f70a7ec
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 13 deletions.
24 changes: 17 additions & 7 deletions lib/GLPI/Agent/Task/ESX.pm
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ sub connect {
}

sub createInventory {
my ( $self, $id, $tag ) = @_;
my ( $self, $id, $tag, $deviceid ) = @_;

die unless $self->{vpbs};

Expand All @@ -54,9 +54,11 @@ sub createInventory {
my $host = $vpbs->getHostFullInfo($id);

my $inventory = GLPI::Agent::Inventory->new(
datadir => $self->{datadir},
logger => $self->{logger},
tag => $tag
datadir => $self->{datadir},
logger => $self->{logger},
tag => $tag,
# deviceid can be set and so reused from previous netscan
deviceid => $deviceid
);

$inventory->setRemote('esx');
Expand Down Expand Up @@ -226,7 +228,7 @@ sub run {
sub serverInventory {
# $host_callback can be used to dump datas retrieved from ESX server as done by glpi-esx
# and is only used for local target
my ($self, $path, $host_callback) = @_;
my ($self, $path, $host_callback, $deviceids) = @_;

# Initialize GLPI server submission if required
if ($self->{target}->isType('server') && !$self->{serverclient}) {
Expand Down Expand Up @@ -271,8 +273,10 @@ sub serverInventory {

my $hostIds = $self->getHostIds();
foreach my $hostId (@$hostIds) {
my $deviceid;
$deviceid = $deviceids->{$hostId} if ref($deviceids) eq 'HASH';
my $inventory = $self->createInventory(
$hostId, $self->{config}->{tag}
$hostId, $self->{config}->{tag}, $deviceid
);

if ($self->{target}->isType('server')) {
Expand Down Expand Up @@ -308,7 +312,13 @@ sub serverInventory {
last;
}
if (ref($host_callback) eq 'CODE') {
&{$host_callback}($hostId, $file);
# $devices is set when called by netscan to keep esx deviceid consistent
# and don't duplicate inventory file when storing them
if ($deviceids) {
&{$host_callback}($inventory, $hostId);
} else {
&{$host_callback}($hostId, $file);
}
}
}
}
Expand Down
59 changes: 53 additions & 6 deletions lib/GLPI/Agent/Task/NetDiscovery.pm
Original file line number Diff line number Diff line change
Expand Up @@ -369,22 +369,24 @@ sub run {
my $esxscan = delete $result->{_esxscan};

my $authsnmp = $result->{AUTHSNMP};
my $deviceid;
# AUTHREMOTE can be set in results but is not actually supported by GLPI
my $authremote = delete $result->{AUTHREMOTE};
if (($authsnmp || $authremote) && $job->localtask) {
# Don't keep authsnmp in result for local task
delete $result->{AUTHSNMP};
# For TooBox, we keep used authsnmp|authremote & ip_range for results page in target storage
if ($self->{target}->isType('local')) {
my $storage = $self->{target}->getStorage();
my $devices = $storage->restore(name => "NetDisco-Devices") // {};
$devices->{$result->{IP}} = {
my $device = $self->_storeNetDiscoDevices(
ip => $result->{IP},
credential => $authsnmp || $authremote,
ip_range => $range->{name},
# Set expiration to ~3 months (3*30*86400)
expiration => time + 7776000
};
$storage->save(name => "NetDisco-Devices", data => $devices);
);
# Still keep eventually known deviceid for later check
$deviceid = $device->{deviceid}
if defined($device->{deviceid});
}
}

Expand Down Expand Up @@ -430,6 +432,17 @@ sub run {
$inventory->run();

} elsif ($authremote) {
my $collectdeviceid = sub {
my ($inventory, $hostid) = @_;
# No need to update deviceid if used one if the stored one
return if ($hostid && ref($deviceid) eq 'HASH' && $inventory->getDeviceId() eq $deviceid->{$hostid})
|| ($deviceid && $inventory->getDeviceId() eq $deviceid);
$self->_storeNetDiscoDevices(
ip => $result->{IP},
deviceid => $inventory->getDeviceId(),
hostid => $hostid
);
};
my $credentials = first { $_->{ID} eq $authremote } @{$jobaddress->{remote_credentials}};
if ($credentials) {
my $path;
Expand All @@ -438,7 +451,7 @@ sub run {
$path .= '/inventory' if $path eq '.';
if ($credentials->{TYPE} eq 'esx' && $esxscan) {
# As we still have run the connection part in _scanAddressByRemote(), we reuse the connected object
$esxscan->serverInventory($path);
$esxscan->serverInventory($path, $collectdeviceid, $deviceid);
} else {
GLPI::Agent::Task::RemoteInventory->require();
# TODO Support RemoteInventory task run
Expand Down Expand Up @@ -481,6 +494,40 @@ sub run {
setExpirationTime();
}

sub _storeNetDiscoDevices {
my ($self, %params) = @_;

my $storage = $self->{target}->getStorage()
or return;

my $ip = $params{ip}
or return;

my $devices = $storage->restore(name => "NetDisco-Devices") // {};
my $hostid = $params{hostid};
my $updated = $devices->{$ip} ? 0 : 1;
my $device = $devices->{$ip} // {};

foreach my $key (qw{credential ip_range expiration deviceid}) {
next unless defined($params{$key});
if ($key eq 'deviceid' && $hostid) {
$device->{$key} = {} unless ref($device->{$key}) eq 'HASH';
next if defined($device->{$key}->{$hostid}) && $device->{$key}->{$hostid} eq $params{$key};
$device->{$key}->{$hostid} = $params{$key};
} else {
next if defined($device->{$key}) && $device->{$key} eq $params{$key};
$device->{$key} = $params{$key};
}
$updated++;
}

$devices->{$ip} = $device;
$storage->save(name => "NetDisco-Devices", data => $devices)
if $updated;

return $device;
}

sub _logExpirationHours {
my ($self, $expiration) = @_;

Expand Down

0 comments on commit f70a7ec

Please sign in to comment.