Просмотр исходного кода

Added offline record for neibourhood scanner

Toby Chui 3 лет назад
Родитель
Сommit
a3fe651264

+ 2 - 1
cluster.go

@@ -25,7 +25,7 @@ func ClusterInit() {
 	//Only enable cluster scanning on mdns enabled mode
 	if *allow_mdns && MDNS != nil {
 		//Start the network discovery
-		thisDiscoverer := neighbour.NewDiscoverer(MDNS)
+		thisDiscoverer := neighbour.NewDiscoverer(MDNS, sysdb)
 		//Start a scan immediately (in go routine for non blocking)
 		go func() {
 			thisDiscoverer.UpdateScan(3)
@@ -55,6 +55,7 @@ func ClusterInit() {
 		})
 
 		router.HandleFunc("/system/cluster/scan", NeighbourDiscoverer.HandleScanningRequest)
+		router.HandleFunc("/system/cluster/record", NeighbourDiscoverer.HandleScanRecord)
 
 		/*
 			Start and Cluster Server and Client

+ 6 - 2
mod/network/mdns/mdns.go

@@ -26,6 +26,7 @@ type NetworkHost struct {
 	BuildVersion string
 	MinorVersion string
 	MacAddr      []string
+	Online       bool
 }
 
 func NewMDNS(config NetworkHost) (*MDNSHost, error) {
@@ -35,8 +36,8 @@ func NewMDNS(config NetworkHost) (*MDNSHost, error) {
 	if err == nil {
 		macAddressBoardcast = strings.Join(macAddress, ",")
 	}
+
 	//Register the mds services
-	//server, err := zeroconf.Register("ArOZ", "_http._tcp", "local.", *listen_port, []string{"version_build=" + build_version, "version_minor=" + internal_version, "vendor=" + deviceVendor, "model=" + deviceModel, "uuid=" + deviceUUID, "domain=aroz.online"}, nil)
 	server, err := zeroconf.Register(config.HostName, "_http._tcp", "local.", config.Port, []string{"version_build=" + config.BuildVersion, "version_minor=" + config.MinorVersion, "vendor=" + config.Vendor, "model=" + config.Model, "uuid=" + config.UUID, "domain=" + config.Domain, "mac_addr=" + macAddressBoardcast}, nil)
 	if err != nil {
 		return &MDNSHost{}, err
@@ -104,6 +105,7 @@ func (m *MDNSHost) Scan(timeout int, domainFilter string) []*NetworkHost {
 					BuildVersion: properties["version_build"],
 					MinorVersion: properties["version_minor"],
 					MacAddr:      macAddrs,
+					Online:       true,
 				})
 
 			} else {
@@ -140,6 +142,7 @@ func (m *MDNSHost) Scan(timeout int, domainFilter string) []*NetworkHost {
 						BuildVersion: properties["version_build"],
 						MinorVersion: properties["version_minor"],
 						MacAddr:      macAddrs,
+						Online:       true,
 					})
 
 				}
@@ -156,7 +159,8 @@ func (m *MDNSHost) Scan(timeout int, domainFilter string) []*NetworkHost {
 		log.Fatalln("Failed to browse:", err.Error())
 	}
 
-	<-ctx.Done()
+	//Update the master scan record
 
+	<-ctx.Done()
 	return discoveredHost
 }

+ 16 - 0
mod/network/neighbour/handler.go

@@ -39,3 +39,19 @@ func (d *Discoverer) HandleScanningRequest(w http.ResponseWriter, r *http.Reques
 	js, _ := json.Marshal(result)
 	sendJSONResponse(w, string(js))
 }
+
+func (d *Discoverer) HandleScanRecord(w http.ResponseWriter, r *http.Request) {
+	offlineNodes, err := d.GetOfflineHosts()
+	if err != nil {
+		sendErrorResponse(w, err.Error())
+		return
+	}
+
+	js, err := json.Marshal(offlineNodes)
+	if err != nil {
+		sendErrorResponse(w, err.Error())
+		return
+	}
+
+	sendJSONResponse(w, string(js))
+}

+ 77 - 2
mod/network/neighbour/neighbour.go

@@ -1,9 +1,11 @@
 package neighbour
 
 import (
+	"encoding/json"
 	"log"
 	"time"
 
+	"imuslab.com/arozos/mod/database"
 	"imuslab.com/arozos/mod/network/mdns"
 )
 
@@ -13,18 +15,37 @@ import (
 	Require MDNS Service
 */
 
+const (
+	AutoDeleteRecordTime = int64(2592000) //30 days = 2592000 seconds
+)
+
 type Discoverer struct {
 	Host             *mdns.MDNSHost
+	Database         *database.Database
 	LastScanningTime int64
 	NearbyHosts      []*mdns.NetworkHost
 	d                chan bool
 	t                *time.Ticker
 }
 
-//NEw Discoverer return a nearby Aroz Discover agent
-func NewDiscoverer(MDNS *mdns.MDNSHost) Discoverer {
+type HostRecord struct {
+	Name       string
+	Model      string
+	Version    string
+	UUID       string
+	LastSeenIP []string
+	MacAddr    []string
+	LastOnline int64
+}
+
+//New Discoverer return a nearby Aroz Discover agent
+func NewDiscoverer(MDNS *mdns.MDNSHost, Database *database.Database) Discoverer {
+	//Create a new table for neighbour records
+	Database.NewTable("neighbour")
+
 	return Discoverer{
 		Host:             MDNS,
+		Database:         Database,
 		LastScanningTime: -1,
 		NearbyHosts:      []*mdns.NetworkHost{},
 	}
@@ -74,6 +95,60 @@ func (d *Discoverer) UpdateScan(scanDuration int) {
 	d.LastScanningTime = time.Now().Unix()
 	results := d.Host.Scan(scanDuration, d.Host.Host.Domain)
 	d.NearbyHosts = results
+
+	//Record all scanned host into database
+	for _, thisHost := range results {
+		thisHostIpString := []string{}
+		for _, ipaddr := range thisHost.IPv4 {
+			thisHostIpString = append(thisHostIpString, ipaddr.String())
+		}
+		thisHostRecord := HostRecord{
+			Name:       thisHost.HostName,
+			Model:      thisHost.Model,
+			Version:    thisHost.MinorVersion,
+			UUID:       thisHost.UUID,
+			LastSeenIP: thisHostIpString,
+			MacAddr:    thisHost.MacAddr,
+			LastOnline: time.Now().Unix(),
+		}
+		d.Database.Write("neighbour", thisHost.UUID, thisHostRecord)
+	}
+}
+
+func (d *Discoverer) GetOfflineHosts() ([]*HostRecord, error) {
+	results := []*HostRecord{}
+	entries, err := d.Database.ListTable("neighbour")
+	if err != nil {
+		return results, err
+	}
+	for _, keypairs := range entries {
+		//Get the host record and UUI from the database
+		thisHostUUID := string(keypairs[0])
+		thisHostRecord := HostRecord{}
+		json.Unmarshal(keypairs[1], &thisHostRecord)
+
+		if time.Now().Unix()-thisHostRecord.LastOnline > AutoDeleteRecordTime {
+			//Remove this record
+			log.Println("[Neighbour] Removing network host record due to long period offline: " + thisHostUUID + " (" + thisHostRecord.Name + ")")
+			d.Database.Delete("neighbour", thisHostUUID)
+			continue
+		}
+		//Check this host is online
+		nodeIsOnline := false
+		for _, thisOnlineHost := range d.NearbyHosts {
+			if thisOnlineHost.UUID == thisHostUUID {
+				//This is online node. skip this
+				nodeIsOnline = true
+				break
+			}
+		}
+
+		if !nodeIsOnline {
+			results = append(results, &thisHostRecord)
+		}
+	}
+
+	return results, nil
 }
 
 func (d *Discoverer) ScannerRunning() bool {

+ 74 - 2
web/SystemAO/cluster/neighbour.html

@@ -49,6 +49,15 @@
             
         </div>
         <div class="ui divider"></div>
+        <h4 class="ui header">
+            Offline Hosts
+            <div class="sub header">Host that goes offline for less than 30 days</div>
+        </h4>
+        <div class="ui basic segment" id="offlineList">
+            
+        </div>
+        <small>All hosts that offline for more than 30 days will be automatically removed from the system record</small>
+        <div class="ui divider"></div>
         <p>Last Updates: <span id="lastUpdateTime"></span> seconds ago</p>
         <br><br><br>
     </div>
@@ -109,7 +118,7 @@
                     //Render remote host info
                     $("#nearybylist").html("");
                     if (data.NearbyHosts == null){
-                        $("#nearybylist").append(`<div class="ui icon message">
+                        $("#nearybylist").append(`<div class="ui icon teal message">
                                 <i class="question icon"></i>
                                 <div class="content">
                                     No nearby hosts discovered
@@ -178,8 +187,71 @@
                 }
             });
 
-
+            $.get("../../system/cluster/record", function(data){
+                $("#offlineList").html("");
+                if (data != null){
+                    data.forEach(function(host){
+                        let ipDOM = "No Record";
+                        if (host.LastSeenIP != null && host.LastSeenIP.length > 0){
+                            ipDOM = host.LastSeenIP.join(" / ");
+                        }
+                        let macDOM = "No Record";
+                        if (host.MacAddr != null && host.MacAddr.length > 0){
+                            macDOM = host.MacAddr.join(" / ");
+                        }
+                        $("#offlineList").append(`<div class="ui icon message">
+                            <i class="server icon"></i>
+                            <div class="content">
+                                <button class="ui right floated basic button"><i class="power icon"></i> Wake On LAN</button>
+                                <div class="header">
+                                    <span>${host.Name}</a>
+                                </div>
+                                <div class="ui list">
+                                    <div class="item">
+                                        <i class="disk icon"></i>
+                                        <div class="content">
+                                            <b>MODEL:</b> ${host.Model}
+                                        </div>
+                                    </div>
+                                    <div class="item">
+                                        <i class="paperclip icon"></i>
+                                        <div class="content">
+                                            <b>VER:</b> ${host.Version}
+                                        </div>
+                                    </div>
+                                    <div class="item">
+                                        <i class="marker icon"></i>
+                                        <div class="content">
+                                            <b>IP:</b> ${ipDOM}
+                                        </div>
+                                    </div>
+                                    <div class="item">
+                                        <i class="tag icon"></i>
+                                        <div class="content">
+                                            <b>UUID:</b> ${host.UUID}
+                                        </div>
+                                    </div>
+                                    <div class="item">
+                                        <i class="server icon"></i>
+                                        <div class="content">
+                                            <b>MAC:</b> ${macDOM}
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>`);
+                    });
+                }
+                if (data == null || data.length == 0){
+                    $("#offlineList").append(`<div class="ui message">
+                        <div class="content">
+                            <i class="checkmark icon"></i> No Offline Network Host
+                        </div>
+                    `);
+                }
+            });
         }
+
        
     </script>
 </body>