feat: Add option to define which DNS server a DNS monitor queries (#2389)

This commit is contained in:
Sven van Ginkel
2026-09-25 01:01:10 +02:00
committed by GitHub
parent a20a7d2edc
commit f7528a0208
10 changed files with 220 additions and 20 deletions

View File

@@ -17,6 +17,10 @@ func generateMonitorID(systemId string, config monitor.Config) string {
if config.Protocol == "tcp" {
args = append(args, strconv.FormatUint(uint64(config.Port), 10))
}
// only use server for DNS monitors, so the same target queried via different servers gets distinct monitors
if config.Protocol == "dns" {
args = append(args, config.Server)
}
return systems.MakeStableHashId(args...)
}
@@ -53,10 +57,15 @@ func bindNetworkMonitorsEvents(hub *Hub) {
// record with the new ID and delete the old one. Otherwise, just update the existing monitor on the agent.
hub.OnRecordUpdateRequest("network_monitors").BindFunc(func(e *core.RecordRequestEvent) error {
systemID := e.Record.GetString("system")
protocol := e.Record.GetString("protocol")
// only tcp uses port - set other protocols port to zero
if e.Record.GetString("protocol") != "tcp" {
if protocol != "tcp" {
e.Record.Set("port", 0)
}
// only dns uses server - clear it for other protocols
if protocol != "dns" {
e.Record.Set("server", "")
}
ID := generateMonitorID(systemID, *monitorConfigFromRecord(e.Record))
if ID != e.Record.Id {
newRecord := copyMonitorToNewRecord(e.Record, ID)
@@ -103,6 +112,7 @@ func monitorConfigFromRecord(record *core.Record) *monitor.Config {
Protocol: record.GetString("protocol"),
Port: uint16(record.GetInt("port")),
Interval: uint16(record.GetInt("interval")),
Server: record.GetString("server"),
}
}
@@ -127,7 +137,7 @@ func copyMonitorToNewRecord(oldRecord *core.Record, newID string) *core.Record {
collection := oldRecord.Collection()
newRecord := core.NewRecord(collection)
newRecord.Id = newID
fields := []string{"system", "target", "protocol", "port", "interval", "enabled"}
fields := []string{"system", "target", "protocol", "port", "server", "interval", "enabled"}
for _, field := range fields {
newRecord.Set(field, oldRecord.Get(field))
}

View File

@@ -174,6 +174,39 @@ func TestGenerateMonitorID(t *testing.T) {
},
expected: "84167969",
},
{
name: "DNS monitor on example.com with server 1.1.1.1",
systemID: "sys999",
config: monitor.Config{
Protocol: "dns",
Target: "example.com",
Server: "1.1.1.1",
Interval: 30,
},
expected: "2175898b",
},
{
name: "DNS monitor on example.com with different server",
systemID: "sys999",
config: monitor.Config{
Protocol: "dns",
Target: "example.com",
Server: "8.8.8.8",
Interval: 30,
},
expected: "ebcd8b33",
},
{
name: "DNS monitor on example.com with no server (system resolver)",
systemID: "sys999",
config: monitor.Config{
Protocol: "dns",
Target: "example.com",
Server: "",
Interval: 30,
},
expected: "19476a7",
},
}
for _, tt := range tests {
@@ -199,6 +232,7 @@ func TestCopyMonitorToNewRecordDropsResultFields(t *testing.T) {
"target": "https://example.com",
"protocol": "http",
"port": 443,
"server": "1.1.1.1",
"interval": 60,
"enabled": true,
"res": 1200,
@@ -216,6 +250,7 @@ func TestCopyMonitorToNewRecordDropsResultFields(t *testing.T) {
assert.Equal(t, "https://example.com", newRecord.GetString("target"))
assert.Equal(t, "http", newRecord.GetString("protocol"))
assert.Equal(t, 443, newRecord.GetInt("port"))
assert.Equal(t, "1.1.1.1", newRecord.GetString("server"))
assert.True(t, newRecord.GetBool("enabled"))
assert.Contains(t, []string{"", "null"}, newRecord.GetString("certInfo"))
assert.Zero(t, newRecord.GetFloat("res"))