diff --git a/server/src/uds/core/util/validators.py b/server/src/uds/core/util/validators.py index 4649785ba..5a2028289 100644 --- a/server/src/uds/core/util/validators.py +++ b/server/src/uds/core/util/validators.py @@ -263,7 +263,7 @@ def validate_host_port(host_port_pair: str, field_name: typing.Optional[str] = N dj_validators.validate_ipv46_address(host) return host, validate_port(port) except Exception: - return validate_hostname(host, 255, False), validate_port(port) + return validate_hostname(host, 255, True), validate_port(port) except Exception: raise exceptions.ui.ValidationError(_('{} is not a valid host:port pair').format(host_port_pair + field_name)) from None diff --git a/server/src/uds/services/Proxmox/proxmox/client.py b/server/src/uds/services/Proxmox/proxmox/client.py index 653935e0c..cc40a1f83 100644 --- a/server/src/uds/services/Proxmox/proxmox/client.py +++ b/server/src/uds/services/Proxmox/proxmox/client.py @@ -670,25 +670,29 @@ class ProxmoxClient: def set_vm_net_mac( self, vmid: int, - mac: str, - netid: typing.Optional[str] = None, + macaddr: str, + netid: typing.Optional[str] = None, # net0, net1, ... node: typing.Optional[str] = None, ) -> None: node = node or self.get_vm_info(vmid).node - # First, read current configuration and extract network configuration - config = self.do_get(f'nodes/{node}/qemu/{vmid}/config', node=node)['data'] - if netid not in config: - # Get first network interface (netX where X is a number) - netid = next((k for k in config if k.startswith('net') and k[3:].isdigit()), None) - if not netid: - raise exceptions.ProxmoxError('No network interface found') + + net: types.NetworkConfiguration = types.NetworkConfiguration.null() + + cfg = self.get_vm_config(vmid, node) + + if netid is None: + net = cfg.networks[0] + else: + for i in cfg.networks: + if i.net == netid: + net = i + break + + # net should be the reference to the network we want to update + if net.is_null(): + raise exceptions.ProxmoxError(f'Network {netid} not found for VM {vmid}') - netdata = config[netid] - - # Update mac address, that is the first field =, - netdata = re.sub(r'^([^=]+)=([^,]+),', r'\1={},'.format(mac), netdata) - - logger.debug('Updating mac address for VM %s: %s=%s', vmid, netid, netdata) + logger.debug('Updating mac address for VM %s: %s=%s', vmid, netid, net.macaddr) self.do_post( f'nodes/{node}/qemu/{vmid}/config', diff --git a/server/src/uds/services/Proxmox/proxmox/types.py b/server/src/uds/services/Proxmox/proxmox/types.py index 3878c4c65..0346609be 100644 --- a/server/src/uds/services/Proxmox/proxmox/types.py +++ b/server/src/uds/services/Proxmox/proxmox/types.py @@ -221,17 +221,30 @@ class TaskStatus: class NetworkConfiguration: net: str type: str - mac: str + macaddr: str + + netdata: str # Original data + + def is_null(self) -> bool: + return self.net == '' + + def set_mac_address(self, macaddr: str) -> None: + self.macaddr = macaddr + # Replace mac address in netdata + self.netdata = re.sub(r'^([^=]+)=([^,]+),', r'\1={},'.format(macaddr), self.netdata) @staticmethod - def from_str(net: str, value: str) -> 'NetworkConfiguration': - v = NETWORK_RE.match(value) + def from_str(net: str, netdata: str) -> 'NetworkConfiguration': + v = NETWORK_RE.match(netdata) type = mac = '' if v: type, mac = v.group(1), v.group(2) - return NetworkConfiguration(net=net, type=type, mac=mac) + return NetworkConfiguration(net=net, type=type, macaddr=mac, netdata=netdata) + @staticmethod + def null() -> 'NetworkConfiguration': + return NetworkConfiguration(net='', type='', macaddr='', netdata='') @dataclasses.dataclass class HAInfo: diff --git a/server/src/uds/services/Proxmox/service_fixed.py b/server/src/uds/services/Proxmox/service_fixed.py index d4da105cf..b7a2d49c3 100644 --- a/server/src/uds/services/Proxmox/service_fixed.py +++ b/server/src/uds/services/Proxmox/service_fixed.py @@ -213,7 +213,7 @@ class ProxmoxServiceFixed(FixedService): # pylint: disable=too-many-public-meth def get_mac(self, vmid: str) -> str: config = self.provider().api.get_vm_config(int(vmid)) - return config.networks[0].mac.lower() + return config.networks[0].macaddr.lower() def get_ip(self, vmid: str) -> str: return self.provider().api.get_guest_ip_address(int(vmid)) diff --git a/server/src/uds/services/Proxmox/service_linked.py b/server/src/uds/services/Proxmox/service_linked.py index 9af28651c..6479bac7c 100644 --- a/server/src/uds/services/Proxmox/service_linked.py +++ b/server/src/uds/services/Proxmox/service_linked.py @@ -265,7 +265,7 @@ class ProxmoxServiceLinked(DynamicService): # If vmid is empty, we are requesting a new mac if not vmid: return self.mac_generator().get(self.get_macs_range()) - return self.provider().api.get_vm_config(int(vmid)).networks[0].mac.lower() + return self.provider().api.get_vm_config(int(vmid)).networks[0].macaddr.lower() def start(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> None: if isinstance(caller_instance, ProxmoxUserserviceLinked):