from sqlmodel import select import libvirt from openec2.libvirt import LibvirtSingleton from openec2.db import DatabaseDep from openec2.db.ipam import IPAMEntry from openec2.utils.ip import ipv4_to_int, int_to_ipv4 def _libvirt_host_update(instance_id: str, mac: str, ipv4: str) -> str: return f"" def add_instance_dhcp_mapping(instance_id: str, mac: str, ipv4: str, db: DatabaseDep): """ Adds a DHCP entry for the network to give the instance a static private IPv4 address. """ entry = IPAMEntry( ipv4_addr_raw=ipv4_to_int(ipv4), instance_id=instance_id, # TODO vpc_id="default", ) db.add(entry) # Tell libvirt about this mapping conn = LibvirtSingleton.of().connection conn.networkLookupByName("default").update( libvirt.VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, libvirt.VIR_NETWORK_SECTION_IP_DHCP_HOST, 0, _libvirt_host_update(instance_id, mac, ipv4), flags=libvirt.VIR_NETWORK_UPDATE_AFFECT_LIVE, ) def remove_instance_dhcp_mapping(instance_id: str, mac: str ,ipv4: str, db: DatabaseDep): i = ipv4_to_int(ipv4) entry = db.exec(select(IPAMEntry).where(IPAMEntry.ipv4_addr_raw == i, IPAMEntry.instance_id == instance_id)).first() db.delete(entry) # Tell libvirt about this mapping conn = LibvirtSingleton.of().connection conn.networkLookupByName("default").update( libvirt.VIR_NETWORK_UPDATE_COMMAND_DELETE, libvirt.VIR_NETWORK_SECTION_IP_DHCP_HOST, 0, _libvirt_host_update(instance_id, mac, ipv4), flags=libvirt.VIR_NETWORK_UPDATE_AFFECT_LIVE, ) def is_ipv4_available(ipv4: str, db: DatabaseDep) -> bool: i = ipv4_to_int(ipv4) return db.exec(select(IPAMEntry).where(IPAMEntry.ipv4_addr_raw == i)).first() is None def get_available_ipv4(db: DatabaseDep) -> str: entries = db.exec(select(IPAMEntry)).all() # TODO: Use the VPC's subnet max_ip = max(e.ipv4_addr_raw for e in entries) if entries else ipv4_to_int("192.168.122.2") # TODO: Check if we're still inside the subnet return int_to_ipv4(max_ip + 1)