Skip to content

Commit 4d5e406

Browse files
Merge pull request #745 from rackerlabs/esx-netscripts
feat: ESX network configuration scripts for Undercloud
2 parents a38b7c9 + d9d93ba commit 4d5e406

22 files changed

+1336
-0
lines changed

python/esxi-netinit/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# ESX Networking setup scripts
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"links": [
3+
{
4+
"ethernet_mac_address": "14:23:f3:f5:21:50",
5+
"id": "c23067a8-b2ca-4114-9fa9-32b0b9151e18",
6+
"mtu": 1500,
7+
"type": "vif",
8+
"vif_id": "145cfec6-bedb-444c-9ef1-de1bfef67b2a"
9+
}
10+
],
11+
"networks": [
12+
{
13+
"id": "b0fa63d0-fb0c-446f-bfd3-26c0a50730c0",
14+
"ip_address": "10.4.50.118",
15+
"link": "c23067a8-b2ca-4114-9fa9-32b0b9151e18",
16+
"netmask": "255.255.255.192",
17+
"network_id": "c57e4a02-73bb-4c6e-ab03-537ea11168e3",
18+
"routes": [
19+
{
20+
"gateway": "10.4.50.65",
21+
"netmask": "0.0.0.0",
22+
"network": "0.0.0.0"
23+
}
24+
],
25+
"type": "ipv4"
26+
}
27+
],
28+
"services": [
29+
{
30+
"address": "10.4.204.3",
31+
"type": "dns"
32+
}
33+
]
34+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{
2+
"links": [
3+
{
4+
"id": "tap47bb4c37-f6",
5+
"vif_id": "47bb4c37-f60d-474f-8ce5-c7c1d9982585",
6+
"type": "phy",
7+
"mtu": 1450,
8+
"ethernet_mac_address": "14:23:f3:f5:3a:d0"
9+
},
10+
{
11+
"id": "tap1b9c25a9-39",
12+
"vif_id": "1b9c25a9-396f-43e7-9f1c-a2dcdfd3989c",
13+
"type": "vlan",
14+
"mtu": 1450,
15+
"ethernet_mac_address": "fa:16:3e:07:86:96",
16+
"vlan_link": "tap47bb4c37-f6",
17+
"vlan_id": 111,
18+
"vlan_mac_address": "fa:16:3e:07:86:96"
19+
},
20+
{
21+
"id": "tape3fbe9a7-93",
22+
"vif_id": "e3fbe9a7-933d-4e27-8ac5-858054be7772",
23+
"type": "vlan",
24+
"mtu": 1450,
25+
"ethernet_mac_address": "fa:16:3e:31:50:d6",
26+
"vlan_link": "tap47bb4c37-f6",
27+
"vlan_id": 222,
28+
"vlan_mac_address": "fa:16:3e:31:50:d6"
29+
},
30+
{
31+
"id": "tapd097f698-89",
32+
"vif_id": "d097f698-8926-44e1-afe7-09fb03947f23",
33+
"type": "vlan",
34+
"mtu": 1450,
35+
"ethernet_mac_address": "fa:16:3e:48:91:ef",
36+
"vlan_link": "tap47bb4c37-f6",
37+
"vlan_id": 444,
38+
"vlan_mac_address": "fa:16:3e:48:91:ef"
39+
}
40+
],
41+
"networks": [
42+
{
43+
"id": "network0",
44+
"type": "ipv4",
45+
"link": "tap47bb4c37-f6",
46+
"ip_address": "192.168.100.170",
47+
"netmask": "255.255.255.0",
48+
"routes": [
49+
{
50+
"network": "0.0.0.0",
51+
"netmask": "0.0.0.0",
52+
"gateway": "192.168.100.1"
53+
}
54+
],
55+
"network_id": "783b4239-7220-4a74-8253-415539469860",
56+
"services": []
57+
},
58+
{
59+
"id": "network1",
60+
"type": "ipv4",
61+
"link": "tap1b9c25a9-39",
62+
"ip_address": "192.168.200.174",
63+
"netmask": "255.255.255.0",
64+
"routes": [],
65+
"network_id": "9608ea7d-18d9-4298-8951-ac9dbe20db06",
66+
"services": []
67+
},
68+
{
69+
"id": "network2",
70+
"type": "ipv4",
71+
"link": "tape3fbe9a7-93",
72+
"ip_address": "192.168.0.24",
73+
"netmask": "255.255.255.0",
74+
"routes": [],
75+
"network_id": "ecff22e4-b364-4575-9d2b-dffc83c8d5b7",
76+
"services": []
77+
},
78+
{
79+
"id": "network3",
80+
"type": "ipv4",
81+
"link": "tapd097f698-89",
82+
"ip_address": "192.168.10.133",
83+
"netmask": "255.255.255.0",
84+
"routes": [],
85+
"network_id": "c47d5a38-c646-42e8-b6ca-3eecc977d645",
86+
"services": []
87+
}
88+
],
89+
"services": []
90+
}

python/esxi-netinit/netinit/__init__.py

Whitespace-only changes.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from functools import cached_property
2+
3+
from .esxhost import ESXHost
4+
from .network_data import NetworkData
5+
from .nic import NIC
6+
from .nic_list import NICList
7+
8+
9+
class ESXConfig:
10+
def __init__(self, network_data: NetworkData, dry_run=False) -> None:
11+
self.network_data = network_data
12+
self.dry_run = dry_run
13+
self.host = ESXHost(dry_run)
14+
15+
def add_default_mgmt_interface(
16+
self, portgroup_name, switch_name, interface_name="vmk0"
17+
):
18+
self.host.portgroup_add(portgroup_name=portgroup_name, switch_name=switch_name)
19+
self.host.add_ip_interface(name=interface_name, portgroup_name=portgroup_name)
20+
21+
def clean_default_network_setup(self, portgroup_name, switch_name):
22+
"""Removes default networking setup left by the installer."""
23+
self.host.delete_vmknic(portgroup_name=portgroup_name)
24+
self.host.portgroup_remove(
25+
switch_name=switch_name, portgroup_name=portgroup_name
26+
)
27+
self.host.destroy_vswitch(name=switch_name)
28+
29+
def configure_default_route(self):
30+
"""Configures default route.
31+
32+
If multiple default routes are present, only first one is used.
33+
"""
34+
route = self.network_data.default_route()
35+
self.host.configure_default_route(route.gateway)
36+
37+
def configure_portgroups(self, switch_name="vSwitch0"):
38+
portgroups = []
39+
for link in self.network_data.links:
40+
if link.type == "vlan":
41+
vid = link.vlan_id
42+
pg_name = f"internal_net_vid_{vid}"
43+
self.host.portgroup_add(portgroup_name=pg_name, switch_name=switch_name)
44+
self.host.portgroup_set_vlan(portgroup_name=pg_name, vlan_id=vid)
45+
portgroups.append(pg_name)
46+
return portgroups
47+
48+
def configure_management_interface(self):
49+
mgmt_network = next(
50+
net for net in self.network_data.networks if net.default_routes()
51+
)
52+
return self.host.change_ip(
53+
"vmk0", mgmt_network.ip_address, mgmt_network.netmask
54+
)
55+
56+
def configure_vswitch(self, uplink: NIC, switch_name: str, mtu: int):
57+
"""Sets up vSwitch."""
58+
self.host.create_vswitch(switch_name)
59+
self.host.uplink_add(nic=uplink.name, switch_name=switch_name)
60+
self.host.vswitch_failover_uplinks(
61+
active_uplinks=[uplink.name], name=switch_name
62+
)
63+
self.host.vswitch_security(name=switch_name)
64+
self.host.vswitch_settings(mtu=mtu, name=switch_name)
65+
66+
def configure_requested_dns(self):
67+
"""Configures DNS servers that were provided in network_data.json."""
68+
dns_servers = [
69+
srv.address for srv in self.network_data.services if srv.type == "dns"
70+
]
71+
if not dns_servers:
72+
return
73+
74+
return self.host.configure_dns(servers=dns_servers)
75+
76+
def identify_uplink(self) -> NIC:
77+
eligible_networks = [
78+
net for net in self.network_data.networks if net.default_routes()
79+
]
80+
if len(eligible_networks) != 1:
81+
raise ValueError(
82+
"the network_data.json should only contain a single default route."
83+
"Unable to identify uplink interface"
84+
)
85+
link = eligible_networks[0].link
86+
return self.nics.find_by_mac(link.ethernet_mac_address)
87+
88+
@cached_property
89+
def nics(self):
90+
return NICList()

0 commit comments

Comments
 (0)