mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
test: new test, dhcp hostname priority test
Verify deterministic hostname management via /etc/hostname.d/, rules: 1. Configured hostname takes precedence over default 2. DHCP hostname takes precedence over configured 3. Hostname reverts when DHCP lease ends Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
test.adoc
|
||||
@@ -0,0 +1,26 @@
|
||||
=== DHCP Hostname Priority
|
||||
|
||||
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/infix_dhcp/client_hostname]
|
||||
|
||||
==== Description
|
||||
|
||||
Verify deterministic hostname management: a DHCP acquired hostname takes
|
||||
precedence over a configured hostname. When a DHCP lease ends, or the
|
||||
hostname option is removed, the system should revert to the configured
|
||||
hostname.
|
||||
|
||||
==== Topology
|
||||
|
||||
image::topology.svg[DHCP Hostname Priority topology, align=center, scaledwidth=75%]
|
||||
|
||||
==== Sequence
|
||||
|
||||
. Set up topology and attach to target DUT
|
||||
. Configure static system hostname
|
||||
. Verify configured hostname is set
|
||||
. Enable DHCP client requesting hostname option
|
||||
. Verify DHCP hostname takes precedence
|
||||
. Drop hostname option from client request
|
||||
. Verify hostname reverts to configured value
|
||||
|
||||
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
"""DHCP Hostname Priority
|
||||
|
||||
Verify deterministic hostname management: a DHCP acquired hostname takes
|
||||
precedence over a configured hostname. When a DHCP lease ends, or the
|
||||
hostname option is removed, the system should revert to the configured
|
||||
hostname.
|
||||
|
||||
"""
|
||||
|
||||
import infamy, infamy.dhcp
|
||||
from infamy.util import until
|
||||
|
||||
|
||||
def verify_hostname(node, expected):
|
||||
"""Verify operational hostname matches expected value"""
|
||||
data = node.get_data("/ietf-system:system")
|
||||
return data["system"]["hostname"] == expected
|
||||
|
||||
|
||||
with infamy.Test() as test:
|
||||
DHCP_HOSTNAME = "dhcp-assigned"
|
||||
CONF_HOSTNAME = "configured-host"
|
||||
|
||||
with test.step("Set up topology and attach to target DUT"):
|
||||
env = infamy.Env()
|
||||
client = env.attach("client", "mgmt")
|
||||
_, host = env.ltop.xlate("host", "mgmt")
|
||||
_, port = env.ltop.xlate("client", "mgmt")
|
||||
|
||||
with test.step("Configure static system hostname"):
|
||||
client.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": CONF_HOSTNAME
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Verify configured hostname is set"):
|
||||
until(lambda: verify_hostname(client, CONF_HOSTNAME))
|
||||
|
||||
with infamy.IsolatedMacVlan(host, mode="private") as netns:
|
||||
netns.addip("10.0.0.1")
|
||||
with infamy.dhcp.Server(netns, ip="10.0.0.42", hostname=DHCP_HOSTNAME):
|
||||
with test.step("Enable DHCP client requesting hostname option"):
|
||||
client.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": port,
|
||||
"ipv4": {
|
||||
"infix-dhcp-client:dhcp": {
|
||||
"option": [
|
||||
{"id": "vendor-class", "value": "infamy"},
|
||||
{"id": "hostname"},
|
||||
{"id": "netmask"},
|
||||
{"id": "router"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Verify DHCP hostname takes precedence"):
|
||||
until(lambda: verify_hostname(client, DHCP_HOSTNAME))
|
||||
|
||||
with test.step("Drop hostname option from client request"):
|
||||
path = f"/ietf-interfaces:interfaces/interface[name='{port}']" \
|
||||
+ "/ietf-ip:ipv4/infix-dhcp-client:dhcp/option[id='hostname']"
|
||||
client.delete_xpath(path)
|
||||
|
||||
with test.step("Verify hostname reverts to configured value"):
|
||||
until(lambda: verify_hostname(client, CONF_HOSTNAME))
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,22 @@
|
||||
graph "1x1" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+100";
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <mgmt> mgmt }",
|
||||
pos="0,20!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
client [
|
||||
label="{ <mgmt> mgmt } | client",
|
||||
pos="200,20!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
host:mgmt -- client:mgmt [requires="mgmt", color=lightgrey]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Title: 1x1 Pages: 1 -->
|
||||
<svg width="474pt" height="45pt"
|
||||
viewBox="0.00 0.00 474.04 45.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 41)">
|
||||
<title>1x1</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-41 470.04,-41 470.04,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-36.5 100,-36.5 100,-0.5 0,-0.5"/>
|
||||
<text text-anchor="middle" x="25" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="50,-0.5 50,-36.5 "/>
|
||||
<text text-anchor="middle" x="75" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
</g>
|
||||
<!-- client -->
|
||||
<g id="node2" class="node">
|
||||
<title>client</title>
|
||||
<polygon fill="none" stroke="black" points="350.04,-0.5 350.04,-36.5 466.04,-36.5 466.04,-0.5 350.04,-0.5"/>
|
||||
<text text-anchor="middle" x="375.04" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="400.04,-0.5 400.04,-36.5 "/>
|
||||
<text text-anchor="middle" x="433.04" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">client</text>
|
||||
</g>
|
||||
<!-- host--client -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:mgmt--client:mgmt</title>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M100,-18.5C100,-18.5 350.04,-18.5 350.04,-18.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -11,6 +11,9 @@
|
||||
- name: DHCP option 121 vs option 3
|
||||
case: client_routes/test.py
|
||||
|
||||
- name: DHCP Hostname Priority
|
||||
case: client_hostname/test.py
|
||||
|
||||
- name: DHCPv6 Basic
|
||||
case: client6_basic/test.py
|
||||
|
||||
|
||||
+7
-3
@@ -8,11 +8,13 @@ class Server:
|
||||
config_file = '/tmp/udhcpd.conf'
|
||||
leases_file = '/tmp/udhcpd.leases'
|
||||
|
||||
def __init__(self, netns, start='192.168.0.100', end='192.168.0.110', netmask='255.255.255.0', ip=None, router=None, prefix=None, iface="iface"):
|
||||
def __init__(self, netns, start='192.168.0.100', end='192.168.0.110',
|
||||
netmask='255.255.255.0', ip=None, router=None, prefix=None,
|
||||
hostname=None, iface="iface"):
|
||||
self.process = None
|
||||
self.netns = netns
|
||||
self.iface = iface
|
||||
self._create_files(start, end, netmask, ip, router, prefix)
|
||||
self._create_files(start, end, netmask, ip, router, prefix, hostname)
|
||||
|
||||
def __del__(self):
|
||||
#print(self.config_file)
|
||||
@@ -26,7 +28,7 @@ class Server:
|
||||
def __exit__(self, _, __, ___):
|
||||
self.stop()
|
||||
|
||||
def _create_files(self, start, end, netmask, ip, router, prefix):
|
||||
def _create_files(self, start, end, netmask, ip, router, prefix, hostname):
|
||||
f = open(self.leases_file, "w")
|
||||
f.close()
|
||||
|
||||
@@ -47,6 +49,8 @@ option lease 864000
|
||||
f.write(f"option router {router}\n")
|
||||
if prefix and router:
|
||||
f.write(f"option staticroutes {prefix} {router}\n")
|
||||
if hostname:
|
||||
f.write(f"option hostname {hostname}\n")
|
||||
|
||||
def get_pid(self):
|
||||
return self.process.pid
|
||||
|
||||
Reference in New Issue
Block a user