mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-30 20:43:02 +02:00
Merge pull request #1410 from saba8814/issue-782-dhcp-ntp-dns
Issue 782 dhcp ntp dns
This commit is contained in:
@@ -5,5 +5,7 @@ Integration tests verifying multiple software components working
|
||||
together:
|
||||
|
||||
- OSPF routing with containerized applications and network segmentation
|
||||
- Combined static and DHCP-provided DNS and NTP servers
|
||||
|
||||
include::dhcp_ntp_dns_combination/Readme.adoc[]
|
||||
include::ospf_container/Readme.adoc[]
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
- name: DHCP NTP DNS combination
|
||||
case: dhcp_ntp_dns_combination/test.py
|
||||
|
||||
- name: OSPF Container
|
||||
case: ospf_container/test.py
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
test.adoc
|
||||
@@ -0,0 +1,21 @@
|
||||
=== DHCP NTP DNS combination
|
||||
|
||||
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/use_case/dhcp_ntp_dns_combination]
|
||||
|
||||
==== Description
|
||||
|
||||
Verify statically configured DNS and NTP servers are not lost when receiving
|
||||
servers from a DHCP server.
|
||||
|
||||
==== Topology
|
||||
|
||||
image::topology.svg[DHCP NTP DNS combination topology, align=center, scaledwidth=75%]
|
||||
|
||||
==== Sequence
|
||||
|
||||
. Set up topology and configure static IP on client
|
||||
. Configure static DNS and NTP on client and verify
|
||||
. Set up DHCP server with NTP and DNS options
|
||||
. Configure client to use DHCP and verify combined servers
|
||||
|
||||
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Combined test of DHCP + NTP + DNS
|
||||
|
||||
Verify statically configured DNS and NTP servers are not lost when receiving
|
||||
servers from a DHCP server.
|
||||
"""
|
||||
import infamy
|
||||
import infamy.iface as iface
|
||||
from infamy.util import until
|
||||
|
||||
def any_dhcp_address(target, iface_name):
|
||||
try:
|
||||
addrs = iface.get_ipv4_address(target, iface_name)
|
||||
if addrs:
|
||||
for addr in addrs:
|
||||
# Origin can be 'dhcp' or 'ietf-ip:dhcp' depending on how it's reported
|
||||
if addr.get('origin') in ['dhcp', 'ietf-ip:dhcp']:
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
return False
|
||||
|
||||
def has_dns_server(target, dns_servers):
|
||||
"""Verify system has all the given DNS servers in operational state"""
|
||||
data = target.get_data("/ietf-system:system-state/infix-system:dns-resolver")
|
||||
if not data:
|
||||
return False
|
||||
|
||||
# In Infix, augmented nodes show up under their name in system-state
|
||||
resolver = data.get('system-state', {}).get('dns-resolver', {})
|
||||
servers = resolver.get('server', [])
|
||||
current_addresses = {s.get('address') for s in servers}
|
||||
return all(addr in current_addresses for addr in dns_servers)
|
||||
|
||||
def has_ntp_server(target, ntp_servers):
|
||||
"""Verify system has all the given NTP servers in operational state"""
|
||||
data = target.get_data("/ietf-system:system-state/infix-system:ntp")
|
||||
if not data:
|
||||
return False
|
||||
|
||||
ntp_state = data.get('system-state', {}).get('ntp', {})
|
||||
sources = ntp_state.get('sources', {}).get('source', [])
|
||||
current_addresses = {s.get('address') for s in sources}
|
||||
return all(addr in current_addresses for addr in ntp_servers)
|
||||
|
||||
def has_system_servers(target, dns, ntp_list):
|
||||
"""Verify DUT has all DNS and NTP server(s)"""
|
||||
return has_dns_server(target, dns) and has_ntp_server(target, ntp_list)
|
||||
|
||||
|
||||
with infamy.Test() as test:
|
||||
SERVER_IP = '192.168.3.1'
|
||||
CLIENT_STATIC_IP = '192.168.3.10'
|
||||
|
||||
STATIC_DNS = '1.1.1.1'
|
||||
STATIC_NTP = '2.2.2.2'
|
||||
|
||||
DHCP_DNS = SERVER_IP
|
||||
DHCP_NTP = SERVER_IP
|
||||
|
||||
with test.step("Set up topology and configure static IP on client"):
|
||||
env = infamy.Env()
|
||||
server = env.attach("server", "mgmt")
|
||||
client = env.attach("client", "mgmt")
|
||||
|
||||
client_data = client["server"]
|
||||
server_data = server["client"]
|
||||
|
||||
# Configure server with static IP and NTP server
|
||||
server.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": server_data,
|
||||
"type": "infix-if-type:ethernet",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{"ip": SERVER_IP, "prefix-length": 24}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-ntp": {
|
||||
"ntp": {
|
||||
"refclock-master": {"master-stratum": 8}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
# Configure client with static IP
|
||||
client.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": client_data,
|
||||
"type": "infix-if-type:ethernet",
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{"ip": CLIENT_STATIC_IP, "prefix-length": 24}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
until(lambda: iface.address_exist(client, client_data, CLIENT_STATIC_IP, proto="static"))
|
||||
print("Initial IP connectivity established")
|
||||
|
||||
with test.step("Configure static DNS and NTP on client and verify"):
|
||||
client.put_config_dicts({
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"ntp": {
|
||||
"enabled": True,
|
||||
"server": [{
|
||||
"name": "static-ntp",
|
||||
"udp": {"address": STATIC_NTP},
|
||||
"iburst": True
|
||||
}]
|
||||
},
|
||||
"dns-resolver": {
|
||||
"server": [{
|
||||
"name": "static-dns",
|
||||
"udp-and-tcp": {"address": STATIC_DNS}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
print("Waiting for static servers to appear in operational state...")
|
||||
until(lambda: has_system_servers(client, [STATIC_DNS], [STATIC_NTP]),
|
||||
attempts=30)
|
||||
print("Static DNS and NTP servers verified")
|
||||
|
||||
with test.step("Set up DHCP server with NTP and DNS options"):
|
||||
server.put_config_dicts({
|
||||
"infix-dhcp-server": {
|
||||
"dhcp-server": {
|
||||
"subnet": [{
|
||||
"subnet": "192.168.3.0/24",
|
||||
"interface": server_data,
|
||||
"pool": {
|
||||
"start-address": "192.168.3.100",
|
||||
"end-address": "192.168.3.150"
|
||||
},
|
||||
"option": [
|
||||
{"id": "router", "address": SERVER_IP},
|
||||
{"id": "dns-server", "address": DHCP_DNS},
|
||||
{"id": "ntp-server", "address": DHCP_NTP}
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
print("DHCP server configured on server DUT")
|
||||
|
||||
with test.step("Configure client to use DHCP and verify combined servers"):
|
||||
# Explicitly delete static config using full path
|
||||
try:
|
||||
# Try to delete the entire ipv4 container from ietf-ip
|
||||
client.delete_xpath(f"ietf-interfaces:interfaces/interface[name='{client_data}']/ietf-ip:ipv4")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Enable DHCP
|
||||
client.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": client_data,
|
||||
"ipv4": {
|
||||
"infix-dhcp-client:dhcp": {
|
||||
"client-id": "client-1",
|
||||
"option": [
|
||||
{"id": "dns-server"},
|
||||
{"id": "ntp-server"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
print("Waiting for DHCP lease...")
|
||||
until(lambda: any_dhcp_address(client, client_data), attempts=120)
|
||||
print("Client got DHCP address")
|
||||
|
||||
print("Verifying combined DNS and NTP servers...")
|
||||
# Expected DNS: STATIC_DNS (1.1.1.1) AND DHCP_DNS (192.168.3.1)
|
||||
# Expected NTP: STATIC_NTP (2.2.2.2) AND DHCP_NTP (192.168.3.1)
|
||||
until(lambda: has_system_servers(client, [STATIC_DNS, DHCP_DNS], [STATIC_NTP, DHCP_NTP]),
|
||||
attempts=60)
|
||||
print("SUCCESS: Combined static and DHCP servers verified")
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,31 @@
|
||||
graph "dhcp_ntp_dns_combination" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+40";
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <client> client | <server> server }",
|
||||
pos="0,120!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
client [
|
||||
label="{ <mgmt> mgmt | <server> server} | client",
|
||||
pos="20,130!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
server [
|
||||
label="{ <client> client | <mgmt> mgmt } | server",
|
||||
pos="20,120!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
host:server -- server:mgmt [requires="mgmt", color=lightgrey]
|
||||
host:client -- client:mgmt [requires="mgmt", color=lightgrey]
|
||||
|
||||
server:client -- client:server [color=blue, fontcolor=black]
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?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: dhcp_ntp_dns_combination Pages: 1 -->
|
||||
<svg width="426pt" height="202pt"
|
||||
viewBox="0.00 0.00 426.03 202.01" 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 198.01)">
|
||||
<title>dhcp_ntp_dns_combination</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-198.01 422.03,-198.01 422.03,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-46.5 116,-46.5 116,-0.5 0,-0.5"/>
|
||||
<text text-anchor="middle" x="25" y="-19.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="50,-0.5 50,-46.5 "/>
|
||||
<text text-anchor="middle" x="83" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">client</text>
|
||||
<polyline fill="none" stroke="black" points="50,-23.5 116,-23.5 "/>
|
||||
<text text-anchor="middle" x="83" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">server</text>
|
||||
</g>
|
||||
<!-- client -->
|
||||
<g id="node2" class="node">
|
||||
<title>client</title>
|
||||
<polygon fill="none" stroke="black" points="286.03,-147.51 286.03,-193.51 418.03,-193.51 418.03,-147.51 286.03,-147.51"/>
|
||||
<text text-anchor="middle" x="319.03" y="-178.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="286.03,-170.51 352.03,-170.51 "/>
|
||||
<text text-anchor="middle" x="319.03" y="-155.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">server</text>
|
||||
<polyline fill="none" stroke="black" points="352.03,-147.51 352.03,-193.51 "/>
|
||||
<text text-anchor="middle" x="385.03" y="-166.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">client</text>
|
||||
</g>
|
||||
<!-- host--client -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>host:client--client:mgmt</title>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M116,-35.5C116,-35.5 286.03,-182.51 286.03,-182.51"/>
|
||||
</g>
|
||||
<!-- server -->
|
||||
<g id="node3" class="node">
|
||||
<title>server</title>
|
||||
<polygon fill="none" stroke="black" points="286.03,-0.5 286.03,-46.5 418.03,-46.5 418.03,-0.5 286.03,-0.5"/>
|
||||
<text text-anchor="middle" x="319.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">client</text>
|
||||
<polyline fill="none" stroke="black" points="286.03,-23.5 352.03,-23.5 "/>
|
||||
<text text-anchor="middle" x="319.03" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="352.03,-0.5 352.03,-46.5 "/>
|
||||
<text text-anchor="middle" x="385.03" y="-19.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">server</text>
|
||||
</g>
|
||||
<!-- host--server -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:server--server:mgmt</title>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M116,-11.5C116,-11.5 286.03,-11.5 286.03,-11.5"/>
|
||||
</g>
|
||||
<!-- server--client -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>server:client--client:server</title>
|
||||
<path fill="none" stroke="blue" stroke-width="2" d="M319.03,-46.5C319.03,-46.5 319.03,-147.51 319.03,-147.51"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
Reference in New Issue
Block a user