Explorar o código

add lock device by snmp discovery

Roman Dmitriev %!s(int64=2) %!d(string=hai) anos
pai
achega
df5d713934

+ 8 - 0
html/admin/devices/editdevice.php

@@ -111,6 +111,13 @@ print_editdevice_submenu($page_url,$id,$device['device_type'],$user_info['login'
 
 ?>
 <div id="contsubmenu">
+
+<?php
+    if (!empty($_GET['status'])) {
+        if ($_GET['status'] ==='locked') { print '<div id="msg">' . WEB_device_locked . '</div>'; }
+    }
+?>
+
 <form name="def" action="editdevice.php?id=<?php echo $id; ?>" method="post">
 <table class="data">
 <tr>
@@ -227,4 +234,5 @@ print "<tr><td colspan=3>".$device['ip']."::". get_device_model_name($db_link,$d
 print "</table>\n";
 ?>
 </form>
+
 <?php require_once ($_SERVER['DOCUMENT_ROOT']."/inc/footer.small.php"); ?>

+ 6 - 0
html/admin/devices/switchstatus.php

@@ -69,6 +69,11 @@ if (isset($_POST['port_off']) and $device['snmp_version'] > 0) {
 
 unset($_POST);
 
+if (!apply_device_lock($db_link,$id)) {
+    header("Location: /admin/devices/editdevice.php&id=".$id."&status=locked");
+    exit;
+}
+
 $user_info = get_record_sql($db_link, "SELECT * FROM User_list WHERE id=" . $device['user_id']);
 
 require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/header.php");
@@ -379,5 +384,6 @@ print_editdevice_submenu($page_url, $id, $device['device_type'], $user_info['log
         print "<tr><td class=\"speed10M\">" . WEB_port_speed_10 . "</td><td class=\"speed100M\">" . WEB_port_speed_100 . "</td><td class=\"speed1G\">" . WEB_port_speed_1G . "</td><td class=\"speed10G\">" . WEB_port_speed_10G . "</td><tr>\n";
         print "</table>\n";
         print "</form>";
+        unset_lock_discovery($db_link,$id);
         require_once($_SERVER['DOCUMENT_ROOT'] . "/inc/footer.small.php");
         ?>

+ 15 - 12
html/admin/users/edituser.php

@@ -124,24 +124,27 @@ if (isset($_POST["showDevice"])) {
 
 if (isset($_POST["addauth"])) {
     $fip = substr(trim($_POST["newip"]), 0, 18);
+    $fmac = NULL;
     if (isset($_POST["newmac"])) { $fmac = mac_dotted(substr(trim($_POST["newmac"]), 0, 17)); }
     if ($fip) {
         if (checkValidIp($fip)) {
             $ip_aton = ip2long($fip);
+            $f_dhcp = 1;
             //search mac
-            $mac_exists=find_mac_in_subnet($db_link,$fip,$fmac);
-            if (isset($mac_exists) and $mac_exists['count']>=1 and !in_array($id,$mac_exists['users_id'])) {
-                $dup_sql = "SELECT * FROM User_list WHERE id=".$mac_exists['users_id']['0'];
-                $dup_info = get_record_sql($db_link, $dup_sql);
-                $msg_error="Mac already exists at another user in this subnet! Skip creating $fip [$fmac].<br>Old user id: ".$dup_info['id']." login: ".$dup_info['login'];
-                $_SESSION[$page_url]['msg'] = $msg_error;
-                LOG_ERROR($db_link, $msg_error);
-                header("Location: " . $_SERVER["REQUEST_URI"]);
-                exit;
+            if (!empty($fmac)) {
+                $mac_exists=find_mac_in_subnet($db_link,$fip,$fmac);
+                if (isset($mac_exists) and $mac_exists['count']>=1 and !in_array($id,$mac_exists['users_id'])) {
+                    $dup_sql = "SELECT * FROM User_list WHERE id=".$mac_exists['users_id']['0'];
+                    $dup_info = get_record_sql($db_link, $dup_sql);
+                    $msg_error="Mac already exists at another user in this subnet! Skip creating $fip [$fmac].<br>Old user id: ".$dup_info['id']." login: ".$dup_info['login'];
+                    $_SESSION[$page_url]['msg'] = $msg_error;
+                    LOG_ERROR($db_link, $msg_error);
+                    header("Location: " . $_SERVER["REQUEST_URI"]);
+                    exit;
+                    }
+                //disable dhcp for secondary ip
+                if (in_array($id,$mac_exists['users_id'])) { $f_dhcp = 0; }
                 }
-            //disable dhcp for secondary ip
-            $f_dhcp = 1;
-            if (in_array($id,$mac_exists['users_id'])) { $f_dhcp = 0; }
             //search ip
             $dup_ip_record = get_record_sql($db_link, "SELECT * FROM User_auth WHERE `ip_int`=$ip_aton AND user_id<>".$id." AND deleted=0");
             if (!empty($dup_ip_record)) {

+ 29 - 0
html/inc/common.php

@@ -2088,6 +2088,35 @@ function is_up($ip)
     return $rval == 0;
 }
 
+function apply_device_lock ($db, $device_id, $iteration =0) {
+    $iteration++;
+    if ($iteration>2) { return false; }
+    $dev = get_record($db,'devices','id='.$device_id);
+    if (empty($dev)) { return true; }
+    if (!$dev['discovery_locked']) { return set_lock_discovery($db,$device_id); }
+    //if timestamp undefined, set and return
+    if (empty($dev['locked_timestamp'])) { return set_lock_discovery($db,$device_id); }
+    //wait for discovery
+    $wait_time = ($dev['locked_timestamp'] + SNMP_LOCK_TIMEOUT) - time();
+    if ($wait_time<0) { return set_lock_discovery($db,$device_id); }
+    sleep($wait_time);
+    return apply_device_lock($db,$device_id,$iteration);
+}
+
+function set_lock_discovery($db,$device_id) {
+    $new['discovery_locked'] = 1;
+    $new['locked_timestamp'] = time();
+    if (update_record($db,'devices','id='.$device_id,$new)) { return true; } 
+    return false;
+}
+
+function unset_lock_discovery($db,$device_id) {
+    $new['discovery_locked'] = 0;
+    $new['locked_timestamp'] = time();
+    if (update_record($db,'devices','id='.$device_id,$new)) { return true; } 
+    return false;
+}
+    
 function get_ifmib_index_table($ip, $community, $version)
 {
     $ifmib_map = NULL;

+ 3 - 0
html/inc/consts.php

@@ -178,4 +178,7 @@ define("L_DEBUG",255);
 define('MYSQL_FIELD_DIGIT', array(1,2,3,4,5,8,9,246));
 define('MYSQL_FIELD_STRING', array(252,253,254));
 
+//lock device by snmp access
+define('SNMP_LOCK_TIMEOUT',30);
+
 ?>

+ 1 - 0
html/inc/languages/english.php

@@ -22,6 +22,7 @@ define("WEB_nagios_host_unknown","Status unknown");
 define("WEB_auth_unknown","Client IP address is not set");
 define("WEB_msg_exists","already exists!");
 define("WEB_msg_ip_error","Address format is not correct!");
+define("WEB_device_locked","Device is busy, try again later");
 
 /* common message */
 define("WEB_msg_IP","IP address");

+ 1 - 0
html/inc/languages/russian.php

@@ -22,6 +22,7 @@ define("WEB_nagios_host_unknown","Состояние неизвестно");
 define("WEB_auth_unknown","IP-адрес клиента не установлен");
 define("WEB_msg_exists","уже существует!");
 define("WEB_msg_ip_error","Формат адреса не верен!");
+define("WEB_device_locked","Устройство занято. Попробуйте позже.");
 
 /* common message */
 define("WEB_msg_IP","IP-адрес");

+ 45 - 0
scripts/eyelib/mysql.pm

@@ -51,6 +51,9 @@ get_subnets_ref
 init_db
 init_option
 insert_record
+apply_device_lock
+set_lock_discovery
+unset_lock_discovery
 IpToStr
 unbind_ports
 resurrection_auth
@@ -734,6 +737,48 @@ if ($fqdn ne '' and !$dynamic_ok) {
 
 #------------------------------------------------------------------------------------------------------------
 
+sub apply_device_lock {
+    my $db = shift;
+    my $device_id = shift;
+    my $iteration = shift || 0;
+    $iteration++;
+    if ($iteration>2) { return 0; }
+    my $dev = get_record_sql($db,"SELECT `discovery_locked`, `locked_timestamp` FROM devices WHERE id=".$device_id);
+    if (!$dev) { return 0; }
+    if (!$dev->{'discovery_locked'}) { return set_lock_discovery($db,$device_id); }
+    #if timestamp undefined, set and return
+    if (!$dev->{'locked_timestamp'}) { return set_lock_discovery($db,$device_id); }
+    #wait for discovery
+    $wait_time = $dev->{'locked_timestamp'} + 30 - now();
+    if ($wait_time<0) { return set_lock_discovery($db,$device_id); }
+    sleep($wait_time);
+    return apply_device_lock($db,$device_id,$iteration);
+}
+
+#------------------------------------------------------------------------------------------------------------
+
+sub set_lock_discovery {
+    my $db = shift;
+    my $device_id = shift;
+    $new->{'discovery_locked'} = 1;
+    $new->{'locked_timestamp'} = GetNowTime();
+    if (update_record($db,'devices',$new,'id='.$device_id)) { return 1; } 
+    return 0;
+}
+
+#------------------------------------------------------------------------------------------------------------
+
+sub unset_lock_discovery {
+    my $db = shift;
+    my $device_id = shift;
+    $new->{'discovery_locked'} = 0;
+    $new->{'locked_timestamp'} = GetNowTime();
+    if (update_record($db,'devices',$new,'id='.$device_id)) { return 1; } 
+    return 0;
+}
+
+#------------------------------------------------------------------------------------------------------------
+
 sub update_ad_hostname {
 my $fqdn = shift;
 my $ip = shift;

+ 12 - 5
scripts/fetch_new_arp.pl

@@ -88,7 +88,11 @@ my $snmp_version=$router->{snmp_version};
 my $community=$router->{community};
 if (!HostIsLive($router_ip)) { log_info("Host id: $router->{id} name: $router->{device_name} ip: $router_ip is down! Skip."); next; }
 $pm_arp->start() and next DATA_LOOP;
-my $arp_table=get_arp_table($router_ip,$community,$snmp_version);
+my $arp_table;
+if (apply_device_lock($dbh,$router->{id})) {
+    $arp_table=get_arp_table($router_ip,$community,$snmp_version);
+    unset_lock_discovery($dbh,$router->{id});
+    }
 $pm_arp->finish(0, \$arp_table);
 }
 $pm_arp->wait_all_children;
@@ -162,7 +166,7 @@ foreach my $auth (@auth_list) {
     $auth_table{oper_table}{$auth_mac}=$auth->{id};
     }
 
-$auth_sql="SELECT id,mac FROM User_auth WHERE mac IS NOT NULL AND deleted=0 ORDER BY id DESC";
+$auth_sql="SELECT id,mac FROM User_auth WHERE mac IS NOT NULL AND deleted=0 ORDER BY last_found DESC";
 my @auth_full_list=get_records_sql($dbh,$auth_sql);
 foreach my $auth (@auth_full_list) {
     next if (!$auth);
@@ -214,10 +218,13 @@ foreach my $device (@device_list) {
 my $int_list = get_snmp_ifindex($device->{ip},$device->{community},$device->{snmp_version});
 if (!$int_list) { log_info("Host id: $device->{id} name: $device->{device_name} ip: $device->{ip} is down! Skip."); next; }
 $pm_fdb->start() and next FDB_LOOP;
-my $fdb=get_fdb_table($device->{ip},$device->{community},$device->{snmp_version},$dev_ifindex{$device->{id}});
 my $result;
-$result->{id}=$device->{id};
-$result->{fdb} = $fdb;
+if (apply_device_lock($dbh,$device->{id})) {
+    my $fdb=get_fdb_table($device->{ip},$device->{community},$device->{snmp_version},$dev_ifindex{$device->{id}});
+    unset_lock_discovery($dbh,$device->{id});
+    $result->{id}=$device->{id};
+    $result->{fdb} = $fdb;
+    }
 $pm_fdb->finish(0, \$result);
 }
 $pm_fdb->wait_all_children;

+ 1 - 0
updates/2-4-14/device_lock.sql

@@ -0,0 +1 @@
+ALTER TABLE `devices` ADD `discovery_locked` BOOLEAN NOT NULL DEFAULT FALSE AFTER `deleted`, ADD `locked_timestamp` DATETIME NULL DEFAULT NULL AFTER `discovery_locked`;