"""Seed nested Engine subcollections so entity `link` hrefs are non-empty. Rows go into `ov_api_objects` (with parent_collection/parent_id) and into `ov_permissions` / `ov_tag_assignments` where specialized tables exist. """ from __future__ import annotations import json from typing import Any from uuid import UUID from asyncpg import Connection from app.ovirt.ids import stable_id def _obj_row( *, parent_collection: str, parent_id: UUID, collection: str, name: str, data: dict[str, Any] | None = None, status: str = "ok", ) -> tuple[Any, ...]: payload = {"name": name, **(data or {})} return ( stable_id("nested", parent_collection, str(parent_id), collection, name), collection, name, status, parent_collection, parent_id, json.dumps(payload), ) async def _insert_objs(conn: Connection, rows: list[tuple[Any, ...]]) -> None: if not rows: return await conn.executemany( """INSERT INTO ov_api_objects( id, collection, name, status, parent_collection, parent_id, data ) VALUES($1,$2,$3,$4,$5,$6::uuid,$7::jsonb) ON CONFLICT (id) DO NOTHING""", rows, ) async def seed_nested_for_inventory( conn: Connection, *, admin_user_id: UUID, role_user_id: UUID, datacenter_ids: list[UUID], cluster_ids: list[UUID], host_ids: list[UUID], network_ids: list[UUID], storage_domain_ids: list[UUID], template_ids: list[UUID], vm_ids: list[UUID], disk_ids: list[UUID], tag_ids: list[UUID] | None = None, user_ids: list[UUID] | None = None, group_ids: list[UUID] | None = None, ) -> None: """Populate nested surface for the given inventory sample.""" obj_rows: list[tuple[Any, ...]] = [] perm_rows: list[tuple[Any, ...]] = [] tag_rows: list[tuple[Any, ...]] = [] if user_ids is None: user_ids = [] if group_ids is None: group_ids = [] def perm(object_type: str, object_id: UUID, key: str) -> None: perm_rows.append( ( stable_id("perm", object_type, key), role_user_id, admin_user_id, object_type, object_id, ) ) for dc_id in datacenter_ids: perm("data_center", dc_id, f"dc-{dc_id}") obj_rows.append( _obj_row( parent_collection="datacenters", parent_id=dc_id, collection="qoss", name="default-qos", data={"type": "storage"}, ) ) obj_rows.append( _obj_row( parent_collection="datacenters", parent_id=dc_id, collection="iscsibonds", name="iscsi-bond-1", data={"description": "iSCSI bond"}, ) ) for cluster_id in cluster_ids: perm("cluster", cluster_id, f"cluster-{cluster_id}") obj_rows.append( _obj_row( parent_collection="clusters", parent_id=cluster_id, collection="cpuprofiles", name="Default", data={"description": "Default CPU profile"}, ) ) obj_rows.append( _obj_row( parent_collection="clusters", parent_id=cluster_id, collection="enabledfeatures", name="gluster", data={"description": "Gluster feature"}, ) ) obj_rows.append( _obj_row( parent_collection="clusters", parent_id=cluster_id, collection="glustervolumes", name="gv0", data={ "volume_type": "distribute", "replica_count": 1, "status": "up", }, ) ) for host_id in host_ids: perm("host", host_id, f"host-{host_id}") obj_rows.append( _obj_row( parent_collection="hosts", parent_id=host_id, collection="nics", name="eth0", data={"mac": {"address": "00:1a:4a:00:00:01"}, "boot_protocol": "dhcp"}, ) ) obj_rows.append( _obj_row( parent_collection="hosts", parent_id=host_id, collection="nics", name="eth1", data={"mac": {"address": "00:1a:4a:00:00:02"}, "boot_protocol": "none"}, ) ) obj_rows.append( _obj_row( parent_collection="hosts", parent_id=host_id, collection="statistics", name="memory.used", data={"unit": "bytes", "values": {"value": [{"datum": 8 * 1024**3}]}}, ) ) obj_rows.append( _obj_row( parent_collection="hosts", parent_id=host_id, collection="statistics", name="cpu.current.user", data={"unit": "percent", "values": {"value": [{"datum": 12.5}]}}, ) ) obj_rows.append( _obj_row( parent_collection="hosts", parent_id=host_id, collection="devices", name="pci-0000:00:1f.2", data={"capability": "storage", "vendor": "lab"}, ) ) obj_rows.append( _obj_row( parent_collection="hosts", parent_id=host_id, collection="hooks", name="before_vm_start", data={"event_name": "before_vm_start"}, ) ) obj_rows.append( _obj_row( parent_collection="hosts", parent_id=host_id, collection="storage", name="local-data", data={"type": "data", "path": "/var/lib/ovirt/storage", "status": "up"}, ) ) obj_rows.append( _obj_row( parent_collection="hosts", parent_id=host_id, collection="katelloerrata", name="RHSA-2024:0001", data={"title": "Important: kernel security update"}, ) ) if tag_ids: tag_rows.append( ( stable_id("ta", "host", str(host_id), str(tag_ids[0])), tag_ids[0], "host", host_id, ) ) for net_id in network_ids: perm("network", net_id, f"net-{net_id}") obj_rows.append( _obj_row( parent_collection="networks", parent_id=net_id, collection="networklabels", name="ovirtmgmt", data={"description": "Management network label"}, ) ) for sd_id in storage_domain_ids: perm("storage_domain", sd_id, f"sd-{sd_id}") obj_rows.append( _obj_row( parent_collection="storagedomains", parent_id=sd_id, collection="files", name="rhel-9.iso", data={"type": "iso", "size": 8 * 1024**3}, ) ) obj_rows.append( _obj_row( parent_collection="storagedomains", parent_id=sd_id, collection="files", name="virtio-win.iso", data={"type": "iso", "size": 512 * 1024**2}, ) ) obj_rows.append( _obj_row( parent_collection="storagedomains", parent_id=sd_id, collection="images", name="base-image", data={"description": "Base disk image"}, ) ) obj_rows.append( _obj_row( parent_collection="storagedomains", parent_id=sd_id, collection="diskprofiles", name="default", data={"description": "Default disk profile"}, ) ) for tpl_id in template_ids: perm("template", tpl_id, f"tpl-{tpl_id}") obj_rows.append( _obj_row( parent_collection="templates", parent_id=tpl_id, collection="nics", name="nic1", data={"interface": "virtio"}, ) ) obj_rows.append( _obj_row( parent_collection="templates", parent_id=tpl_id, collection="diskattachments", name="disk1", data={"bootable": True, "interface": "virtio_scsi"}, ) ) obj_rows.append( _obj_row( parent_collection="templates", parent_id=tpl_id, collection="cdroms", name="ide0", data={"file": {"id": "rhel-9.iso"}}, ) ) obj_rows.append( _obj_row( parent_collection="templates", parent_id=tpl_id, collection="graphicsconsoles", name="spice", data={"protocol": "spice"}, ) ) obj_rows.append( _obj_row( parent_collection="templates", parent_id=tpl_id, collection="watchdogs", name="i6300esb", data={"model": "i6300esb", "action": "reset"}, ) ) for disk_id in disk_ids: perm("disk", disk_id, f"disk-{disk_id}") obj_rows.append( _obj_row( parent_collection="disks", parent_id=disk_id, collection="statistics", name="data.current.read", data={"unit": "bytespers", "values": {"value": [{"datum": 1024}]}}, ) ) if tag_ids: for user_id in user_ids: tag_rows.append( ( stable_id("ta", "user", str(user_id), str(tag_ids[0])), tag_ids[0], "user", user_id, ) ) for group_id in group_ids: perm("group", group_id, f"group-{group_id}") tag_rows.append( ( stable_id("ta", "group", str(group_id), str(tag_ids[0])), tag_ids[0], "group", group_id, ) ) else: for group_id in group_ids: perm("group", group_id, f"group-{group_id}") for vm_id in vm_ids: perm("vm", vm_id, f"vm-{vm_id}") obj_rows.extend( [ _obj_row( parent_collection="vms", parent_id=vm_id, collection="cdroms", name="ide0", data={"file": {"id": "rhel-9.iso"}}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="graphicsconsoles", name="vnc", data={"protocol": "vnc", "port": 5900, "address": "127.0.0.1"}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="graphicsconsoles", name="spice", data={"protocol": "spice", "port": 5901}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="reporteddevices", name="eth0", data={"type": "network", "mac": {"address": "00:1a:4a:01:00:01"}}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="sessions", name="console-1", data={"user": {"name": "admin@internal"}, "ip": {"address": "10.0.0.1"}}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="applications", name="qemu-guest-agent", data={"version": "8.2.0"}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="watchdogs", name="i6300esb", data={"model": "i6300esb", "action": "reset"}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="statistics", name="memory.installed", data={"unit": "bytes", "values": {"value": [{"datum": 2 * 1024**3}]}}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="numanodes", name="0", data={"index": 0, "memory": 1024**3}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="hostdevices", name="pci_0000_00_02_0", data={"capability": "pci"}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="mediateddevices", name="mdev0", data={"spec_params": {"mdev_type": "nvidia-11"}}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="affinitylabels", name="label-a", data={"description": "VM affinity label"}, ), _obj_row( parent_collection="vms", parent_id=vm_id, collection="katelloerrata", name="RHSA-2024:0001", data={"title": "Important: qemu-kvm security update"}, ), ] ) for user_id in user_ids: obj_rows.append( _obj_row( parent_collection="users", parent_id=user_id, collection="sshpublickeys", name="lab-key", data={ "content": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILabSeedKey admin@lab", }, ) ) # Scheduling policy children + role permits for sp_name in ("evenly_distributed", "power_saving", "vm_evenly_distributed"): sp_id = await conn.fetchval( "SELECT id FROM ov_api_objects WHERE collection='schedulingpolicies' AND name=$1", sp_name, ) if sp_id is None: continue for sub, child in ( ("filters", "Memory"), ("weights", "EvenlyDistributed"), ("balances", "EvenlyDistributed"), ): obj_rows.append( _obj_row( parent_collection="schedulingpolicies", parent_id=sp_id, collection=sub, name=child, data={"factor": 1}, ) ) for role_name in ("SuperUser", "UserRole", "ClusterAdmin"): role_id = await conn.fetchval("SELECT id FROM ov_roles WHERE name=$1", role_name) if role_id is None: continue for permit in ("create_vm", "login", "manipulate_vm"): obj_rows.append( _obj_row( parent_collection="roles", parent_id=role_id, collection="permits", name=permit, data={"administrative": role_name != "UserRole"}, ) ) if perm_rows: await conn.executemany( """INSERT INTO ov_permissions(id, role_id, user_id, object_type, object_id) VALUES($1,$2,$3,$4,$5::uuid) ON CONFLICT (id) DO NOTHING""", perm_rows, ) await _insert_objs(conn, obj_rows) if tag_rows: await conn.executemany( """INSERT INTO ov_tag_assignments(id, tag_id, object_type, object_id) VALUES($1,$2,$3,$4::uuid) ON CONFLICT DO NOTHING""", tag_rows, )