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).
437 lines
16 KiB
Python
437 lines
16 KiB
Python
"""Large demo datacenter seed (~1000 VMs + full inventory)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from asyncpg import Connection
|
|
|
|
from app.ovirt.ids import stable_id
|
|
from app.ovirt.seed import DEMO_PROFILE, clear_ovirt_state, seed_ovirt
|
|
from app.security.auth import hash_secret
|
|
|
|
DEMO_VM_COUNT = 1000
|
|
|
|
|
|
async def seed_ovirt_demo(conn: Connection) -> dict[str, Any]:
|
|
"""Replace state with a multi-DC demo inventory including ~1000 VMs."""
|
|
|
|
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)
|
|
pwd = hash_secret("secret", salt=b"ovirt-sim-v1-salt!")
|
|
role_super = stable_id("role", "SuperUser")
|
|
role_user = stable_id("role", "UserRole")
|
|
role_cluster = stable_id("role", "ClusterAdmin")
|
|
for rid, name, admin in (
|
|
(role_super, "SuperUser", True),
|
|
(role_user, "UserRole", False),
|
|
(role_cluster, "ClusterAdmin", True),
|
|
(stable_id("role", "TemplateAdmin"), "TemplateAdmin", True),
|
|
(stable_id("role", "StorageAdmin"), "StorageAdmin", True),
|
|
):
|
|
await conn.execute(
|
|
"INSERT INTO ov_roles(id, name, administrative) VALUES($1,$2,$3)",
|
|
rid,
|
|
name,
|
|
admin,
|
|
)
|
|
|
|
users = {}
|
|
for uname, role in (
|
|
("admin", role_super),
|
|
("ops", role_cluster),
|
|
("developer", role_user),
|
|
("demo", role_user),
|
|
):
|
|
uid = stable_id("user", uname)
|
|
users[uname] = uid
|
|
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),
|
|
role,
|
|
uid,
|
|
)
|
|
|
|
await conn.execute(
|
|
"INSERT INTO ov_groups(id, domain_id, name) VALUES($1,$2,'engine-admins')",
|
|
stable_id("group", "engine-admins"),
|
|
domain_id,
|
|
)
|
|
for gname in ("developers", "operators", "readers"):
|
|
await conn.execute(
|
|
"INSERT INTO ov_groups(id, domain_id, name) VALUES($1,$2,$3)",
|
|
stable_id("group", gname),
|
|
domain_id,
|
|
gname,
|
|
)
|
|
|
|
# 3 datacenters, multiple clusters/hosts/storage/networks
|
|
dc_specs = [
|
|
("dc-prod", "Production", False, 4, 5),
|
|
("dc-stage", "Staging", False, 4, 4),
|
|
("dc-edge", "Edge", True, 4, 3),
|
|
]
|
|
clusters: list[tuple[Any, Any, str]] = []
|
|
hosts: list[Any] = []
|
|
networks: list[Any] = []
|
|
profiles: list[Any] = []
|
|
storage_domains: list[Any] = []
|
|
|
|
storage_types = ["nfs", "iscsi", "fcp", "localfs"]
|
|
for dc_key, dc_name, local, maj, minor in dc_specs:
|
|
dc_id = stable_id("dc", dc_key)
|
|
await conn.execute(
|
|
"""INSERT INTO ov_datacenters(id, name, description, local, status, version_major, version_minor)
|
|
VALUES($1,$2,$3,$4,'up',$5,$6)""",
|
|
dc_id,
|
|
dc_name,
|
|
f"{dc_name} datacenter",
|
|
local,
|
|
maj,
|
|
minor,
|
|
)
|
|
await conn.execute(
|
|
"""INSERT INTO ov_quotas(id, datacenter_id, name, description)
|
|
VALUES($1,$2,'Default','Default quota')""",
|
|
stable_id("quota", dc_key),
|
|
dc_id,
|
|
)
|
|
for ci in range(2):
|
|
cname = f"{dc_key}-cluster-{ci+1}"
|
|
cid = stable_id("cluster", cname)
|
|
clusters.append((cid, dc_id, cname))
|
|
await conn.execute(
|
|
"""INSERT INTO ov_clusters(id, datacenter_id, name, description, version_major, version_minor)
|
|
VALUES($1,$2,$3,$4,$5,$6)""",
|
|
cid,
|
|
dc_id,
|
|
cname,
|
|
f"Cluster {ci+1} in {dc_name}",
|
|
maj,
|
|
minor,
|
|
)
|
|
await conn.execute(
|
|
"""INSERT INTO ov_affinity_groups(id, cluster_id, name, enforcing, positive)
|
|
VALUES($1,$2,'web-affinity',true,true)""",
|
|
stable_id("ag", cname),
|
|
cid,
|
|
)
|
|
for hi in range(4):
|
|
hname = f"{cname}-host-{hi+1:02d}"
|
|
hid = stable_id("host", hname)
|
|
hosts.append(hid)
|
|
await conn.execute(
|
|
"""INSERT INTO ov_hosts(id, cluster_id, name, address, status, memory, cpu_cores, type)
|
|
VALUES($1,$2,$3,$4,'up',$5,32,'rhel')""",
|
|
hid,
|
|
cid,
|
|
hname,
|
|
f"10.{dc_specs.index((dc_key, dc_name, local, maj, minor))+10}.{ci+1}.{hi+10}",
|
|
(256 + hi * 32) * 1024**3,
|
|
)
|
|
# networks
|
|
for nname, vlan in (("ovirtmgmt", None), ("vm-net", 100), ("storage-net", 200)):
|
|
nid = stable_id("net", dc_key, nname)
|
|
networks.append(nid)
|
|
await conn.execute(
|
|
"""INSERT INTO ov_networks(id, datacenter_id, name, description, vlan_id)
|
|
VALUES($1,$2,$3,$4,$5)""",
|
|
nid,
|
|
dc_id,
|
|
nname if nname != "ovirtmgmt" else f"{dc_key}-ovirtmgmt" if dc_key != "dc-prod" else "ovirtmgmt",
|
|
f"{nname} in {dc_name}",
|
|
vlan,
|
|
)
|
|
pid = stable_id("vnic", dc_key, nname)
|
|
profiles.append(pid)
|
|
await conn.execute(
|
|
"INSERT INTO ov_vnic_profiles(id, network_id, name) VALUES($1,$2,$3)",
|
|
pid,
|
|
nid,
|
|
nname,
|
|
)
|
|
# storage domains
|
|
for si, stype in enumerate(storage_types):
|
|
sname = f"{dc_key}-{stype}-{si+1}"
|
|
sid = stable_id("sd", sname)
|
|
storage_domains.append(sid)
|
|
await conn.execute(
|
|
"""INSERT INTO ov_storage_domains(id, name, type, storage_type, status, available, used)
|
|
VALUES($1,$2,'data',$3,'active',$4,$5)""",
|
|
sid,
|
|
sname,
|
|
stype,
|
|
(5 + si) * 1024**4,
|
|
si * 200 * 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", sname),
|
|
sid,
|
|
dc_id,
|
|
)
|
|
await conn.execute(
|
|
"""INSERT INTO ov_storage_connections(id, type, address, path)
|
|
VALUES($1,$2,$3,$4)""",
|
|
stable_id("sc", sname),
|
|
stype if stype != "localfs" else "localfs",
|
|
f"storage-{si}.lab.local",
|
|
f"/export/{sname}",
|
|
)
|
|
|
|
blank_id = stable_id("template", "Blank")
|
|
await conn.execute(
|
|
"""INSERT INTO ov_templates(id, cluster_id, name, description, status, memory, cpu_sockets, cpu_cores)
|
|
VALUES($1,$2,'Blank','Blank template','ok',$3,1,1)""",
|
|
blank_id,
|
|
clusters[0][0],
|
|
1024**3,
|
|
)
|
|
for tname, mem, cores in (
|
|
("rhel8-base", 4 * 1024**3, 2),
|
|
("rhel9-base", 4 * 1024**3, 2),
|
|
("win2022-base", 8 * 1024**3, 4),
|
|
("ubuntu2204-base", 2 * 1024**3, 2),
|
|
):
|
|
await conn.execute(
|
|
"""INSERT INTO ov_templates(id, cluster_id, name, description, status, memory, cpu_sockets, cpu_cores)
|
|
VALUES($1,$2,$3,$4,'ok',$5,1,$6)""",
|
|
stable_id("template", tname),
|
|
clusters[0][0],
|
|
tname,
|
|
f"Template {tname}",
|
|
mem,
|
|
cores,
|
|
)
|
|
|
|
# ~1000 VMs spread across clusters
|
|
statuses = ["up", "up", "up", "down", "down", "suspended", "powering_up"]
|
|
os_types = ["rhel_8x64", "rhel_9x64", "ubuntu_22_04", "windows_2022", "other"]
|
|
default_profile = profiles[0]
|
|
default_sd = storage_domains[0]
|
|
|
|
vm_rows = []
|
|
disk_rows = []
|
|
da_rows = []
|
|
nic_rows = []
|
|
snap_rows = []
|
|
|
|
for i in range(DEMO_VM_COUNT):
|
|
cluster_id, _dc, cname = clusters[i % len(clusters)]
|
|
host_id = hosts[i % len(hosts)] if i % 3 != 0 else None
|
|
status = statuses[i % len(statuses)]
|
|
if status == "down":
|
|
host_id = None
|
|
name = f"vm-{i+1:04d}"
|
|
vm_id = stable_id("vm", name)
|
|
memory = (1 + (i % 8)) * 1024**3
|
|
cores = 1 + (i % 8)
|
|
vm_rows.append(
|
|
(
|
|
vm_id,
|
|
cluster_id,
|
|
blank_id,
|
|
name,
|
|
f"Demo VM {i+1}",
|
|
status,
|
|
memory,
|
|
1,
|
|
cores,
|
|
1,
|
|
os_types[i % len(os_types)],
|
|
"server" if i % 5 else "desktop",
|
|
host_id,
|
|
)
|
|
)
|
|
disk_id = stable_id("disk", name)
|
|
size = (10 + (i % 50)) * 1024**3
|
|
disk_rows.append(
|
|
(disk_id, f"{name}_Disk1", size, size, storage_domains[i % len(storage_domains)])
|
|
)
|
|
da_rows.append((stable_id("da", name), vm_id, disk_id, True))
|
|
nic_rows.append(
|
|
(
|
|
stable_id("nic", name),
|
|
vm_id,
|
|
"nic1",
|
|
f"00:1a:4a:{(i >> 16) & 0xFF:02x}:{(i >> 8) & 0xFF:02x}:{i & 0xFF:02x}",
|
|
profiles[i % len(profiles)] if profiles else default_profile,
|
|
)
|
|
)
|
|
if i % 7 == 0:
|
|
snap_rows.append(
|
|
(stable_id("snap", name, "1"), vm_id, f"snapshot-{name}", "ok")
|
|
)
|
|
|
|
# Batch insert VMs
|
|
await conn.executemany(
|
|
"""INSERT INTO ov_vms(id, cluster_id, template_id, name, description, status,
|
|
memory, cpu_sockets, cpu_cores, cpu_threads, os_type, type, host_id)
|
|
VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13)""",
|
|
vm_rows,
|
|
)
|
|
await conn.executemany(
|
|
"""INSERT INTO ov_disks(id, name, provisioned_size, actual_size, storage_domain_id)
|
|
VALUES($1,$2,$3,$4,$5)""",
|
|
disk_rows,
|
|
)
|
|
await conn.executemany(
|
|
"""INSERT INTO ov_disk_attachments(id, vm_id, disk_id, bootable)
|
|
VALUES($1,$2,$3,$4)""",
|
|
da_rows,
|
|
)
|
|
await conn.executemany(
|
|
"""INSERT INTO ov_nics(id, vm_id, name, mac_address, vnic_profile_id)
|
|
VALUES($1,$2,$3,$4,$5)""",
|
|
nic_rows,
|
|
)
|
|
if snap_rows:
|
|
await conn.executemany(
|
|
"""INSERT INTO ov_snapshots(id, vm_id, description, status)
|
|
VALUES($1,$2,$3,$4)""",
|
|
snap_rows,
|
|
)
|
|
|
|
# Tags, bookmarks, events, jobs, surface objects
|
|
for tname in ("production", "web", "database", "batch", "gpu"):
|
|
tid = stable_id("tag", tname)
|
|
await conn.execute(
|
|
"INSERT INTO ov_tags(id, name, description) VALUES($1,$2,$3)",
|
|
tid,
|
|
tname,
|
|
f"Tag {tname}",
|
|
)
|
|
for i in range(0, min(50, DEMO_VM_COUNT), 10):
|
|
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", tname, str(i)),
|
|
tid,
|
|
stable_id("vm", f"vm-{i+1:04d}"),
|
|
)
|
|
|
|
await conn.execute(
|
|
"INSERT INTO ov_bookmarks(id, name, value) VALUES($1,'UpVMs','Vms: status=up')",
|
|
stable_id("bm", "UpVMs"),
|
|
)
|
|
for i in range(50):
|
|
await conn.execute(
|
|
"""INSERT INTO ov_events(code, severity, description, user_id)
|
|
VALUES($1,$2,$3,$4)""",
|
|
1000 + i,
|
|
"normal" if i % 4 else "warning",
|
|
f"Demo event {i}",
|
|
users["admin"],
|
|
)
|
|
for i in range(20):
|
|
jid = stable_id("job", str(i))
|
|
await conn.execute(
|
|
"""INSERT INTO ov_jobs(id, description, status, owner_id)
|
|
VALUES($1,$2,'finished',$3)""",
|
|
jid,
|
|
f"Demo job {i}",
|
|
users["admin"],
|
|
)
|
|
await conn.execute(
|
|
"""INSERT INTO ov_job_steps(id, job_id, description, status, type, number)
|
|
VALUES($1,$2,$3,'finished','executing',1)""",
|
|
stable_id("step", str(i)),
|
|
jid,
|
|
f"Step for job {i}",
|
|
)
|
|
|
|
for collection, names in (
|
|
("instancetypes", ["Tiny", "Small", "Medium", "Large", "XLarge"]),
|
|
("macpools", ["Default", "Secondary"]),
|
|
("schedulingpolicies", ["evenly_distributed", "power_saving", "vm_evenly_distributed"]),
|
|
("schedulingpolicyunits", ["EvenlyDistributed", "PowerSaving", "VmEvenlyDistributed"]),
|
|
("clusterlevels", ["4.3", "4.4", "4.5"]),
|
|
("icons", ["default", "custom"]),
|
|
("operatingsystems", ["rhel_8x64", "rhel_9x64", "windows_2022", "ubuntu_22_04"]),
|
|
("networkfilters", ["vdsm-no-mac-spoofing"]),
|
|
("vmpools", ["web-pool", "batch-pool"]),
|
|
("affinitylabels", ["label-a", "label-b"]),
|
|
("katelloerrata", ["RHSA-2024:0001", "RHBA-2024:0002"]),
|
|
("externalhostproviders", ["foreman-lab"]),
|
|
("openstacknetworkproviders", ["ovn-provider"]),
|
|
("openstackimageproviders", ["glance-lab"]),
|
|
("openstackvolumeproviders", ["cinder-lab"]),
|
|
("imagetransfers", ["transfer-1"]),
|
|
):
|
|
for name in names:
|
|
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"demo {collection}"}),
|
|
)
|
|
|
|
from app.ovirt.settings import seed_engine_options
|
|
|
|
await seed_engine_options(conn)
|
|
|
|
from app.ovirt.seed_nested import seed_nested_for_inventory
|
|
|
|
dc_ids = [stable_id("dc", key) for key, *_ in dc_specs]
|
|
cluster_ids = [c[0] for c in clusters]
|
|
template_ids = [
|
|
blank_id,
|
|
*[
|
|
stable_id("template", n)
|
|
for n in ("rhel8-base", "rhel9-base", "win2022-base", "ubuntu2204-base")
|
|
],
|
|
]
|
|
tag_ids = [stable_id("tag", t) for t in ("production", "web", "database", "batch", "gpu")]
|
|
await seed_nested_for_inventory(
|
|
conn,
|
|
admin_user_id=users["admin"],
|
|
role_user_id=role_user,
|
|
datacenter_ids=dc_ids,
|
|
cluster_ids=cluster_ids,
|
|
host_ids=list(hosts),
|
|
network_ids=list(networks),
|
|
storage_domain_ids=list(storage_domains),
|
|
template_ids=template_ids,
|
|
vm_ids=[stable_id("vm", f"vm-{i:04d}") for i in range(1, DEMO_VM_COUNT + 1)],
|
|
disk_ids=[stable_id("disk", f"vm-{i:04d}") for i in range(1, DEMO_VM_COUNT + 1)],
|
|
tag_ids=tag_ids,
|
|
user_ids=list(users.values()),
|
|
group_ids=[
|
|
stable_id("group", n)
|
|
for n in ("engine-admins", "developers", "operators", "readers")
|
|
],
|
|
)
|
|
|
|
await conn.execute(
|
|
"INSERT INTO ov_demo_meta(key, value) VALUES('profile', $1)", DEMO_PROFILE
|
|
)
|
|
return {
|
|
"profile": DEMO_PROFILE,
|
|
"vms": DEMO_VM_COUNT,
|
|
"hosts": len(hosts),
|
|
"datacenters": len(dc_specs),
|
|
"clusters": len(clusters),
|
|
"storage_domains": len(storage_domains),
|
|
"networks": len(networks),
|
|
}
|
|
|
|
|
|
# Re-export for web routes
|
|
__all__ = ["DEMO_PROFILE", "DEMO_VM_COUNT", "clear_ovirt_state", "seed_ovirt", "seed_ovirt_demo"]
|