mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-31 13:03:02 +02:00
test: new test, verify DHCP server with multiple subnets
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -12,3 +12,5 @@ include::client_routes/Readme.adoc[]
|
||||
include::server_basic/Readme.adoc[]
|
||||
|
||||
include::server_host/Readme.adoc[]
|
||||
|
||||
include::server_subnets/Readme.adoc[]
|
||||
|
||||
@@ -13,3 +13,6 @@
|
||||
|
||||
- name: server_host
|
||||
case: server_host/test.py
|
||||
|
||||
- name: server_subnets
|
||||
case: server_subnets/test.py
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
server_subnets.adoc
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 519 KiB |
@@ -0,0 +1,59 @@
|
||||
=== DHCP Server Multiple Subnets
|
||||
==== Description
|
||||
Verify that the DHCP server is capble of acting on more than one subnet,
|
||||
handing out leases from a pool and static host lease, ensuring global,
|
||||
subnet, and host-specific options are honored and do not leak between
|
||||
subnets.
|
||||
|
||||
.Internal network setup, client2 and client3 are on the same LAN
|
||||
ifdef::topdoc[]
|
||||
image::../../test/case/infix_dhcp/server_subnets/dhcp-subnets.svg[Internal networks]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::server_subnets/dhcp-subnets.svg[Internal networks]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::dhcp-subnets.svg[Internal networks]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
|
||||
To verify isolation of subnet settings, a few "decoys" are added to the
|
||||
configuration of each subnet. These are then checked for on each of the
|
||||
clients. E.g., both subnets have static host configurations, but only
|
||||
one client should match.
|
||||
|
||||
Both DNS and NTP servers are handed out to clients. Some clients have
|
||||
a static DNS and NTP server configured already.
|
||||
|
||||
The test is concluded by the server trying to reach each client using
|
||||
ping of the hostname.
|
||||
|
||||
==== Topology
|
||||
ifdef::topdoc[]
|
||||
image::{topdoc}../../test/case/infix_dhcp/server_subnets/topology.svg[DHCP Server Multiple Subnets topology]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::server_subnets/topology.svg[DHCP Server Multiple Subnets topology]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::topology.svg[DHCP Server Multiple Subnets topology]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
==== Test sequence
|
||||
. Set up topology and attach to client and server DUTs
|
||||
. Configure DHCP server and clients
|
||||
. Verify DHCP client1 get correct lease
|
||||
. Verify DHCP client1 has default route via server
|
||||
. Verify DHCP client1 has correct DNS server(s)
|
||||
. Verify DHCP client2 get correct static lease
|
||||
. Verify DHCP client2 has default route via classless-static-route
|
||||
. Verify DHCP client2 has correct DNS and NTP server(s)
|
||||
. Verify DHCP client3 get correct lease
|
||||
. Verify DHCP client3 has default route via server
|
||||
. Verify DHCP client3 has correct DNS and NTP server(s)
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
Executable
+313
@@ -0,0 +1,313 @@
|
||||
#!/usr/bin/env python3
|
||||
"""DHCP Server Multiple Subnets
|
||||
|
||||
Verify that the DHCP server is capble of acting on more than one subnet,
|
||||
handing out leases from a pool and static host lease, ensuring global,
|
||||
subnet, and host-specific options are honored and do not leak between
|
||||
subnets.
|
||||
|
||||
.Internal network setup, client2 and client3 are on the same LAN
|
||||
image::dhcp-subnets.svg[Internal networks]
|
||||
|
||||
To verify isolation of subnet settings, a few "decoys" are added to the
|
||||
configuration of each subnet. These are then checked for on each of the
|
||||
clients. E.g., both subnets have static host configurations, but only
|
||||
one client should match.
|
||||
|
||||
Both DNS and NTP servers are handed out to clients. Some clients have
|
||||
a static DNS and NTP server configured already.
|
||||
|
||||
The test is concluded by the server trying to reach each client using
|
||||
ping of the hostname.
|
||||
|
||||
"""
|
||||
import infamy
|
||||
import infamy.iface as iface
|
||||
import infamy.route as route
|
||||
from infamy.util import until
|
||||
|
||||
|
||||
def has_dns_server(data, dns_servers):
|
||||
"""Verify system have all the given DNS servers"""
|
||||
servers = data.get('system-state', {}) \
|
||||
.get('dns-resolver', {}) \
|
||||
.get('server')
|
||||
if not servers:
|
||||
return False
|
||||
|
||||
configured = {server['address'] for server in servers}
|
||||
return all(server in configured for server in dns_servers)
|
||||
|
||||
|
||||
def has_ntp_server(data, ntp_server):
|
||||
"""Verify system has, or does *not* have*, an NTP server"""
|
||||
sources = data.get('system-state', {}) \
|
||||
.get('ntp', {}) \
|
||||
.get('sources', {}) \
|
||||
.get('source')
|
||||
if not ntp_server:
|
||||
# This system should *not* have any NTP server
|
||||
return not sources
|
||||
|
||||
if not sources:
|
||||
return False
|
||||
|
||||
for source in sources:
|
||||
if source['address'] == ntp_server:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def has_system_servers(dut, dns, ntp=None):
|
||||
"""Verify DUT have all DNS and, if given, NTP server(s)"""
|
||||
data = dut.get_data("/ietf-system:system-state")
|
||||
if data is None:
|
||||
return False
|
||||
|
||||
return has_dns_server(data, dns) and has_ntp_server(data, ntp)
|
||||
|
||||
|
||||
with infamy.Test() as test:
|
||||
SERVER1 = '192.168.1.1'
|
||||
POOL1 = '192.168.1.100'
|
||||
ADDR1 = '192.168.1.11'
|
||||
SERVER2 = '192.168.2.1'
|
||||
POOL2 = '192.168.2.200'
|
||||
ADDR2 = '192.168.2.22'
|
||||
GW1 = '192.168.1.11'
|
||||
GW2 = '192.168.2.2'
|
||||
HOSTNM1 = 'client1'
|
||||
HOSTNM2 = 'client2'
|
||||
HOSTNM3 = 'client3'
|
||||
|
||||
with test.step("Set up topology and attach to client and server DUTs"):
|
||||
env = infamy.Env()
|
||||
server = env.attach("server", "mgmt")
|
||||
client1 = env.attach("client1", "mgmt")
|
||||
client2 = env.attach("client2", "mgmt")
|
||||
client3 = env.attach("client3", "mgmt")
|
||||
|
||||
with test.step("Configure DHCP server and clients"):
|
||||
server.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": server["client1"],
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": SERVER1,
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": "br0",
|
||||
"type": "infix-if-type:bridge",
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": SERVER2,
|
||||
"prefix-length": 24,
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
"name": server["client2"],
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
}, {
|
||||
"name": server["client3"],
|
||||
"infix-interfaces:bridge-port": {
|
||||
"bridge": "br0"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
"infix-dhcp-server": {
|
||||
"dhcp-server": {
|
||||
"option": [
|
||||
{
|
||||
"id": "dns-server",
|
||||
"address": "auto"
|
||||
},
|
||||
],
|
||||
# No client should get the static host lease on this
|
||||
# subnet. Only a pool address and global options.
|
||||
"subnet": [
|
||||
{
|
||||
"subnet": "192.168.1.0/24",
|
||||
"option": [{
|
||||
"id": "router",
|
||||
"address": "auto"
|
||||
}],
|
||||
"pool": {
|
||||
"start-address": POOL1,
|
||||
"end-address": POOL1
|
||||
},
|
||||
# Decoy, client2 should not get this lease!
|
||||
"host": [{
|
||||
"address": ADDR1,
|
||||
"match": {
|
||||
"hostname": HOSTNM2
|
||||
},
|
||||
"option": [{
|
||||
"id": "classless-static-route",
|
||||
"static-route": [{
|
||||
"destination": "0.0.0.0/0",
|
||||
"next-hop": GW1
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"subnet": "192.168.2.0/24",
|
||||
"option": [
|
||||
{
|
||||
"id": "ntp-server",
|
||||
"address": "auto"
|
||||
}, {
|
||||
# Verify correct option selection in
|
||||
# client: option 3 < option 121
|
||||
"id": "router",
|
||||
"address": "auto"
|
||||
}
|
||||
],
|
||||
"pool": {
|
||||
"start-address": POOL2,
|
||||
"end-address": POOL2
|
||||
},
|
||||
"host": [{
|
||||
"address": ADDR2,
|
||||
"match": {
|
||||
"hostname": HOSTNM2
|
||||
},
|
||||
"option": [{
|
||||
"id": "classless-static-route",
|
||||
"static-route": [{
|
||||
"destination": "0.0.0.0/0",
|
||||
"next-hop": GW2
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
]
|
||||
}
|
||||
}})
|
||||
|
||||
# All clients request/accept the same options. We do this to
|
||||
# both keep fleet configuration simple but also to verify that
|
||||
# the server is behaving correctly.
|
||||
|
||||
client1.put_config_dicts({
|
||||
"infix-dhcp-client": {
|
||||
"dhcp-client": {
|
||||
"client-if": [{
|
||||
"if-name": client1["server"],
|
||||
"option": [
|
||||
{"id": "hostname", "value": "auto"},
|
||||
{"id": "router"},
|
||||
{"id": "dns"},
|
||||
{"id": "ntpsrv"},
|
||||
{"id": 121}
|
||||
]
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": HOSTNM1,
|
||||
"ntp": {"enabled": True},
|
||||
}
|
||||
}})
|
||||
|
||||
client2.put_config_dicts({
|
||||
"infix-dhcp-client": {
|
||||
"dhcp-client": {
|
||||
"client-if": [{
|
||||
"if-name": client2["server"],
|
||||
"option": [
|
||||
{"id": "hostname", "value": "auto"},
|
||||
{"id": "router"},
|
||||
{"id": "dns"},
|
||||
{"id": "ntpsrv"},
|
||||
{"id": 121}
|
||||
]
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": HOSTNM2,
|
||||
"ntp": {"enabled": True},
|
||||
}
|
||||
}})
|
||||
|
||||
client3.put_config_dicts({
|
||||
"infix-dhcp-client": {
|
||||
"dhcp-client": {
|
||||
"client-if": [{
|
||||
"if-name": client3["server"],
|
||||
"option": [
|
||||
{"id": "hostname", "value": "auto"},
|
||||
{"id": "router"},
|
||||
{"id": "dns"},
|
||||
{"id": "ntpsrv"},
|
||||
{"id": 121}
|
||||
]
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"hostname": HOSTNM3,
|
||||
"ntp": {"enabled": True},
|
||||
"dns-resolver": {
|
||||
"search": [
|
||||
"example.com",
|
||||
"kernelkit.org"
|
||||
],
|
||||
"server": [
|
||||
{
|
||||
"name": "static",
|
||||
"udp-and-tcp": {
|
||||
"address": "1.2.3.4"
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"timeout": 3,
|
||||
"attempts": 5
|
||||
}
|
||||
},
|
||||
}
|
||||
}})
|
||||
|
||||
with test.step("Verify DHCP client1 get correct lease"):
|
||||
until(lambda: iface.address_exist(client1, client1["server"], POOL1))
|
||||
|
||||
with test.step("Verify DHCP client1 has default route via server"):
|
||||
until(lambda: route.ipv4_route_exist(client1, "0.0.0.0/0", nexthop=SERVER1))
|
||||
|
||||
with test.step("Verify DHCP client1 has correct DNS server(s)"):
|
||||
until(lambda: has_system_servers(client1, ["192.168.1.1"]))
|
||||
|
||||
with test.step("Verify DHCP client2 get correct static lease"):
|
||||
until(lambda: iface.address_exist(client2, client2["server"], ADDR2))
|
||||
|
||||
with test.step("Verify DHCP client2 has default route via classless-static-route"):
|
||||
until(lambda: route.ipv4_route_exist(client2, "0.0.0.0/0", nexthop=GW2))
|
||||
|
||||
with test.step("Verify DHCP client2 has correct DNS and NTP server(s)"):
|
||||
until(lambda: has_system_servers(client2, ["192.168.2.1"], "192.168.2.1"))
|
||||
|
||||
with test.step("Verify DHCP client3 get correct lease"):
|
||||
until(lambda: iface.address_exist(client3, client3["server"], POOL2))
|
||||
|
||||
with test.step("Verify DHCP client3 has default route via server"):
|
||||
until(lambda: route.ipv4_route_exist(client3, "0.0.0.0/0", nexthop=SERVER2))
|
||||
|
||||
with test.step("Verify DHCP client3 has correct DNS and NTP server(s)"):
|
||||
until(lambda: has_system_servers(client3, ["1.2.3.4", "192.168.2.1"], "192.168.2.1"))
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,51 @@
|
||||
graph "server subnets" {
|
||||
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 | { <client1> client1 | <server> server | <client3> client3 | <client2> client2 }",
|
||||
pos="0,120!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
client1 [
|
||||
label="{ <mgmt> mgmt | <server> server} | client1",
|
||||
pos="20,130!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
server [
|
||||
label="{ <client1> client1 | <mgmt> mgmt | { <client2> client2 | <client3> client3 } } | server ",
|
||||
pos="20,120!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
client2 [
|
||||
label="{ <server> server | <mgmt> mgmt } | client2",
|
||||
pos="10,110!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
client3 [
|
||||
label="{ <server> server | <mgmt> mgmt } | client3",
|
||||
pos="30,110!",
|
||||
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
host:server -- server:mgmt [requires="mgmt", color=lightgrey]
|
||||
host:client1 -- client1:mgmt [requires="mgmt", color=lightgrey]
|
||||
host:client2 -- client2:mgmt [requires="mgmt", color=lightgrey]
|
||||
host:client3 -- client3:mgmt [requires="mgmt", color=lightgrey]
|
||||
|
||||
server:client1 -- client1:server [color=blue, fontcolor=black, taillabel="192.168.1.1/24"]
|
||||
server:client2 -- client2:server [color=green]
|
||||
server:client3 -- client3:server [color=green, fontcolor=black, taillabel="192.168.2.1/24"]
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?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: server subnets Pages: 1 -->
|
||||
<svg width="650pt" height="395pt"
|
||||
viewBox="0.00 0.00 650.05 395.03" 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 391.03)">
|
||||
<title>server subnets</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-391.03 646.05,-391.03 646.05,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="0,-147.52 0,-239.52 124,-239.52 124,-147.52 0,-147.52"/>
|
||||
<text text-anchor="middle" x="25" y="-189.82" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="50,-147.52 50,-239.52 "/>
|
||||
<text text-anchor="middle" x="87" y="-224.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">client1</text>
|
||||
<polyline fill="none" stroke="black" points="50,-216.52 124,-216.52 "/>
|
||||
<text text-anchor="middle" x="87" y="-201.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">server</text>
|
||||
<polyline fill="none" stroke="black" points="50,-193.52 124,-193.52 "/>
|
||||
<text text-anchor="middle" x="87" y="-178.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">client3</text>
|
||||
<polyline fill="none" stroke="black" points="50,-170.52 124,-170.52 "/>
|
||||
<text text-anchor="middle" x="87" y="-155.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">client2</text>
|
||||
</g>
|
||||
<!-- client1 -->
|
||||
<g id="node2" class="node">
|
||||
<title>client1</title>
|
||||
<polygon fill="none" stroke="black" points="332.03,-340.53 332.03,-386.53 472.03,-386.53 472.03,-340.53 332.03,-340.53"/>
|
||||
<text text-anchor="middle" x="365.03" y="-371.33" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="332.03,-363.53 398.03,-363.53 "/>
|
||||
<text text-anchor="middle" x="365.03" y="-348.33" font-family="DejaVu Sans Mono, Book" font-size="14.00">server</text>
|
||||
<polyline fill="none" stroke="black" points="398.03,-340.53 398.03,-386.53 "/>
|
||||
<text text-anchor="middle" x="435.03" y="-359.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">client1</text>
|
||||
</g>
|
||||
<!-- host--client1 -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>host:client1--client1:mgmt</title>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M124,-228.52C124,-228.52 332.03,-375.53 332.03,-375.53"/>
|
||||
</g>
|
||||
<!-- server -->
|
||||
<g id="node3" class="node">
|
||||
<title>server</title>
|
||||
<polygon fill="none" stroke="black" points="291.03,-159.02 291.03,-228.02 513.03,-228.02 513.03,-159.02 291.03,-159.02"/>
|
||||
<text text-anchor="middle" x="365.03" y="-212.82" font-family="DejaVu Sans Mono, Book" font-size="14.00">client1</text>
|
||||
<polyline fill="none" stroke="black" points="291.03,-205.02 439.03,-205.02 "/>
|
||||
<text text-anchor="middle" x="365.03" y="-189.82" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="291.03,-182.02 439.03,-182.02 "/>
|
||||
<text text-anchor="middle" x="328.03" y="-166.82" font-family="DejaVu Sans Mono, Book" font-size="14.00">client2</text>
|
||||
<polyline fill="none" stroke="black" points="365.03,-159.02 365.03,-182.02 "/>
|
||||
<text text-anchor="middle" x="402.03" y="-166.82" font-family="DejaVu Sans Mono, Book" font-size="14.00">client3</text>
|
||||
<polyline fill="none" stroke="black" points="439.03,-159.02 439.03,-228.02 "/>
|
||||
<text text-anchor="middle" x="476.03" y="-189.82" 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="M124,-205.52C124,-205.52 291.03,-193.52 291.03,-193.52"/>
|
||||
</g>
|
||||
<!-- client2 -->
|
||||
<g id="node4" class="node">
|
||||
<title>client2</title>
|
||||
<polygon fill="none" stroke="black" points="162.02,-0.5 162.02,-46.5 302.02,-46.5 302.02,-0.5 162.02,-0.5"/>
|
||||
<text text-anchor="middle" x="195.02" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">server</text>
|
||||
<polyline fill="none" stroke="black" points="162.02,-23.5 228.02,-23.5 "/>
|
||||
<text text-anchor="middle" x="195.02" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="228.02,-0.5 228.02,-46.5 "/>
|
||||
<text text-anchor="middle" x="265.02" y="-19.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">client2</text>
|
||||
</g>
|
||||
<!-- host--client2 -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>host:client2--client2:mgmt</title>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M124,-158.52C124,-158.52 162.02,-11.5 162.02,-11.5"/>
|
||||
</g>
|
||||
<!-- client3 -->
|
||||
<g id="node5" class="node">
|
||||
<title>client3</title>
|
||||
<polygon fill="none" stroke="black" points="502.05,-0.5 502.05,-46.5 642.05,-46.5 642.05,-0.5 502.05,-0.5"/>
|
||||
<text text-anchor="middle" x="535.05" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">server</text>
|
||||
<polyline fill="none" stroke="black" points="502.05,-23.5 568.05,-23.5 "/>
|
||||
<text text-anchor="middle" x="535.05" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="568.05,-0.5 568.05,-46.5 "/>
|
||||
<text text-anchor="middle" x="605.05" y="-19.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">client3</text>
|
||||
</g>
|
||||
<!-- host--client3 -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>host:client3--client3:mgmt</title>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M124,-181.52C124,-181.52 502.05,-11.5 502.05,-11.5"/>
|
||||
</g>
|
||||
<!-- server--client1 -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>server:client1--client1:server</title>
|
||||
<path fill="none" stroke="blue" stroke-width="2" d="M365.03,-228.52C365.03,-228.52 365.03,-340.53 365.03,-340.53"/>
|
||||
<text text-anchor="middle" x="310.53" y="-232.32" font-family="DejaVu Serif, Book" font-size="14.00">192.168.1.1/24</text>
|
||||
</g>
|
||||
<!-- server--client2 -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>server:client2--client2:server</title>
|
||||
<path fill="none" stroke="green" stroke-width="2" d="M291.03,-170.52C291.03,-170.52 195.02,-46.5 195.02,-46.5"/>
|
||||
</g>
|
||||
<!-- server--client3 -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>server:client3--client3:server</title>
|
||||
<path fill="none" stroke="green" stroke-width="2" d="M402.03,-158.52C402.03,-158.52 502.05,-35.5 502.05,-35.5"/>
|
||||
<text text-anchor="middle" x="347.53" y="-147.32" font-family="DejaVu Serif, Book" font-size="14.00">192.168.2.1/24</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.5 KiB |
Reference in New Issue
Block a user