From 5e2f2bb2562de76d80885e62bab3157d8853a05b Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Tue, 4 Mar 2025 16:15:33 +0000 Subject: [PATCH] Revert "feat: ESX network configuration scripts for Undercloud" --- python/esxi-netinit/README.md | 1 - python/esxi-netinit/doc/example.json | 34 --- python/esxi-netinit/doc/multiif.json | 90 ------ python/esxi-netinit/netinit/__init__.py | 0 python/esxi-netinit/netinit/esxconfig.py | 90 ------ python/esxi-netinit/netinit/esxhost.py | 267 ------------------ python/esxi-netinit/netinit/link.py | 14 - python/esxi-netinit/netinit/main.py | 42 --- python/esxi-netinit/netinit/network.py | 19 -- python/esxi-netinit/netinit/network_data.py | 56 ---- python/esxi-netinit/netinit/nic.py | 9 - python/esxi-netinit/netinit/nic_list.py | 34 --- python/esxi-netinit/netinit/route.py | 11 - python/esxi-netinit/netinit/service.py | 7 - python/esxi-netinit/poetry.lock | 167 ----------- python/esxi-netinit/pyproject.toml | 53 ---- python/esxi-netinit/tests/__init__.py | 0 python/esxi-netinit/tests/conftest.py | 133 --------- python/esxi-netinit/tests/test_esxconfig.py | 47 --- python/esxi-netinit/tests/test_esxhost.py | 135 --------- python/esxi-netinit/tests/test_networkdata.py | 89 ------ python/esxi-netinit/tests/test_niclist.py | 38 --- 22 files changed, 1336 deletions(-) delete mode 100644 python/esxi-netinit/README.md delete mode 100644 python/esxi-netinit/doc/example.json delete mode 100644 python/esxi-netinit/doc/multiif.json delete mode 100644 python/esxi-netinit/netinit/__init__.py delete mode 100644 python/esxi-netinit/netinit/esxconfig.py delete mode 100644 python/esxi-netinit/netinit/esxhost.py delete mode 100644 python/esxi-netinit/netinit/link.py delete mode 100644 python/esxi-netinit/netinit/main.py delete mode 100644 python/esxi-netinit/netinit/network.py delete mode 100644 python/esxi-netinit/netinit/network_data.py delete mode 100644 python/esxi-netinit/netinit/nic.py delete mode 100644 python/esxi-netinit/netinit/nic_list.py delete mode 100644 python/esxi-netinit/netinit/route.py delete mode 100644 python/esxi-netinit/netinit/service.py delete mode 100644 python/esxi-netinit/poetry.lock delete mode 100644 python/esxi-netinit/pyproject.toml delete mode 100644 python/esxi-netinit/tests/__init__.py delete mode 100644 python/esxi-netinit/tests/conftest.py delete mode 100644 python/esxi-netinit/tests/test_esxconfig.py delete mode 100644 python/esxi-netinit/tests/test_esxhost.py delete mode 100644 python/esxi-netinit/tests/test_networkdata.py delete mode 100644 python/esxi-netinit/tests/test_niclist.py diff --git a/python/esxi-netinit/README.md b/python/esxi-netinit/README.md deleted file mode 100644 index f44d5b6e7..000000000 --- a/python/esxi-netinit/README.md +++ /dev/null @@ -1 +0,0 @@ -# ESX Networking setup scripts diff --git a/python/esxi-netinit/doc/example.json b/python/esxi-netinit/doc/example.json deleted file mode 100644 index d30287b46..000000000 --- a/python/esxi-netinit/doc/example.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "links": [ - { - "ethernet_mac_address": "14:23:f3:f5:21:50", - "id": "c23067a8-b2ca-4114-9fa9-32b0b9151e18", - "mtu": 1500, - "type": "vif", - "vif_id": "145cfec6-bedb-444c-9ef1-de1bfef67b2a" - } - ], - "networks": [ - { - "id": "b0fa63d0-fb0c-446f-bfd3-26c0a50730c0", - "ip_address": "10.4.50.118", - "link": "c23067a8-b2ca-4114-9fa9-32b0b9151e18", - "netmask": "255.255.255.192", - "network_id": "c57e4a02-73bb-4c6e-ab03-537ea11168e3", - "routes": [ - { - "gateway": "10.4.50.65", - "netmask": "0.0.0.0", - "network": "0.0.0.0" - } - ], - "type": "ipv4" - } - ], - "services": [ - { - "address": "10.4.204.3", - "type": "dns" - } - ] -} diff --git a/python/esxi-netinit/doc/multiif.json b/python/esxi-netinit/doc/multiif.json deleted file mode 100644 index 8ad2f8803..000000000 --- a/python/esxi-netinit/doc/multiif.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "links": [ - { - "id": "tap47bb4c37-f6", - "vif_id": "47bb4c37-f60d-474f-8ce5-c7c1d9982585", - "type": "phy", - "mtu": 1450, - "ethernet_mac_address": "14:23:f3:f5:3a:d0" - }, - { - "id": "tap1b9c25a9-39", - "vif_id": "1b9c25a9-396f-43e7-9f1c-a2dcdfd3989c", - "type": "vlan", - "mtu": 1450, - "ethernet_mac_address": "fa:16:3e:07:86:96", - "vlan_link": "tap47bb4c37-f6", - "vlan_id": 111, - "vlan_mac_address": "fa:16:3e:07:86:96" - }, - { - "id": "tape3fbe9a7-93", - "vif_id": "e3fbe9a7-933d-4e27-8ac5-858054be7772", - "type": "vlan", - "mtu": 1450, - "ethernet_mac_address": "fa:16:3e:31:50:d6", - "vlan_link": "tap47bb4c37-f6", - "vlan_id": 222, - "vlan_mac_address": "fa:16:3e:31:50:d6" - }, - { - "id": "tapd097f698-89", - "vif_id": "d097f698-8926-44e1-afe7-09fb03947f23", - "type": "vlan", - "mtu": 1450, - "ethernet_mac_address": "fa:16:3e:48:91:ef", - "vlan_link": "tap47bb4c37-f6", - "vlan_id": 444, - "vlan_mac_address": "fa:16:3e:48:91:ef" - } - ], - "networks": [ - { - "id": "network0", - "type": "ipv4", - "link": "tap47bb4c37-f6", - "ip_address": "192.168.100.170", - "netmask": "255.255.255.0", - "routes": [ - { - "network": "0.0.0.0", - "netmask": "0.0.0.0", - "gateway": "192.168.100.1" - } - ], - "network_id": "783b4239-7220-4a74-8253-415539469860", - "services": [] - }, - { - "id": "network1", - "type": "ipv4", - "link": "tap1b9c25a9-39", - "ip_address": "192.168.200.174", - "netmask": "255.255.255.0", - "routes": [], - "network_id": "9608ea7d-18d9-4298-8951-ac9dbe20db06", - "services": [] - }, - { - "id": "network2", - "type": "ipv4", - "link": "tape3fbe9a7-93", - "ip_address": "192.168.0.24", - "netmask": "255.255.255.0", - "routes": [], - "network_id": "ecff22e4-b364-4575-9d2b-dffc83c8d5b7", - "services": [] - }, - { - "id": "network3", - "type": "ipv4", - "link": "tapd097f698-89", - "ip_address": "192.168.10.133", - "netmask": "255.255.255.0", - "routes": [], - "network_id": "c47d5a38-c646-42e8-b6ca-3eecc977d645", - "services": [] - } - ], - "services": [] -} diff --git a/python/esxi-netinit/netinit/__init__.py b/python/esxi-netinit/netinit/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/python/esxi-netinit/netinit/esxconfig.py b/python/esxi-netinit/netinit/esxconfig.py deleted file mode 100644 index b5b159e3d..000000000 --- a/python/esxi-netinit/netinit/esxconfig.py +++ /dev/null @@ -1,90 +0,0 @@ -from functools import cached_property - -from .esxhost import ESXHost -from .network_data import NetworkData -from .nic import NIC -from .nic_list import NICList - - -class ESXConfig: - def __init__(self, network_data: NetworkData, dry_run=False) -> None: - self.network_data = network_data - self.dry_run = dry_run - self.host = ESXHost(dry_run) - - def add_default_mgmt_interface( - self, portgroup_name, switch_name, interface_name="vmk0" - ): - self.host.portgroup_add(portgroup_name=portgroup_name, switch_name=switch_name) - self.host.add_ip_interface(name=interface_name, portgroup_name=portgroup_name) - - def clean_default_network_setup(self, portgroup_name, switch_name): - """Removes default networking setup left by the installer.""" - self.host.delete_vmknic(portgroup_name=portgroup_name) - self.host.portgroup_remove( - switch_name=switch_name, portgroup_name=portgroup_name - ) - self.host.destroy_vswitch(name=switch_name) - - def configure_default_route(self): - """Configures default route. - - If multiple default routes are present, only first one is used. - """ - route = self.network_data.default_route() - self.host.configure_default_route(route.gateway) - - def configure_portgroups(self, switch_name="vSwitch0"): - portgroups = [] - for link in self.network_data.links: - if link.type == "vlan": - vid = link.vlan_id - pg_name = f"internal_net_vid_{vid}" - self.host.portgroup_add(portgroup_name=pg_name, switch_name=switch_name) - self.host.portgroup_set_vlan(portgroup_name=pg_name, vlan_id=vid) - portgroups.append(pg_name) - return portgroups - - def configure_management_interface(self): - mgmt_network = next( - net for net in self.network_data.networks if net.default_routes() - ) - return self.host.change_ip( - "vmk0", mgmt_network.ip_address, mgmt_network.netmask - ) - - def configure_vswitch(self, uplink: NIC, switch_name: str, mtu: int): - """Sets up vSwitch.""" - self.host.create_vswitch(switch_name) - self.host.uplink_add(nic=uplink.name, switch_name=switch_name) - self.host.vswitch_failover_uplinks( - active_uplinks=[uplink.name], name=switch_name - ) - self.host.vswitch_security(name=switch_name) - self.host.vswitch_settings(mtu=mtu, name=switch_name) - - def configure_requested_dns(self): - """Configures DNS servers that were provided in network_data.json.""" - dns_servers = [ - srv.address for srv in self.network_data.services if srv.type == "dns" - ] - if not dns_servers: - return - - return self.host.configure_dns(servers=dns_servers) - - def identify_uplink(self) -> NIC: - eligible_networks = [ - net for net in self.network_data.networks if net.default_routes() - ] - if len(eligible_networks) != 1: - raise ValueError( - "the network_data.json should only contain a single default route." - "Unable to identify uplink interface" - ) - link = eligible_networks[0].link - return self.nics.find_by_mac(link.ethernet_mac_address) - - @cached_property - def nics(self): - return NICList() diff --git a/python/esxi-netinit/netinit/esxhost.py b/python/esxi-netinit/netinit/esxhost.py deleted file mode 100644 index 9056164be..000000000 --- a/python/esxi-netinit/netinit/esxhost.py +++ /dev/null @@ -1,267 +0,0 @@ -import subprocess - - -class ESXHost: - """Low level commands for configuring various aspects of ESXi hypervisor.""" - - def __init__(self, dry_run=False) -> None: - self.dry_run = dry_run - - def __execute(self, cmd: list): - if self.dry_run: - print(f"Would execute: {' '.join(cmd)}") - return cmd - else: - subprocess.run(cmd, check=True) # noqa: S603 - - def add_ip_interface(self, name, portgroup_name): - """Adds IP interface.""" - return self.__execute( - [ - "/bin/esxcli", - "network", - "ip", - "interface", - "add", - "--interface-name", - name, - "--portgroup-name", - portgroup_name, - ] - ) - - def configure_default_route(self, gateway): - cmd = [ - "/bin/esxcli", - "network", - "ip", - "route", - "ipv4", - "add", - "-g", - gateway, - "-n", - "default", - ] - return self.__execute(cmd) - - def change_ip(self, interface, ip, netmask): - """Configures IP address on logical interface.""" - cmd = [ - "/bin/esxcli", - "network", - "ip", - "interface", - "ipv4", - "set", - "-i", - interface, - "-I", - ip, - "-N", - netmask, - "-t", - "static", - ] - return self.__execute(cmd) - - def configure_dns(self, servers=None, search=None): - """Sets up arbitrary DNS servers.""" - if not servers: - servers = [] - if not search: - search = [] - - for server in servers: - self.__execute( - [ - "/bin/esxcli", - "network", - "ip", - "dns", - "server", - "add", - "--server", - server, - ] - ) - - for domain in search: - self.__execute( - [ - "/bin/esxcli", - "network", - "ip", - "dns", - "search", - "add", - "--domain", - domain, - ] - ) - - def create_vswitch(self, name="vSwitch0", ports=256): - """Creates vSwitch.""" - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "add", - "--ports", - str(ports), - "--vswitch-name", - str(name), - ] - - return self.__execute(cmd) - - def delete_vmknic(self, portgroup_name): - """Deletes a vmknic from a portgroup.""" - return self.__execute(["/bin/esxcfg-vmknic", "-d", portgroup_name]) - - def destroy_vswitch(self, name): - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "remove", - "--vswitch-name", - name, - ] - - return self.__execute(cmd) - - def portgroup_add(self, portgroup_name, switch_name="vswitch0"): - """Adds Portgroup to a vSwitch.""" - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "portgroup", - "add", - "--portgroup-name", - str(portgroup_name), - "--vswitch-name", - str(switch_name), - ] - return self.__execute(cmd) - - # - def portgroup_remove(self, portgroup_name, switch_name): - """Removes Portgroup from a vSwitch.""" - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "portgroup", - "remove", - "--portgroup-name", - str(portgroup_name), - "--vswitch-name", - str(switch_name), - ] - return self.__execute(cmd) - - def portgroup_set_vlan(self, portgroup_name, vlan_id): - """Configures VLANid to be used on a portgroup.""" - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "portgroup", - "set", - "--portgroup-name", - str(portgroup_name), - "--vlan-id", - str(vlan_id), - ] - return self.__execute(cmd) - - def uplink_add(self, nic, switch_name="vSwitch0"): - """Adds uplink to a vSwitch.""" - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "uplink", - "add", - "--uplink-name", - str(nic), - "--vswitch-name", - str(switch_name), - ] - return self.__execute(cmd) - - def vswitch_settings(self, mtu=9000, cdp="listen", name="vSwitch0"): - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "set", - "--mtu", - str(mtu), - "--cdp-status", - cdp, - "--vswitch-name", - str(name), - ] - return self.__execute(cmd) - - def vswitch_failover_uplinks( - self, active_uplinks=None, standby_uplinks=None, name="vSwitch0" - ): - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "policy", - "failover", - "set", - ] - - if active_uplinks: - cmd.extend(["--active-uplinks", ",".join(active_uplinks)]) - if standby_uplinks: - cmd.extend(["--standby-uplinks", ",".join(standby_uplinks)]) - - cmd.extend( - [ - "--vswitch-name", - str(name), - ] - ) - return self.__execute(cmd) - - def vswitch_security( - self, - allow_forged_transmits="no", - allow_mac_change="no", - allow_promiscuous="no", - name="vSwitch0", - ): - cmd = [ - "/bin/esxcli", - "network", - "vswitch", - "standard", - "policy", - "security", - "set", - "--allow-forged-transmits", - allow_forged_transmits, - "--allow-mac-change", - allow_mac_change, - "--allow-promiscuous", - allow_promiscuous, - "--vswitch-name", - str(name), - ] - return self.__execute(cmd) diff --git a/python/esxi-netinit/netinit/link.py b/python/esxi-netinit/netinit/link.py deleted file mode 100644 index 3f59d5eaa..000000000 --- a/python/esxi-netinit/netinit/link.py +++ /dev/null @@ -1,14 +0,0 @@ -from dataclasses import dataclass -from dataclasses import field - - -@dataclass -class Link: - ethernet_mac_address: str - id: str - mtu: int - type: str - vif_id: str - vlan_id: "int | None" = field(default=None) - vlan_mac_address: "str | None" = field(default=None) - vlan_link: "Link | None" = field(default=None) diff --git a/python/esxi-netinit/netinit/main.py b/python/esxi-netinit/netinit/main.py deleted file mode 100644 index af91aeb04..000000000 --- a/python/esxi-netinit/netinit/main.py +++ /dev/null @@ -1,42 +0,0 @@ -import argparse -import sys - -from netinit.esxconfig import ESXConfig -from netinit.network_data import NetworkData - -OLD_MGMT_PG = "Management Network" -OLD_VSWITCH = "vSwitch0" -NEW_MGMT_PG = "mgmt" -NEW_VSWITCH = "vSwitch22" - - -def main(json_file, dry_run): - network_data = NetworkData.from_json_file(json_file) - esx = ESXConfig(network_data, dry_run=dry_run) - esx.clean_default_network_setup(OLD_MGMT_PG, OLD_VSWITCH) - esx.configure_vswitch( - uplink=esx.identify_uplink(), switch_name=NEW_VSWITCH, mtu=9000 - ) - - esx.configure_portgroups() - esx.add_default_mgmt_interface(NEW_MGMT_PG, NEW_VSWITCH) - esx.configure_management_interface() - esx.configure_default_route() - esx.configure_requested_dns() - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Network configuration script") - parser.add_argument("json_file", help="Path to the JSON configuration file") - parser.add_argument( - "--dry-run", - action="store_true", - help="Perform a dry run without making any changes", - ) - args = parser.parse_args() - - try: - main(args.json_file, args.dry_run) - except Exception as e: - print(f"Error configuring network: {str(e)}") - sys.exit(1) diff --git a/python/esxi-netinit/netinit/network.py b/python/esxi-netinit/netinit/network.py deleted file mode 100644 index 27c008ad2..000000000 --- a/python/esxi-netinit/netinit/network.py +++ /dev/null @@ -1,19 +0,0 @@ -from dataclasses import dataclass -from dataclasses import field - -from .link import Link - - -@dataclass -class Network: - id: str - ip_address: str - netmask: str - network_id: str - link: Link - type: str - routes: list - services: "list | None" = field(default=None) - - def default_routes(self): - return [route for route in self.routes if route.is_default()] diff --git a/python/esxi-netinit/netinit/network_data.py b/python/esxi-netinit/netinit/network_data.py deleted file mode 100644 index 41a179167..000000000 --- a/python/esxi-netinit/netinit/network_data.py +++ /dev/null @@ -1,56 +0,0 @@ -import json - -from .link import Link -from .network import Network -from .route import Route -from .service import Service - - -class NetworkData: - """Represents network_data.json.""" - - def __init__(self, data: dict) -> None: - self.data = data - self.links = self._init_links(data.get("links", [])) - self.networks = [] - - for net_data in data.get("networks", []): - net_data = net_data.copy() - routes_data = net_data.pop("routes", []) - routes = [Route(**route) for route in routes_data] - link_id = net_data.pop("link", []) - try: - relevant_link = next(link for link in self.links if link.id == link_id) - except StopIteration: - raise ValueError( - f"Link {link_id} is not defined in links section" - ) from None - self.networks.append(Network(**net_data, routes=routes, link=relevant_link)) - - self.services = [Service(**service) for service in data.get("services", [])] - - def _init_links(self, links_data): - links_data = links_data.copy() - links = [] - for link in links_data: - if "vlan_link" in link: - phy_link = next( - plink for plink in links if plink.id == link["vlan_link"] - ) - link["vlan_link"] = phy_link - - links.append(Link(**link)) - return links - - def default_route(self) -> Route: - return next( - network.default_routes()[0] - for network in self.networks - if network.default_routes() - ) - - @staticmethod - def from_json_file(path): - with open(path) as f: - data = json.load(f) - return NetworkData(data) diff --git a/python/esxi-netinit/netinit/nic.py b/python/esxi-netinit/netinit/nic.py deleted file mode 100644 index 533e7d5ae..000000000 --- a/python/esxi-netinit/netinit/nic.py +++ /dev/null @@ -1,9 +0,0 @@ -from dataclasses import dataclass - - -@dataclass -class NIC: - name: str - status: str - link: str - mac: str diff --git a/python/esxi-netinit/netinit/nic_list.py b/python/esxi-netinit/netinit/nic_list.py deleted file mode 100644 index 561b2aea0..000000000 --- a/python/esxi-netinit/netinit/nic_list.py +++ /dev/null @@ -1,34 +0,0 @@ -import subprocess - -from .nic import NIC - - -class NICList(list): - def __init__(self, data=None) -> None: - nic_data = data or self._esxi_nics() - return super().__init__(NICList.parse(nic_data)) - - @staticmethod - def parse(data): - output = [] - for line in data.split("\n"): - if line.startswith("vmnic"): - parts = line.split() - nic = NIC(name=parts[0], status=parts[3], link=parts[4], mac=parts[7]) - output.append(nic) - return output - - def _esxi_nics(self) -> str: - return subprocess.run( # noqa: S603 - [ - "/bin/esxcli", - "network", - "nic", - "list", - ], - check=True, - capture_output=True, - ).stdout.decode() - - def find_by_mac(self, mac) -> NIC: - return next(nic for nic in self if nic.mac == mac) diff --git a/python/esxi-netinit/netinit/route.py b/python/esxi-netinit/netinit/route.py deleted file mode 100644 index 9346e0662..000000000 --- a/python/esxi-netinit/netinit/route.py +++ /dev/null @@ -1,11 +0,0 @@ -from dataclasses import dataclass - - -@dataclass -class Route: - gateway: str - netmask: str - network: str - - def is_default(self): - return self.network == "0.0.0.0" and self.netmask == "0.0.0.0" diff --git a/python/esxi-netinit/netinit/service.py b/python/esxi-netinit/netinit/service.py deleted file mode 100644 index b5770ec43..000000000 --- a/python/esxi-netinit/netinit/service.py +++ /dev/null @@ -1,7 +0,0 @@ -from dataclasses import dataclass - - -@dataclass -class Service: - address: str - type: str diff --git a/python/esxi-netinit/poetry.lock b/python/esxi-netinit/poetry.lock deleted file mode 100644 index cc3774191..000000000 --- a/python/esxi-netinit/poetry.lock +++ /dev/null @@ -1,167 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "packaging" -version = "24.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, -] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pytest" -version = "8.3.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, - {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=1.5,<2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "pytest-subprocess" -version = "1.5.3" -description = "A plugin to fake subprocess for pytest" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest_subprocess-1.5.3-py3-none-any.whl", hash = "sha256:b62580f5a84335fb9f2ec65d49e56a3c93f4722c148fe1771a002835d310a75b"}, - {file = "pytest_subprocess-1.5.3.tar.gz", hash = "sha256:c00b1140fb0211b3153e09500d770db10770baccbe6e05ee9c140036d1d811d5"}, -] - -[package.dependencies] -pytest = ">=4.0.0" - -[package.extras] -dev = ["changelogd", "nox"] -docs = ["changelogd", "furo", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-napoleon"] -test = ["Pygments (>=2.0)", "anyio", "docutils (>=0.12)", "pytest (>=4.0)", "pytest-asyncio (>=0.15.1)", "pytest-rerunfailures", "pytest-timeout"] - -[[package]] -name = "tomli" -version = "2.2.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.8" -content-hash = "639fa5d98334b296e832b33dfb58cfff03ccc40fe6d064b8b2fe5df027ba0d7b" diff --git a/python/esxi-netinit/pyproject.toml b/python/esxi-netinit/pyproject.toml deleted file mode 100644 index e661764d5..000000000 --- a/python/esxi-netinit/pyproject.toml +++ /dev/null @@ -1,53 +0,0 @@ -[tool.poetry] -name = "esxi-netinit" -version = "0.1.0" -description = "Script to initialize networking on ESXi hosts with usage of Openstack network_data.json" -authors = ["Marek Skrobacki "] -license = "MIT" -readme = "README.md" -packages = [{include = "netinit"}] - -[tool.poetry.dependencies] -python = "^3.8" - -[tool.poetry.group.dev.dependencies] -pytest = "^8.3.4" -pytest-subprocess = "^1.5.3" -pytest-mock = "^3.14.0" - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" - -[tool.pytest.ini_options] -minversion = "6.0" -testpaths = [ - "tests", -] -filterwarnings = [] - -[tool.ruff] -# use our default and override anything we need specifically -extend = "../pyproject.toml" -target-version = "py310" - -[tool.ruff.lint.per-file-ignores] -"tests/**/*.py" = [ - "S101", # allow 'assert' for pytest - "S105", # allow hardcoded passwords for testing - "S104", # false positive on binding to all ifaces -] -"tests/test_esxconfig.py" = [ -] -"tests/test_esxhost.py" = [ - "E501" # esxcli outputs with long lines -] -"tests/test_niclist.py" = [ - "E501" # esxcli outputs with long lines -] -"netinit/route.py" = [ - "S104", # false positive on binding to all ifaces -] - -[tool.poetry.scripts] -netinit = "netinit.main:main" diff --git a/python/esxi-netinit/tests/__init__.py b/python/esxi-netinit/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/python/esxi-netinit/tests/conftest.py b/python/esxi-netinit/tests/conftest.py deleted file mode 100644 index b621d581a..000000000 --- a/python/esxi-netinit/tests/conftest.py +++ /dev/null @@ -1,133 +0,0 @@ -import pytest - - -@pytest.fixture -def network_data_single(): - return { - "links": [ - { - "ethernet_mac_address": "00:11:22:33:44:55", - "id": "eth0", - "mtu": 1500, - "type": "vif", - "vif_id": "vif-12345", - } - ], - "networks": [ - { - "id": "net0", - "ip_address": "192.168.1.10", - "netmask": "255.255.255.0", - "network_id": "public", - "link": "eth0", - "type": "ipv4", - "routes": [ - { - "gateway": "192.168.1.1", - "netmask": "255.255.255.0", - "network": "192.168.2.0", - }, - { - "gateway": "192.168.1.1", - "netmask": "0.0.0.0", - "network": "0.0.0.0", - }, - ], - } - ], - "services": [{"address": "8.8.4.4", "type": "dns"}], - } - - -@pytest.fixture -def network_data_multi(): - return { - "links": [ - { - "id": "tap47bb4c37-f6", - "vif_id": "47bb4c37-f60d-474f-8ce5-c7c1d9982585", - "type": "phy", - "mtu": 1450, - "ethernet_mac_address": "14:23:f3:f5:3a:d0", - }, - { - "id": "tap1b9c25a9-39", - "vif_id": "1b9c25a9-396f-43e7-9f1c-a2dcdfd3989c", - "type": "vlan", - "mtu": 1450, - "ethernet_mac_address": "fa:16:3e:07:86:96", - "vlan_link": "tap47bb4c37-f6", - "vlan_id": 111, - "vlan_mac_address": "fa:16:3e:07:86:96", - }, - { - "id": "tape3fbe9a7-93", - "vif_id": "e3fbe9a7-933d-4e27-8ac5-858054be7772", - "type": "vlan", - "mtu": 1450, - "ethernet_mac_address": "fa:16:3e:31:50:d6", - "vlan_link": "tap47bb4c37-f6", - "vlan_id": 222, - "vlan_mac_address": "fa:16:3e:31:50:d6", - }, - { - "id": "tapd097f698-89", - "vif_id": "d097f698-8926-44e1-afe7-09fb03947f23", - "type": "vlan", - "mtu": 1450, - "ethernet_mac_address": "fa:16:3e:48:91:ef", - "vlan_link": "tap47bb4c37-f6", - "vlan_id": 444, - "vlan_mac_address": "fa:16:3e:48:91:ef", - }, - ], - "networks": [ - { - "id": "network0", - "type": "ipv4", - "link": "tap47bb4c37-f6", - "ip_address": "192.168.100.170", - "netmask": "255.255.255.0", - "routes": [ - { - "network": "0.0.0.0", - "netmask": "0.0.0.0", - "gateway": "192.168.100.1", - } - ], - "network_id": "783b4239-7220-4a74-8253-415539469860", - "services": [], - }, - { - "id": "network1", - "type": "ipv4", - "link": "tap1b9c25a9-39", - "ip_address": "192.168.200.174", - "netmask": "255.255.255.0", - "routes": [], - "network_id": "9608ea7d-18d9-4298-8951-ac9dbe20db06", - "services": [], - }, - { - "id": "network2", - "type": "ipv4", - "link": "tape3fbe9a7-93", - "ip_address": "192.168.0.24", - "netmask": "255.255.255.0", - "routes": [], - "network_id": "ecff22e4-b364-4575-9d2b-dffc83c8d5b7", - "services": [], - }, - { - "id": "network3", - "type": "ipv4", - "link": "tapd097f698-89", - "ip_address": "192.168.10.133", - "netmask": "255.255.255.0", - "routes": [], - "network_id": "c47d5a38-c646-42e8-b6ca-3eecc977d645", - "services": [], - }, - ], - "services": [], - } diff --git a/python/esxi-netinit/tests/test_esxconfig.py b/python/esxi-netinit/tests/test_esxconfig.py deleted file mode 100644 index 801a31319..000000000 --- a/python/esxi-netinit/tests/test_esxconfig.py +++ /dev/null @@ -1,47 +0,0 @@ -import pytest - -from netinit.esxconfig import ESXConfig -from netinit.esxhost import ESXHost -from netinit.network_data import NetworkData - - -@pytest.fixture -def host_mock(mocker): - return mocker.Mock(spec=ESXHost) - - -def test_configure_requested_dns(host_mock, network_data_single): - ndata = NetworkData(network_data_single) - ec = ESXConfig(ndata, dry_run=False) - ec.host = host_mock - ec.configure_requested_dns() - print(host_mock.configure_dns.call_args_list) - host_mock.configure_dns.assert_called_once_with(servers=["8.8.4.4"]) - - -def test_configure_default_route(network_data_single, host_mock): - ndata = NetworkData(network_data_single) - ec = ESXConfig(ndata, dry_run=False) - ec.host = host_mock - ec.configure_default_route() - host_mock.configure_default_route.assert_called_once_with("192.168.1.1") - - -def test_configure_management_interface(network_data_single, host_mock): - ndata = NetworkData(network_data_single) - ec = ESXConfig(ndata, dry_run=False) - ec.host = host_mock - ec.configure_management_interface() - host_mock.change_ip.assert_called_once_with("vmk0", "192.168.1.10", "255.255.255.0") - - -def test_configure_portgroups(network_data_multi, host_mock): - ndata = NetworkData(network_data_multi) - ec = ESXConfig(ndata, dry_run=False) - ec.host = host_mock - ec.configure_portgroups() - assert host_mock.portgroup_add.call_count == 3 - assert host_mock.portgroup_set_vlan.call_count == 3 - host_mock.portgroup_set_vlan.assert_called_with( - portgroup_name="internal_net_vid_444", vlan_id=444 - ) diff --git a/python/esxi-netinit/tests/test_esxhost.py b/python/esxi-netinit/tests/test_esxhost.py deleted file mode 100644 index 7b3b084ab..000000000 --- a/python/esxi-netinit/tests/test_esxhost.py +++ /dev/null @@ -1,135 +0,0 @@ -import pytest - -from netinit.esxhost import ESXHost - - -@pytest.fixture -def esx_host(fp): - fp.register(["/bin/esxcli", fp.any()]) - return ESXHost() - - -def test_portgroup_add(fp, esx_host): - esx_host.portgroup_add("mypg") - assert ( - fp.call_count( - "/bin/esxcli network vswitch standard portgroup add --portgroup-name mypg --vswitch-name vswitch0" - ) - == 1 - ) - - -def test_portgroup_set_vlan(fp, esx_host): - esx_host.portgroup_set_vlan("mypg", 1984) - assert ( - fp.call_count( - "/bin/esxcli network vswitch standard portgroup set --portgroup-name mypg --vlan-id 1984" - ) - == 1 - ) - - -def test_create_vswitch(fp, esx_host): - esx_host.create_vswitch(name="vSwitch8", ports=512) - assert ( - fp.call_count( - "/bin/esxcli network vswitch standard add --ports 512 --vswitch-name vSwitch8" - ) - == 1 - ) - - -def test_destroy_vswitch(fp, esx_host): - esx_host.destroy_vswitch(name="vSwitch8") - assert ( - fp.call_count( - "/bin/esxcli network vswitch standard remove --vswitch-name vSwitch8" - ) - == 1 - ) - - -def test_portgroup_remove(fp, esx_host): - esx_host.portgroup_remove(switch_name="vSwitch20", portgroup_name="Management") - assert ( - fp.call_count( - "/bin/esxcli network vswitch standard portgroup remove --portgroup-name Management --vswitch-name vSwitch20" - ) - == 1 - ) - - -def test_uplink_add(fp, esx_host): - esx_host.uplink_add(switch_name="vSwitch8", nic="vmnic4") - assert ( - fp.call_count( - "/bin/esxcli network vswitch standard uplink add --uplink-name vmnic4 --vswitch-name vSwitch8" - ) - == 1 - ) - - -def test_vswitch_settings(fp, esx_host): - esx_host.vswitch_settings(mtu=9000, cdp="listen", name="vSwitch8") - assert ( - fp.call_count( - "/bin/esxcli network vswitch standard set --mtu 9000 --cdp-status listen --vswitch-name vSwitch8" - ) - == 1 - ) - - -def test_vswitch_failover_uplinks_active(fp, esx_host): - esx_host.vswitch_failover_uplinks(active_uplinks=["vmnic4", "vmnic10"]) - assert fp.call_count( - "/bin/esxcli network vswitch standard policy failover set --active-uplinks vmnic4,vmnic10 --vswitch-name vSwitch0" - ) - - -def test_vswitch_failover_uplinks_standby(fp, esx_host): - esx_host.vswitch_failover_uplinks(standby_uplinks=["vmnic3", "vmnic7"]) - assert fp.call_count( - "/bin/esxcli network vswitch standard policy failover set --standby-uplinks vmnic3,vmnic7 --vswitch-name vSwitch0" - ) - - -def test_vswitch_security(fp, esx_host): - esx_host.vswitch_security( - allow_forged_transmits="no", - allow_mac_change="no", - allow_promiscuous="yes", - name="vSwitch7", - ) - assert ( - fp.call_count( - "/bin/esxcli network vswitch standard policy security set --allow-forged-transmits no --allow-mac-change no --allow-promiscuous yes --vswitch-name vSwitch7" - ) - == 1 - ) - - -def test_configure_dns(fp, esx_host): - fp.register(["/bin/esxcli", fp.any()]) - fp.keep_last_process(True) - esx_host.configure_dns(servers=["8.8.8.8", "4.4.4.4"], search=["example.com"]) - assert fp.call_count("/bin/esxcli network ip dns server add --server 8.8.8.8") == 1 - assert fp.call_count("/bin/esxcli network ip dns server add --server 4.4.4.4") == 1 - assert ( - fp.call_count("/bin/esxcli network ip dns search add --domain example.com") == 1 - ) - - -def test_delete_vmknic(fp, esx_host): - fp.register(["/bin/esxcfg-vmknic", fp.any()]) - esx_host.delete_vmknic(portgroup_name="ManagementPG") - assert fp.call_count("/bin/esxcfg-vmknic -d ManagementPG") == 1 - - -def test_add_ip_interface(fp, esx_host): - esx_host.add_ip_interface(name="vmk1", portgroup_name="VMNet-Mgmt") - assert ( - fp.call_count( - "/bin/esxcli network ip interface add --interface-name vmk1 --portgroup-name VMNet-Mgmt" - ) - == 1 - ) diff --git a/python/esxi-netinit/tests/test_networkdata.py b/python/esxi-netinit/tests/test_networkdata.py deleted file mode 100644 index 5ca8a8cb2..000000000 --- a/python/esxi-netinit/tests/test_networkdata.py +++ /dev/null @@ -1,89 +0,0 @@ -import json -from dataclasses import is_dataclass - -from netinit.link import Link -from netinit.network_data import NetworkData -from netinit.route import Route - - -def test_links_parsing(network_data_single): - network_data = NetworkData(network_data_single) - assert len(network_data.links) == 1 - - link = network_data.links[0] - assert link.ethernet_mac_address == "00:11:22:33:44:55" - assert link.id == "eth0" - assert link.mtu == 1500 - assert link.type == "vif" - assert link.vif_id == "vif-12345" - - -def test_networks_parsing(network_data_single): - network_data = NetworkData(network_data_single) - assert len(network_data.networks) == 1 - - network = network_data.networks[0] - assert network.id == "net0" - assert network.ip_address == "192.168.1.10" - assert network.netmask == "255.255.255.0" - assert network.network_id == "public" - assert network.link == Link( - ethernet_mac_address="00:11:22:33:44:55", - id="eth0", - mtu=1500, - type="vif", - vif_id="vif-12345", - ) - - # Test routes parsing - assert len(network.routes) == 2 - assert all(is_dataclass(route) for route in network.routes) - - # Test route values - assert network.routes[0].gateway == "192.168.1.1" - assert network.routes[1].network == "0.0.0.0" - - -def test_services_parsing(network_data_single): - network_data = NetworkData(network_data_single) - assert len(network_data.services) == 1 - - service = network_data.services[0] - assert is_dataclass(service) - assert service.address == "8.8.4.4" - assert service.type == "dns" - - -def test_route_default_check(): - default_route = Route(gateway="10.0.0.1", netmask="0.0.0.0", network="0.0.0.0") - non_default_route = Route( - gateway="192.168.1.1", netmask="255.255.255.0", network="192.168.1.0" - ) - - assert default_route.is_default() is True - assert non_default_route.is_default() is False - - -def test_from_json_file(tmp_path, network_data_single): - # Create temporary JSON file - file_path = tmp_path / "test.json" - with open(file_path, "w") as f: - json.dump(network_data_single, f) - - # Test loading from file - network_data = NetworkData.from_json_file(file_path) - - # Verify basic structure - assert len(network_data.links) == 1 - assert len(network_data.networks) == 1 - assert len(network_data.services) == 1 - - # Spot check one value - assert network_data.networks[0].routes[1].is_default() is True - - -def test_empty_data(): - empty_data = NetworkData({}) - assert len(empty_data.links) == 0 - assert len(empty_data.networks) == 0 - assert len(empty_data.services) == 0 diff --git a/python/esxi-netinit/tests/test_niclist.py b/python/esxi-netinit/tests/test_niclist.py deleted file mode 100644 index 570bf8b68..000000000 --- a/python/esxi-netinit/tests/test_niclist.py +++ /dev/null @@ -1,38 +0,0 @@ -import pytest - -from netinit.nic_list import NICList - - -@pytest.fixture -def sample_niclist_data(): - return """Name PCI Device Driver Admin Status Link Status Speed Duplex MAC Address MTU Description ------- ------------ ------- ------------ ----------- ----- ------ ----------------- ---- ----------- -vmnic0 0000:c3:00.0 ntg3 Up Down 0 Half c4:cb:e1:bf:79:b6 1500 Broadcom Corporation NetXtreme BCM5720 Gigabit Ethernet -vmnic1 0000:c3:00.1 ntg3 Up Down 0 Half c4:cb:e1:bf:79:b7 1500 Broadcom Corporation NetXtreme BCM5720 Gigabit Ethernet -vmnic2 0000:c5:00.0 bnxtnet Up Up 25000 Full d4:04:e6:50:3e:9c 1500 Broadcom NetXtreme E-Series Dual-port 25Gb SFP28 Ethernet OCP 3.0 Adapter -vmnic3 0000:c5:00.1 bnxtnet Up Up 25000 Full d4:04:e6:50:3e:9d 1500 Broadcom NetXtreme E-Series Dual-port 25Gb SFP28 Ethernet OCP 3.0 Adapter -vmnic4 0000:c4:00.0 bnxtnet Up Up 25000 Full 14:23:f3:f5:21:50 1500 Broadcom BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller -vmnic5 0000:c4:00.1 bnxtnet Up Up 25000 Full 14:23:f3:f5:21:51 1500 Broadcom BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller""" - - -def test_parse_niclist(sample_niclist_data): - nics = NICList.parse(sample_niclist_data) - - assert len(nics) == 6 - assert nics[0].name == "vmnic0" - assert nics[0].mac == "c4:cb:e1:bf:79:b6" - assert nics[0].status == "Up" - assert nics[0].link == "Down" - assert nics[2].name == "vmnic2" - assert nics[2].mac == "d4:04:e6:50:3e:9c" - assert nics[2].status == "Up" - assert nics[2].link == "Up" - - -def test_find_by_mac(sample_niclist_data): - nics = NICList(sample_niclist_data) - - found = nics.find_by_mac("d4:04:e6:50:3e:9c") - - assert found.name == "vmnic2" - assert found.mac == "d4:04:e6:50:3e:9c"