Skip to content

Commit 9b96fc8

Browse files
committed
refactor(ipdiscover): improve ipdiscover with tag option, now 5 agents can be elected per tag and network
1 parent 7210dee commit 9b96fc8

File tree

1 file changed

+58
-83
lines changed

1 file changed

+58
-83
lines changed

Apache/Ocsinventory/Server/Capacities/Ipdiscover.pm

Lines changed: 58 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ push @{$Apache::Ocsinventory::OPTIONS_STRUCTURE},{
5050
'HANDLER_PROLOG_RESP' => \&_ipdiscover_prolog_resp,
5151
'HANDLER_PRE_INVENTORY' => undef,
5252
'HANDLER_POST_INVENTORY' => \&_ipdiscover_main,
53-
'REQUEST_NAME' => 'IPDISCOVER',
54-
'HANDLER_REQUEST' => \&ipd_handler,
53+
'REQUEST_NAME' => undef,
54+
'HANDLER_REQUEST' => undef,
5555
'HANDLER_DUPLICATE' => undef,
5656
'TYPE' => OPTION_TYPE_SYNC,
5757
'XML_PARSER_OPT' => {
@@ -236,7 +236,7 @@ sub _ipdiscover_main{
236236

237237
if($row = $request->fetchrow_hashref){
238238
if( ($row->{'FIDELITY'} > 2 and $row->{'QUALITY'} != 0) || $ENV{'OCS_OPT_IPDISCOVER_NO_POSTPONE'} ){
239-
$subnet = &_ipdiscover_find_iface($result, $current_context->{'DBI_HANDLE'});
239+
$subnet = &_ipdiscover_find_iface($result, $current_context->{'DBI_HANDLE'}, $DeviceID);
240240
if(!$subnet){
241241
return &_ipdiscover_evaluate($result, $row->{'FIDELITY'}, $row->{'QUALITY'}, $dbh, $DeviceID);
242242
}elsif($subnet =~ /^(\d{1,3}(?:\.\d{1,3}){3})$/){
@@ -371,6 +371,7 @@ sub _ipdiscover_find_iface{
371371
my $base = $result->{CONTENT}->{NETWORKS};
372372

373373
my $dbh = shift;
374+
my $DeviceID = shift;
374375

375376
my $request;
376377
my @worth;
@@ -389,11 +390,32 @@ sub _ipdiscover_find_iface{
389390
}
390391

391392
# Looking for a need of ipdiscover
392-
$request = $dbh->prepare('SELECT HARDWARE_ID FROM devices WHERE TVALUE=? AND NAME="IPDISCOVER"');
393-
$request->execute($_->{IPSUBNET});
394-
if($request->rows < $ENV{'OCS_OPT_IPDISCOVER'}){
395-
$request->finish;
396-
return $_->{IPSUBNET};
393+
my $request_tag = $dbh->prepare('SELECT TAG FROM accountinfo WHERE HARDWARE_ID=?');
394+
my $tag = undef;
395+
396+
unless($request_tag->execute($DeviceID)){
397+
&_log(519,'ipdiscover','_ipdiscover_find_iface: ERROR cannot find tag on this machine') if $ENV{'OCS_OPT_LOGLEVEL'};
398+
return(1);
399+
}
400+
401+
my $row = $request_tag->fetchrow_hashref;
402+
403+
if (defined $row->{'TAG'}) {
404+
&_log(519,'ipdiscover','_ipdiscover_find_iface: TAG DEFINED on machine id: '.$DeviceID.' subnet: '.$_->{IPSUBNET}.' MASK: '.$_->{IPMASK}) if $ENV{'OCS_OPT_LOGLEVEL'};
405+
$tag = $row->{'TAG'};
406+
$request = $dbh->prepare('SELECT devices.HARDWARE_ID FROM devices INNER JOIN accountinfo ON accountinfo.HARDWARE_ID = devices.HARDWARE_ID WHERE TVALUE=? AND accountinfo.TAG=? AND NAME="IPDISCOVER"');
407+
$request->execute($_->{IPSUBNET},$tag);
408+
}
409+
else{
410+
&_log(519,'ipdiscover','_ipdiscover_find_iface: NO TAG DEFINED on machine id: '.$DeviceID.' subnet: '.$_->{IPSUBNET}.' MASK: '.$_->{IPMASK}) if $ENV{'OCS_OPT_LOGLEVEL'};
411+
$request = $dbh->prepare('SELECT HARDWARE_ID FROM devices WHERE TVALUE=? AND NAME="IPDISCOVER"');
412+
$request->execute($_->{IPSUBNET});
413+
}
414+
415+
&_log(519,'ipdiscover','_ipdiscover_find_iface: Nb machines elected on this network: '.$_->{IPSUBNET}.' ----> '.$request->rows.' machines') if $ENV{'OCS_OPT_LOGLEVEL'};
416+
417+
if($request->rows < $ENV{'OCS_OPT_IPDISCOVER'}){
418+
$request->finish; return $_->{IPSUBNET};
397419
}
398420
$request->finish;
399421

@@ -421,13 +443,36 @@ sub _ipdiscover_evaluate{
421443

422444
for(@$base){
423445
if(defined($_->{IPSUBNET}) and $_->{IPSUBNET}=~/^(\d{1,3}(?:\.\d{1,3}){3})$/ ){
446+
my $request_tag = $dbh->prepare('SELECT TAG FROM accountinfo WHERE HARDWARE_ID=?');
447+
my $tag = undef;
424448

425-
$request = $dbh->prepare('
426-
SELECT h.ID AS ID, h.QUALITY AS QUALITY, UNIX_TIMESTAMP(h.LASTDATE) AS LAST
427-
FROM hardware h,devices d
428-
WHERE d.HARDWARE_ID=h.ID AND d.TVALUE=? AND h.ID<>? AND d.IVALUE<>? AND d.NAME="IPDISCOVER"');
429-
$request->execute($_->{IPSUBNET}, $DeviceID, IPD_MAN);
449+
unless($request_tag->execute($DeviceID)){
450+
&_log(519,'ipdiscover','_ipdiscover_evaluate: Error cannot find tag on machine') if $ENV{'OCS_OPT_LOGLEVEL'};
451+
return(1);
452+
}
453+
454+
my $row = $request_tag->fetchrow_hashref;
430455

456+
if (defined $row->{'TAG'}) {
457+
&_log(519,'ipdiscover','_ipdiscover_evaluate: TAG defined to evaluate machine id: '.$DeviceID.' network: '.$_->{IPSUBNET}) if $ENV{'OCS_OPT_LOGLEVEL'};
458+
$tag = $row->{'TAG'};
459+
$request = $dbh->prepare('
460+
SELECT h.ID AS ID, h.QUALITY AS QUALITY, UNIX_TIMESTAMP(h.LASTDATE) AS LAST
461+
FROM hardware h
462+
INNER JOIN accountinfo ON accountinfo.HARDWARE_ID = h.ID
463+
INNER JOIN devices d ON d.HARDWARE_ID = h.ID
464+
WHERE d.TVALUE=? AND h.ID<>? AND d.IVALUE<>? AND d.NAME="IPDISCOVER" AND accountinfo.TAG=?');
465+
466+
$request->execute($_->{IPSUBNET}, $DeviceID, IPD_MAN, $tag);
467+
}
468+
else{
469+
$request = $dbh->prepare('
470+
SELECT h.ID AS ID, h.QUALITY AS QUALITY, UNIX_TIMESTAMP(h.LASTDATE) AS LAST
471+
FROM hardware h,devices d
472+
WHERE d.HARDWARE_ID=h.ID AND d.TVALUE=? AND h.ID<>? AND d.IVALUE<>? AND d.NAME="IPDISCOVER"');
473+
$request->execute($_->{IPSUBNET}, $DeviceID, IPD_MAN);
474+
}
475+
431476
while($row = $request->fetchrow_hashref){
432477
# If we find an ipdiscover that is older than IP_MAX_ALIVE, we replace it with the current
433478
if( (($time - $row->{'LAST'}) > $max_age) and $max_age){
@@ -486,74 +531,4 @@ sub assign_config {
486531
return $value;
487532
}
488533

489-
490-
sub ipd_handler {
491-
my $current_context = shift;
492-
my $dbh = $current_context->{'DBI_HANDLE'};
493-
my $result = $current_context->{'XML_ENTRY'};
494-
my $DeviceID = $current_context->{'DATABASE_ID'};
495-
496-
&_log(1007,'ipdiscover','processing IpDiscover data') if $ENV{'OCS_OPT_LOGLEVEL'};
497-
498-
if (exists($result->{CONTENT}->{IPDISCOVER})) {
499-
my $ipd_data = $result->{CONTENT}->{IPDISCOVER}->{H};
500-
my $subnets = $result->{CONTENT}->{SUBNETS}->{S};
501-
502-
# ensure that we have an array of subnets
503-
$subnets = [$subnets] unless ref($subnets) eq 'ARRAY';
504-
505-
foreach my $subnet_entry (@$subnets) {
506-
my $mask = cidr_to_netmask($subnet_entry);
507-
my ($netid) = split('/', $subnet_entry);
508-
509-
# delete entries for this netod
510-
my $delete_req = $dbh->prepare('DELETE FROM netmap WHERE NETID=?');
511-
$delete_req->execute($netid);
512-
513-
514-
foreach my $ipd_entry (@$ipd_data) {
515-
my $ip = $ipd_entry->{I};
516-
my $mac = $ipd_entry->{M} // $ip;
517-
my $hostname = $ipd_entry->{N};
518-
my $tag = $ipd_entry->{T};
519-
520-
521-
if (ip_belongs_to_subnet($ip, $subnet_entry)) {
522-
insert_netmap($dbh, $ip, $mac, $mask, $netid, $hostname, $tag, $DeviceID);
523-
}
524-
}
525-
}
526-
}
527-
528-
&_log(1008,'ipdiscover','IpDiscover data processed') if $ENV{'OCS_OPT_LOGLEVEL'};
529-
530-
return 'APACHE_OK';
531-
}
532-
533-
534-
sub cidr_to_netmask {
535-
my $cidr = shift;
536-
my $bits = (split('/', $cidr))[1];
537-
my $mask = unpack("N", pack("B32", '1' x $bits . '0' x (32 - $bits)));
538-
return join '.', unpack "C4", pack "N", $mask;
539-
}
540-
541-
use Net::IP;
542-
sub ip_belongs_to_subnet {
543-
my ($ip, $subnet) = @_;
544-
my $ip_obj = new Net::IP($ip) or die Net::IP::Error();
545-
my $subnet_obj = new Net::IP($subnet) or die Net::IP::Error();
546-
547-
return $subnet_obj->overlaps($ip_obj) == $IP_B_IN_A_OVERLAP;
548-
}
549-
550-
sub insert_netmap {
551-
my ($dbh, $ip, $mac, $mask, $netid, $hostname, $tag, $DeviceID) = @_;
552-
553-
# insert ignore
554-
my $insert_req = $dbh->prepare('INSERT IGNORE INTO netmap(IP, MAC, MASK, NETID, NAME, HARDWARE_ID, TAG) VALUES(?,?,?,?,?,?,?)');
555-
$insert_req->execute($ip, $mac, $mask, $netid, $hostname, $DeviceID, $tag);
556-
}
557-
558-
559534
1;

0 commit comments

Comments
 (0)