Skip to content

Commit f09aa24

Browse files
committed
Add support for DNS resolver operational data
Example status output: "infix-system:dns-resolver": { "options": { "timeout": 3, "attempts": 5 }, "search": [ "example.com", "foo.com" ], "server": [ { "address": "1.2.3.4", "origin": "static" }, { "address": "192.168.2.1", "origin": "dhcp", "interface": "e5" } ] } Fixes #510 Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
1 parent 2fb1370 commit f09aa24

File tree

4 files changed

+145
-2
lines changed

4 files changed

+145
-2
lines changed

src/confd/yang/confd.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ MODULES=(
3333
"infix-dhcp-client@2025-01-20.yang"
3434
"infix-dhcp-server@2025-01-13.yang"
3535
"infix-meta@2024-10-18.yang"
36-
"infix-system@2024-11-27.yang"
36+
"infix-system@2025-01-25.yang"
3737
"infix-services@2024-12-03.yang"
3838
"ieee802-ethernet-interface@2019-06-21.yang"
3939
"infix-ethernet-interface@2024-02-27.yang"

src/confd/yang/infix-system.yang

+82-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ module infix-system {
66
import ietf-system {
77
prefix sys;
88
}
9+
import ietf-interfaces {
10+
prefix if;
11+
}
12+
import ietf-yang-types {
13+
prefix yang;
14+
}
915
import iana-timezones {
1016
prefix iana-tz;
1117
}
@@ -22,8 +28,12 @@ module infix-system {
2228
contact "kernelkit@googlegroups.com";
2329
description "Infix augments and deviations to ietf-system.";
2430

31+
revision 2025-01-25 {
32+
description "Add DNS resolver status.";
33+
reference "internal";
34+
}
2535
revision 2024-11-27 {
26-
description "Add NTP status";
36+
description "Add NTP status.";
2737
reference "internal";
2838
}
2939
revision 2024-09-13 {
@@ -305,6 +315,8 @@ module infix-system {
305315
augment "/sys:system-state" {
306316
container ntp {
307317
description "NTP status";
318+
config false;
319+
308320
container sources {
309321
list source {
310322
key address;
@@ -328,11 +340,80 @@ module infix-system {
328340
type uint8;
329341
description "Interval between transmitted NTP messages, expressed as a power of two in seconds";
330342
}
343+
}
344+
}
345+
}
331346

347+
container dns-resolver {
348+
description "List of active DNS servers";
349+
config false;
350+
351+
container options {
352+
description "Resolver options.";
353+
354+
leaf timeout {
355+
description "Number of seconds before resolves tries another server.";
356+
type uint8;
357+
units "seconds";
358+
}
359+
leaf attempts {
360+
description "Number of times the resolver reties before giving up.";
361+
type uint8;
362+
}
363+
}
364+
365+
leaf-list search {
366+
type inet:domain-name;
367+
description "Ordered list of domains to search when resolving a host name.";
368+
}
369+
370+
list server {
371+
key "address";
372+
373+
leaf address {
374+
description "IP address of DNS server";
375+
type inet:ip-address;
376+
}
377+
378+
leaf origin {
379+
description "How DNS server was acquired";
380+
type enumeration {
381+
enum static {
382+
description "Statically configured";
383+
}
384+
enum dhcp {
385+
description "Dynamically acquired via DHCP";
386+
}
387+
}
388+
}
389+
390+
leaf interface {
391+
type if:interface-ref;
392+
description "Interface DNS server was learned from, if DHCP";
393+
}
394+
}
395+
396+
container statistics {
397+
description "DNS resolver statistics";
398+
399+
leaf cache-size {
400+
description "Current number of entries in DNS cache";
401+
type yang:counter32;
402+
}
403+
404+
leaf cache-hits {
405+
description "Number of successful cache lookups";
406+
type yang:counter64;
407+
}
408+
409+
leaf cache-misses {
410+
description "Number of failed cache lookups";
411+
type yang:counter64;
332412
}
333413
}
334414
}
335415
}
416+
336417
deviation "/sys:system/sys:hostname" {
337418
deviate replace {
338419
type infix-sys:hostname;

src/statd/python/yanger/ietf_system.py

+62
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import subprocess
2+
import ipaddress
23

34
from .common import insert
45
from .host import HOST
@@ -61,6 +62,65 @@ def add_ntp(out):
6162

6263
insert(out, "infix-system:ntp", "sources", "source", source)
6364

65+
def add_dns(out):
66+
options = {}
67+
servers = []
68+
search = []
69+
70+
content = HOST.read_multiline("/etc/resolv.conf.head", [])
71+
for line in content:
72+
line = line.strip()
73+
74+
if line.startswith('nameserver'):
75+
ip = line.split()[1]
76+
try:
77+
ipaddress.ip_address(ip)
78+
servers.append({
79+
"address": ip,
80+
"origin": "static"
81+
})
82+
except ValueError:
83+
continue
84+
85+
elif line.startswith('search'):
86+
search.extend(line.split()[1:])
87+
88+
elif line.startswith('options'):
89+
opts = line.split()[1:]
90+
for opt in opts:
91+
if opt.startswith('timeout:'):
92+
options["timeout"] = int(opt.split(':')[1])
93+
elif opt.startswith('attempts:'):
94+
options["attempts"] = int(opt.split(':')[1])
95+
96+
output = HOST.run_multiline(['/sbin/resolvconf', '-l'], [])
97+
for line in output:
98+
line = line.strip()
99+
if line.startswith('nameserver'):
100+
parts = line.split('#', 1)
101+
ip = parts[0].split()[1]
102+
103+
iface = None
104+
if len(parts) > 1:
105+
iface = parts[1].strip()
106+
107+
try:
108+
ipaddress.ip_address(ip)
109+
servers.append({
110+
"address": ip,
111+
"origin": "dhcp",
112+
"interface": iface
113+
})
114+
except ValueError:
115+
continue
116+
117+
elif line.startswith('search'):
118+
search.extend(line.split()[1:])
119+
120+
insert(out, "infix-system:dns-resolver", "options", options)
121+
insert(out, "infix-system:dns-resolver", "server", servers)
122+
insert(out, "infix-system:dns-resolver", "search", search)
123+
64124
def add_software_slots(out, data):
65125
slots = []
66126
for slot in data["slots"]:
@@ -136,4 +196,6 @@ def operational():
136196

137197
add_software(out_state)
138198
add_ntp(out_state)
199+
add_dns(out_state)
200+
139201
return out

0 commit comments

Comments
 (0)