cbd0adca91
Stateful FastAPI lab with contract packs, Compose/Helm, Docker Hub release targets, and Pulumi coverage across all Engine series (GET/POST/PUT/DELETE/HEAD).
349 lines
12 KiB
Python
349 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"
|
|
DEMO_PROFILE = "demo"
|
|
|
|
|
|
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"),
|
|
("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)""",
|
|
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]:
|
|
profile = await conn.fetchval("SELECT value FROM ov_demo_meta WHERE key='profile'")
|
|
return {
|
|
"profile": profile or MINIMAL_PROFILE,
|
|
"loaded": profile == DEMO_PROFILE,
|
|
"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,
|
|
}
|