Files
ovirt-api-simulator/app/ovirt/seed.py
T

362 lines
12 KiB
Python

"""Minimal and demo seed profiles for the oVirt Engine simulator."""
from __future__ import annotations
import json
from typing import Any
from asyncpg import Connection
from app.ovirt.ids import stable_id
from app.security.auth import hash_secret
MINIMAL_PROFILE = "minimal"
# Legacy name kept for imports; sized demos live in demo_datacenter.DEMO_PROFILES.
DEMO_PROFILE = "large"
async def clear_ovirt_state(conn: Connection) -> None:
tables = [
"ov_job_steps",
"ov_jobs",
"ov_events",
"ov_tag_assignments",
"ov_tags",
"ov_snapshots",
"ov_nics",
"ov_disk_attachments",
"ov_disks",
"ov_vms",
"ov_templates",
"ov_affinity_groups",
"ov_quotas",
"ov_vnic_profiles",
"ov_networks",
"ov_storage_domain_attachments",
"ov_storage_domains",
"ov_storage_connections",
"ov_hosts",
"ov_clusters",
"ov_datacenters",
"ov_bookmarks",
"ov_permissions",
"ov_tokens",
"ov_users",
"ov_groups",
"ov_roles",
"ov_domains",
"ov_api_objects",
"ov_demo_meta",
]
for table in tables:
await conn.execute(f"TRUNCATE TABLE {table} CASCADE")
async def seed_ovirt(conn: Connection) -> dict[str, Any]:
"""Minimal lab: 1 DC, 1 cluster, 1 host, Blank template, admin user."""
await clear_ovirt_state(conn)
domain_id = stable_id("domain", "internal")
await conn.execute(
"INSERT INTO ov_domains(id, name) VALUES($1, 'internal')", domain_id
)
roles = [
(stable_id("role", "SuperUser"), "SuperUser", True),
(stable_id("role", "UserRole"), "UserRole", False),
(stable_id("role", "ClusterAdmin"), "ClusterAdmin", True),
]
for rid, name, admin in roles:
await conn.execute(
"INSERT INTO ov_roles(id, name, administrative) VALUES($1,$2,$3)",
rid,
name,
admin,
)
admin_id = stable_id("user", "admin")
pwd = hash_secret("secret", salt=b"ovirt-sim-v1-salt!")
await conn.execute(
"""INSERT INTO ov_users(id, domain_id, name, password_hash, enabled, principal)
VALUES($1,$2,'admin',$3,true,'admin@internal')""",
admin_id,
domain_id,
pwd,
)
await conn.execute(
"""INSERT INTO ov_permissions(id, role_id, user_id, object_type)
VALUES($1,$2,$3,'system')""",
stable_id("perm", "admin-super"),
roles[0][0],
admin_id,
)
# Extra lab users
for uname in ("ops", "developer", "demo"):
uid = stable_id("user", uname)
await conn.execute(
"""INSERT INTO ov_users(id, domain_id, name, password_hash, enabled, principal)
VALUES($1,$2,$3,$4,true,$5)""",
uid,
domain_id,
uname,
pwd,
f"{uname}@internal",
)
await conn.execute(
"""INSERT INTO ov_permissions(id, role_id, user_id, object_type)
VALUES($1,$2,$3,'system')""",
stable_id("perm", uname),
roles[1][0],
uid,
)
dc_id = stable_id("dc", "Default")
await conn.execute(
"""INSERT INTO ov_datacenters(id, name, description, status, version_major, version_minor)
VALUES($1,'Default','Default datacenter','up',4,5)""",
dc_id,
)
cluster_id = stable_id("cluster", "Default")
await conn.execute(
"""INSERT INTO ov_clusters(id, datacenter_id, name, description)
VALUES($1,$2,'Default','Default cluster')""",
cluster_id,
dc_id,
)
host_id = stable_id("host", "host01")
await conn.execute(
"""INSERT INTO ov_hosts(id, cluster_id, name, address, status, memory, cpu_cores)
VALUES($1,$2,'host01','192.168.1.10','up',$3,16)""",
host_id,
cluster_id,
128 * 1024**3,
)
net_id = stable_id("net", "ovirtmgmt")
await conn.execute(
"""INSERT INTO ov_networks(id, datacenter_id, name, description)
VALUES($1,$2,'ovirtmgmt','Management network')""",
net_id,
dc_id,
)
profile_id = stable_id("vnic", "ovirtmgmt")
await conn.execute(
"INSERT INTO ov_vnic_profiles(id, network_id, name) VALUES($1,$2,'ovirtmgmt')",
profile_id,
net_id,
)
sd_id = stable_id("sd", "data1")
await conn.execute(
"""INSERT INTO ov_storage_domains(id, name, type, storage_type, status, available, used)
VALUES($1,'data1','data','nfs','active',$2,$3)""",
sd_id,
2 * 1024**4,
100 * 1024**3,
)
await conn.execute(
"""INSERT INTO ov_storage_domain_attachments(id, storage_domain_id, datacenter_id, status)
VALUES($1,$2,$3,'active')""",
stable_id("sda", "data1"),
sd_id,
dc_id,
)
await conn.execute(
"""INSERT INTO ov_storage_connections(id, type, address, path)
VALUES($1,'nfs','nfs.lab.local','/export/data1')""",
stable_id("sc", "data1"),
)
blank_id = stable_id("template", "Blank")
await conn.execute(
"""INSERT INTO ov_templates(id, cluster_id, name, description, status, memory)
VALUES($1,$2,'Blank','Blank template','ok',$3)""",
blank_id,
cluster_id,
1024**3,
)
# One sample VM
vm_id = stable_id("vm", "lab-vm-01")
await conn.execute(
"""INSERT INTO ov_vms(id, cluster_id, template_id, name, description, status,
memory, cpu_sockets, cpu_cores, cpu_threads, os_type, type)
VALUES($1,$2,$3,'lab-vm-01','Sample VM','down',$4,1,2,1,'rhel_8x64','server')""",
vm_id,
cluster_id,
blank_id,
2 * 1024**3,
)
disk_id = stable_id("disk", "lab-vm-01")
await conn.execute(
"""INSERT INTO ov_disks(id, name, provisioned_size, actual_size, storage_domain_id)
VALUES($1,'lab-vm-01_Disk1',$2,$2,$3)""",
disk_id,
20 * 1024**3,
sd_id,
)
await conn.execute(
"""INSERT INTO ov_disk_attachments(id, vm_id, disk_id, bootable)
VALUES($1,$2,$3,true)""",
stable_id("da", "lab-vm-01"),
vm_id,
disk_id,
)
await conn.execute(
"""INSERT INTO ov_nics(id, vm_id, name, mac_address, vnic_profile_id)
VALUES($1,$2,'nic1','00:1a:4a:16:01:01',$3)""",
stable_id("nic", "lab-vm-01"),
vm_id,
profile_id,
)
await conn.execute(
"INSERT INTO ov_bookmarks(id, name, value) VALUES($1,'AllVMs','Vms:')",
stable_id("bm", "AllVMs"),
)
await conn.execute(
"""INSERT INTO ov_events(code, severity, description, user_id, vm_id)
VALUES(1,'normal','Engine started',$1,$2)""",
admin_id,
vm_id,
)
await conn.execute(
"INSERT INTO ov_groups(id, domain_id, name) VALUES($1,$2,'engine-admins')",
stable_id("group", "engine-admins"),
domain_id,
)
await conn.execute(
"INSERT INTO ov_tags(id, name, description) VALUES($1,'lab','Lab tag')",
stable_id("tag", "lab"),
)
job_id = stable_id("job", "seed-1")
await conn.execute(
"""INSERT INTO ov_jobs(id, description, status, owner_id)
VALUES($1,'Seed inventory job','finished',$2)""",
job_id,
admin_id,
)
await conn.execute(
"""INSERT INTO ov_job_steps(id, job_id, description, status, type, number)
VALUES($1,$2,'Finish seed','finished','executing',1)""",
stable_id("step", "seed-1"),
job_id,
)
# Surface-complete sample objects (generic collections)
for collection, name in (
("instancetypes", "Large"),
("macpools", "Default"),
("schedulingpolicies", "evenly_distributed"),
("schedulingpolicies", "power_saving"),
("schedulingpolicies", "vm_evenly_distributed"),
("schedulingpolicyunits", "EvenlyDistributed"),
("clusterlevels", "4.5"),
("icons", "default"),
("operatingsystems", "rhel_8x64"),
("networkfilters", "vdsm-no-mac-spoofing"),
("vmpools", "pool-demo"),
("affinitylabels", "label-a"),
("katelloerrata", "RHSA-2024:0001"),
("externalhostproviders", "foreman-lab"),
("openstacknetworkproviders", "ovn-provider"),
("openstackimageproviders", "glance-lab"),
("openstackvolumeproviders", "cinder-lab"),
("imagetransfers", "transfer-1"),
):
await conn.execute(
"""INSERT INTO ov_api_objects(id, collection, name, status, data)
VALUES($1,$2,$3,'ok',$4::jsonb)
ON CONFLICT (id) DO NOTHING""",
stable_id("obj", collection, name),
collection,
name,
json.dumps({"name": name, "description": f"seed {collection}"}),
)
from app.ovirt.settings import seed_engine_options
await seed_engine_options(conn)
# Nested entity links + resource permissions (avoid empty subcollection GETs)
from app.ovirt.seed_nested import seed_nested_for_inventory
tag_id = stable_id("tag", "lab")
await conn.execute(
"""INSERT INTO ov_tag_assignments(id, tag_id, object_type, object_id)
VALUES($1,$2,'vm',$3) ON CONFLICT DO NOTHING""",
stable_id("ta", "lab", "lab-vm-01"),
tag_id,
vm_id,
)
await conn.execute(
"""INSERT INTO ov_snapshots(id, vm_id, description, status)
VALUES($1,$2,'seed-snapshot','ok')""",
stable_id("snap", "lab-vm-01", "1"),
vm_id,
)
await conn.execute(
"""INSERT INTO ov_quotas(id, datacenter_id, name, description)
VALUES($1,$2,'Default','Default quota')""",
stable_id("quota", "Default"),
dc_id,
)
await conn.execute(
"""INSERT INTO ov_affinity_groups(id, cluster_id, name, enforcing, positive)
VALUES($1,$2,'web-affinity',true,true)""",
stable_id("ag", "Default"),
cluster_id,
)
user_ids = [
r["id"]
for r in await conn.fetch("SELECT id FROM ov_users ORDER BY name")
]
group_ids = [r["id"] for r in await conn.fetch("SELECT id FROM ov_groups ORDER BY name")]
await seed_nested_for_inventory(
conn,
admin_user_id=admin_id,
role_user_id=roles[1][0],
datacenter_ids=[dc_id],
cluster_ids=[cluster_id],
host_ids=[host_id],
network_ids=[net_id],
storage_domain_ids=[sd_id],
template_ids=[blank_id],
vm_ids=[vm_id],
disk_ids=[disk_id],
tag_ids=[tag_id],
user_ids=user_ids,
group_ids=group_ids,
)
await conn.execute(
"INSERT INTO ov_demo_meta(key, value) VALUES('profile', $1)", MINIMAL_PROFILE
)
return {
"profile": MINIMAL_PROFILE,
"vms": 1,
"hosts": 1,
"datacenters": 1,
"users": 4,
}
async def ovirt_demo_summary(conn: Connection) -> dict[str, Any]:
from app.ovirt.demo_datacenter import CLUSTER_SIZES, DEMO_PROFILES
profile = await conn.fetchval("SELECT value FROM ov_demo_meta WHERE key='profile'")
active = profile or MINIMAL_PROFILE
size = CLUSTER_SIZES.get(active) or (
CLUSTER_SIZES["large"] if active == "demo" else None
)
return {
"profile": active,
"loaded": active in DEMO_PROFILES,
"size": size.name if size else None,
"size_hosts": size.hosts if size else None,
"size_vms": size.vms if size else None,
"vms": await conn.fetchval("SELECT count(*) FROM ov_vms") or 0,
"hosts": await conn.fetchval("SELECT count(*) FROM ov_hosts") or 0,
"datacenters": await conn.fetchval("SELECT count(*) FROM ov_datacenters") or 0,
"clusters": await conn.fetchval("SELECT count(*) FROM ov_clusters") or 0,
"disks": await conn.fetchval("SELECT count(*) FROM ov_disks") or 0,
"networks": await conn.fetchval("SELECT count(*) FROM ov_networks") or 0,
"storage_domains": await conn.fetchval("SELECT count(*) FROM ov_storage_domains") or 0,
"templates": await conn.fetchval("SELECT count(*) FROM ov_templates") or 0,
"users": await conn.fetchval("SELECT count(*) FROM ov_users") or 0,
"events": await conn.fetchval("SELECT count(*) FROM ov_events") or 0,
"jobs": await conn.fetchval("SELECT count(*) FROM ov_jobs") or 0,
}