master
go 109 lines 2.32 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package snmpsd
4
5 import (
6 "encoding/json"
7 "fmt"
8 "os"
9 "path/filepath"
10 "sync"
11 "sync/atomic"
12 "time"
13
14 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/snmputils"
15 )
16
17 func (d *Discoverer) loadFileStatus() {
18 d.status = newDiscoveryStatus()
19
20 filename := statusFileName()
21 if filename == "" {
22 return
23 }
24
25 f, err := os.Open(filename)
26 if err != nil {
27 d.Warningf("failed to open status file %s: %v", filename, err)
28 return
29 }
30 defer func() { _ = f.Close() }()
31
32 if err := json.NewDecoder(f).Decode(d.status); err != nil {
33 d.Warningf("failed to parse status file %s: %v", filename, err)
34 return
35 }
36
37 d.Infof("loaded status file: last discovery=%s", d.status.LastDiscoveryTime)
38 }
39
40 func statusFileName() string {
41 v := os.Getenv("NETDATA_LIB_DIR")
42 if v == "" {
43 return ""
44 }
45 return filepath.Join(v, "god-sd-snmp-status.json")
46 }
47
48 func newDiscoveryStatus() *discoveryStatus {
49 return &discoveryStatus{
50 Networks: make(map[string]map[string]*discoveredDevice),
51 }
52 }
53
54 type (
55 discoveryStatus struct {
56 updated atomic.Bool
57 mux sync.RWMutex
58 Networks map[string]map[string]*discoveredDevice `json:"networks"`
59 LastDiscoveryTime time.Time `json:"last_discovery_time"`
60 ConfigHash uint64 `json:"config_hash"`
61 }
62 discoveredDevice struct {
63 DiscoverTime time.Time `json:"discover_time"`
64 SysInfo snmputils.SysInfo `json:"sysinfo"`
65 }
66 )
67
68 func (s *discoveryStatus) Bytes() ([]byte, error) {
69 s.mux.RLock()
70 defer s.mux.RUnlock()
71
72 return json.MarshalIndent(s, "", " ")
73 }
74
75 func (s *discoveryStatus) get(sub subnet, ip string) *discoveredDevice {
76 s.mux.RLock()
77 defer s.mux.RUnlock()
78
79 devices, ok := s.Networks[subKey(sub)]
80 if !ok {
81 return nil
82 }
83 return devices[ip]
84 }
85
86 func (s *discoveryStatus) put(sub subnet, ip string, dev *discoveredDevice) {
87 s.mux.Lock()
88 defer s.mux.Unlock()
89
90 devices, ok := s.Networks[subKey(sub)]
91 if !ok {
92 devices = make(map[string]*discoveredDevice)
93 s.Networks[subKey(sub)] = devices
94 }
95 devices[ip] = dev
96 }
97
98 func (s *discoveryStatus) del(sub subnet, ip string) {
99 s.mux.Lock()
100 defer s.mux.Unlock()
101
102 if devices, ok := s.Networks[subKey(sub)]; ok {
103 delete(devices, ip)
104 }
105 }
106
107 func subKey(s subnet) string {
108 return fmt.Sprintf("%s:%s", s.str, s.credential.Name)
109 }