Initial commit: VMware vSphere API simulator scaffold.
Add the FastAPI app, PostgreSQL migrations, Docker/Helm packaging, API contracts, docs, client examples, and the unit/integration/compatibility test suite for local client and tooling labs without a real vCenter.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
CREATE TABLE contract_snapshots (
|
||||
checksum text PRIMARY KEY,
|
||||
source_version text NOT NULL,
|
||||
document jsonb NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE TABLE nodes (
|
||||
id uuid PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
status text NOT NULL CHECK (status IN ('online', 'offline'))
|
||||
);
|
||||
CREATE TABLE resources (
|
||||
id uuid PRIMARY KEY,
|
||||
node_id uuid NOT NULL REFERENCES nodes(id) ON DELETE RESTRICT,
|
||||
kind text NOT NULL,
|
||||
external_id text NOT NULL,
|
||||
state jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
UNIQUE (kind, external_id)
|
||||
);
|
||||
CREATE INDEX resources_node_id_idx ON resources(node_id);
|
||||
CREATE TABLE principals (
|
||||
id uuid PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
password_hash text
|
||||
);
|
||||
CREATE TABLE roles (
|
||||
name text PRIMARY KEY,
|
||||
privileges text[] NOT NULL DEFAULT '{}'
|
||||
);
|
||||
CREATE TABLE acl_entries (
|
||||
principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE,
|
||||
role_name text NOT NULL REFERENCES roles(name) ON DELETE RESTRICT,
|
||||
path text NOT NULL,
|
||||
propagate boolean NOT NULL DEFAULT true,
|
||||
PRIMARY KEY (principal_id, role_name, path)
|
||||
);
|
||||
CREATE TABLE tasks (
|
||||
id uuid PRIMARY KEY,
|
||||
upid text NOT NULL UNIQUE,
|
||||
status text NOT NULL,
|
||||
payload jsonb NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX tasks_status_created_idx ON tasks(status, created_at);
|
||||
CREATE TABLE scenarios (
|
||||
id uuid PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
definition jsonb NOT NULL,
|
||||
enabled boolean NOT NULL DEFAULT true
|
||||
);
|
||||
CREATE TABLE audit_events (
|
||||
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
occurred_at timestamptz NOT NULL DEFAULT now(),
|
||||
principal text,
|
||||
action text NOT NULL,
|
||||
target text,
|
||||
details jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
CREATE INDEX audit_events_occurred_idx ON audit_events(occurred_at);
|
||||
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE realms (
|
||||
name text PRIMARY KEY,
|
||||
kind text NOT NULL CHECK (kind IN ('pam', 'pve', 'openid', 'ldap'))
|
||||
);
|
||||
INSERT INTO realms(name, kind) VALUES ('pam', 'pam'), ('pve', 'pve');
|
||||
ALTER TABLE principals ADD COLUMN realm_name text REFERENCES realms(name) ON DELETE RESTRICT;
|
||||
CREATE TABLE api_tokens (
|
||||
principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE,
|
||||
token_id text NOT NULL,
|
||||
secret_hash text NOT NULL,
|
||||
privileges text[] NOT NULL DEFAULT '{}',
|
||||
expires_at timestamptz,
|
||||
PRIMARY KEY (principal_id, token_id),
|
||||
CHECK (secret_hash LIKE 'scrypt$%')
|
||||
);
|
||||
CREATE INDEX api_tokens_expires_idx ON api_tokens(expires_at) WHERE expires_at IS NOT NULL;
|
||||
@@ -0,0 +1,32 @@
|
||||
ALTER TABLE tasks
|
||||
ADD COLUMN task_type text NOT NULL DEFAULT 'generic',
|
||||
ADD COLUMN progress integer NOT NULL DEFAULT 0 CHECK (progress BETWEEN 0 AND 100),
|
||||
ADD COLUMN result jsonb,
|
||||
ADD COLUMN error text,
|
||||
ADD COLUMN worker_id text,
|
||||
ADD COLUMN lease_expires_at timestamptz,
|
||||
ADD COLUMN cancel_requested boolean NOT NULL DEFAULT false,
|
||||
ADD COLUMN idempotency_key text UNIQUE,
|
||||
ADD COLUMN attempt integer NOT NULL DEFAULT 0,
|
||||
ADD CONSTRAINT tasks_status_check CHECK (status IN ('queued', 'running', 'success', 'error', 'cancelled'));
|
||||
CREATE INDEX tasks_claim_idx ON tasks(status, lease_expires_at, created_at);
|
||||
CREATE TABLE resource_locks (
|
||||
resource_key text PRIMARY KEY,
|
||||
task_id uuid NOT NULL UNIQUE REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
acquired_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE TABLE task_logs (
|
||||
task_id uuid NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
sequence bigint GENERATED ALWAYS AS IDENTITY,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
message text NOT NULL,
|
||||
PRIMARY KEY (task_id, sequence)
|
||||
);
|
||||
CREATE TABLE task_events (
|
||||
task_id uuid NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
sequence bigint GENERATED ALWAYS AS IDENTITY,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
kind text NOT NULL,
|
||||
data jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
PRIMARY KEY (task_id, sequence)
|
||||
);
|
||||
@@ -0,0 +1,204 @@
|
||||
CREATE TABLE clusters (
|
||||
id uuid PRIMARY KEY,
|
||||
external_id text NOT NULL UNIQUE,
|
||||
name text NOT NULL,
|
||||
version integer NOT NULL DEFAULT 1,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
INSERT INTO clusters(id, external_id, name)
|
||||
VALUES ('dc760c47-d8d7-57e6-9404-f0c6f2395d8f', 'default', 'pve-simulator');
|
||||
|
||||
ALTER TABLE nodes
|
||||
ADD COLUMN cluster_id uuid NOT NULL DEFAULT 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f'
|
||||
REFERENCES clusters(id) ON DELETE CASCADE,
|
||||
ADD COLUMN version integer NOT NULL DEFAULT 1,
|
||||
ADD COLUMN metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
ADD COLUMN created_at timestamptz NOT NULL DEFAULT now(),
|
||||
ADD COLUMN updated_at timestamptz NOT NULL DEFAULT now();
|
||||
|
||||
ALTER TABLE resources
|
||||
ADD COLUMN cluster_id uuid NOT NULL DEFAULT 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f'
|
||||
REFERENCES clusters(id) ON DELETE CASCADE,
|
||||
ADD COLUMN version integer NOT NULL DEFAULT 1,
|
||||
ADD COLUMN metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
ADD COLUMN created_at timestamptz NOT NULL DEFAULT now(),
|
||||
ADD COLUMN updated_at timestamptz NOT NULL DEFAULT now();
|
||||
CREATE UNIQUE INDEX resources_cluster_vmid_idx
|
||||
ON resources(cluster_id, external_id) WHERE kind IN ('qemu', 'lxc');
|
||||
|
||||
CREATE TABLE virtual_machines (
|
||||
resource_id uuid PRIMARY KEY REFERENCES resources(id) ON DELETE CASCADE,
|
||||
cluster_id uuid NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
|
||||
vmid integer NOT NULL CHECK (vmid BETWEEN 100 AND 999999999),
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
lock text,
|
||||
template boolean NOT NULL DEFAULT false,
|
||||
UNIQUE (cluster_id, vmid)
|
||||
);
|
||||
CREATE TABLE containers (
|
||||
resource_id uuid PRIMARY KEY REFERENCES resources(id) ON DELETE CASCADE,
|
||||
cluster_id uuid NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
|
||||
vmid integer NOT NULL CHECK (vmid BETWEEN 100 AND 999999999),
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
lock text,
|
||||
template boolean NOT NULL DEFAULT false,
|
||||
UNIQUE (cluster_id, vmid)
|
||||
);
|
||||
CREATE TABLE vm_disks (
|
||||
id uuid PRIMARY KEY,
|
||||
resource_id uuid NOT NULL REFERENCES resources(id) ON DELETE CASCADE,
|
||||
device text NOT NULL,
|
||||
storage_id text NOT NULL,
|
||||
size_bytes bigint NOT NULL CHECK (size_bytes >= 0),
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
UNIQUE (resource_id, device)
|
||||
);
|
||||
CREATE TABLE vm_network_interfaces (
|
||||
id uuid PRIMARY KEY,
|
||||
resource_id uuid NOT NULL REFERENCES resources(id) ON DELETE CASCADE,
|
||||
device text NOT NULL,
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
UNIQUE (resource_id, device)
|
||||
);
|
||||
|
||||
CREATE TABLE storages (
|
||||
resource_id uuid PRIMARY KEY REFERENCES resources(id) ON DELETE CASCADE,
|
||||
cluster_id uuid NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
|
||||
storage_id text NOT NULL,
|
||||
storage_type text NOT NULL,
|
||||
shared boolean NOT NULL DEFAULT false,
|
||||
capacity_bytes bigint CHECK (capacity_bytes >= 0),
|
||||
used_bytes bigint CHECK (used_bytes >= 0),
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
UNIQUE (cluster_id, storage_id)
|
||||
);
|
||||
CREATE TABLE storage_contents (
|
||||
id uuid PRIMARY KEY,
|
||||
storage_resource_id uuid NOT NULL REFERENCES storages(resource_id) ON DELETE CASCADE,
|
||||
volume_id text NOT NULL,
|
||||
content_type text NOT NULL,
|
||||
size_bytes bigint NOT NULL DEFAULT 0 CHECK (size_bytes >= 0),
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (storage_resource_id, volume_id)
|
||||
);
|
||||
|
||||
CREATE TABLE snapshots (
|
||||
id uuid PRIMARY KEY,
|
||||
resource_id uuid NOT NULL REFERENCES resources(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
parent_name text,
|
||||
description text,
|
||||
state jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (resource_id, name)
|
||||
);
|
||||
CREATE TABLE backups (
|
||||
id uuid PRIMARY KEY,
|
||||
resource_id uuid REFERENCES resources(id) ON DELETE SET NULL,
|
||||
storage_resource_id uuid NOT NULL REFERENCES storages(resource_id) ON DELETE CASCADE,
|
||||
volume_id text NOT NULL,
|
||||
size_bytes bigint NOT NULL DEFAULT 0 CHECK (size_bytes >= 0),
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (storage_resource_id, volume_id)
|
||||
);
|
||||
CREATE TABLE pools (
|
||||
id uuid PRIMARY KEY,
|
||||
cluster_id uuid NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
|
||||
pool_id text NOT NULL,
|
||||
comment text,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
UNIQUE (cluster_id, pool_id)
|
||||
);
|
||||
CREATE TABLE pool_members (
|
||||
pool_id uuid NOT NULL REFERENCES pools(id) ON DELETE CASCADE,
|
||||
resource_id uuid NOT NULL REFERENCES resources(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (pool_id, resource_id)
|
||||
);
|
||||
|
||||
CREATE TABLE identity_groups (
|
||||
id uuid PRIMARY KEY,
|
||||
group_id text NOT NULL UNIQUE,
|
||||
comment text,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
CREATE TABLE identity_group_members (
|
||||
group_id uuid NOT NULL REFERENCES identity_groups(id) ON DELETE CASCADE,
|
||||
principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (group_id, principal_id)
|
||||
);
|
||||
CREATE TABLE auth_tickets (
|
||||
id uuid PRIMARY KEY,
|
||||
principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE,
|
||||
ticket_hash text NOT NULL UNIQUE,
|
||||
issued_at timestamptz NOT NULL,
|
||||
expires_at timestamptz NOT NULL,
|
||||
revoked_at timestamptz
|
||||
);
|
||||
CREATE INDEX auth_tickets_expiry_idx ON auth_tickets(expires_at) WHERE revoked_at IS NULL;
|
||||
|
||||
CREATE TABLE contract_paths (
|
||||
snapshot_checksum text NOT NULL REFERENCES contract_snapshots(checksum) ON DELETE CASCADE,
|
||||
path text NOT NULL,
|
||||
document jsonb NOT NULL,
|
||||
PRIMARY KEY (snapshot_checksum, path)
|
||||
);
|
||||
CREATE TABLE contract_methods (
|
||||
snapshot_checksum text NOT NULL,
|
||||
path text NOT NULL,
|
||||
verb text NOT NULL,
|
||||
fingerprint text NOT NULL,
|
||||
document jsonb NOT NULL,
|
||||
PRIMARY KEY (snapshot_checksum, path, verb),
|
||||
FOREIGN KEY (snapshot_checksum, path)
|
||||
REFERENCES contract_paths(snapshot_checksum, path) ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE contract_parameters (
|
||||
snapshot_checksum text NOT NULL,
|
||||
path text NOT NULL,
|
||||
verb text NOT NULL,
|
||||
name text NOT NULL,
|
||||
location text NOT NULL,
|
||||
document jsonb NOT NULL,
|
||||
PRIMARY KEY (snapshot_checksum, path, verb, name, location),
|
||||
FOREIGN KEY (snapshot_checksum, path, verb)
|
||||
REFERENCES contract_methods(snapshot_checksum, path, verb) ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE contract_schema_fragments (
|
||||
id uuid PRIMARY KEY,
|
||||
snapshot_checksum text NOT NULL REFERENCES contract_snapshots(checksum) ON DELETE CASCADE,
|
||||
fingerprint text NOT NULL,
|
||||
document jsonb NOT NULL,
|
||||
UNIQUE (snapshot_checksum, fingerprint)
|
||||
);
|
||||
CREATE TABLE observed_contracts (
|
||||
id uuid PRIMARY KEY,
|
||||
source_version text NOT NULL,
|
||||
method_fingerprint text NOT NULL,
|
||||
observation jsonb NOT NULL,
|
||||
observed_at timestamptz NOT NULL,
|
||||
UNIQUE (source_version, method_fingerprint, observed_at)
|
||||
);
|
||||
|
||||
CREATE TABLE scenario_rules (
|
||||
id uuid PRIMARY KEY,
|
||||
scenario_id uuid NOT NULL REFERENCES scenarios(id) ON DELETE CASCADE,
|
||||
priority integer NOT NULL DEFAULT 0,
|
||||
matcher jsonb NOT NULL,
|
||||
action jsonb NOT NULL,
|
||||
enabled boolean NOT NULL DEFAULT true
|
||||
);
|
||||
CREATE INDEX scenario_rules_scenario_priority_idx ON scenario_rules(scenario_id, priority DESC);
|
||||
CREATE TABLE fault_injections (
|
||||
id uuid PRIMARY KEY,
|
||||
scenario_id uuid REFERENCES scenarios(id) ON DELETE CASCADE,
|
||||
fault_type text NOT NULL,
|
||||
matcher jsonb NOT NULL,
|
||||
parameters jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
active_from timestamptz,
|
||||
active_until timestamptz,
|
||||
enabled boolean NOT NULL DEFAULT true
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
INSERT INTO realms(name, kind) VALUES ('test', 'pve') ON CONFLICT (name) DO NOTHING;
|
||||
ALTER TABLE api_tokens
|
||||
ADD COLUMN comment text,
|
||||
ADD COLUMN privilege_separation boolean NOT NULL DEFAULT true,
|
||||
ADD COLUMN created_at timestamptz NOT NULL DEFAULT now(),
|
||||
ADD COLUMN updated_at timestamptz NOT NULL DEFAULT now();
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE group_acl_entries (
|
||||
group_id uuid NOT NULL REFERENCES identity_groups(id) ON DELETE CASCADE,
|
||||
role_name text NOT NULL REFERENCES roles(name) ON DELETE RESTRICT,
|
||||
path text NOT NULL,
|
||||
propagate boolean NOT NULL DEFAULT true,
|
||||
PRIMARY KEY (group_id, role_name, path)
|
||||
);
|
||||
CREATE INDEX identity_group_members_principal_idx
|
||||
ON identity_group_members(principal_id, group_id);
|
||||
@@ -0,0 +1,17 @@
|
||||
ALTER TABLE realms DROP CONSTRAINT IF EXISTS realms_kind_check;
|
||||
ALTER TABLE realms
|
||||
ADD CONSTRAINT realms_kind_check
|
||||
CHECK (kind IN ('pam', 'pve', 'openid', 'ldap', 'ad'));
|
||||
ALTER TABLE realms
|
||||
ADD COLUMN IF NOT EXISTS config jsonb NOT NULL DEFAULT '{}'::jsonb;
|
||||
UPDATE realms
|
||||
SET config = config || jsonb_build_object(
|
||||
'comment',
|
||||
CASE name
|
||||
WHEN 'pam' THEN 'Linux PAM standard authentication'
|
||||
WHEN 'pve' THEN 'Proxmox VE authentication server'
|
||||
ELSE COALESCE(config->>'comment', '')
|
||||
END
|
||||
)
|
||||
WHERE name IN ('pam', 'pve')
|
||||
AND COALESCE(config->>'comment', '') = '';
|
||||
@@ -0,0 +1,23 @@
|
||||
CREATE TABLE tfa_entries (
|
||||
principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE,
|
||||
entry_id text NOT NULL,
|
||||
tfa_type text NOT NULL CHECK (tfa_type IN ('totp', 'u2f', 'webauthn', 'recovery', 'yubico')),
|
||||
description text,
|
||||
enable boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
secret text,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
PRIMARY KEY (principal_id, entry_id)
|
||||
);
|
||||
CREATE INDEX tfa_entries_principal_idx ON tfa_entries(principal_id);
|
||||
|
||||
ALTER TABLE principals
|
||||
ADD COLUMN IF NOT EXISTS tfa_locked_until timestamptz,
|
||||
ADD COLUMN IF NOT EXISTS totp_locked boolean NOT NULL DEFAULT false;
|
||||
|
||||
CREATE TABLE openid_pending (
|
||||
state text PRIMARY KEY,
|
||||
realm text NOT NULL REFERENCES realms(name) ON DELETE CASCADE,
|
||||
redirect_url text NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1,30 @@
|
||||
-- Native vSphere inventory + sessions (independent of Proxmox resources).
|
||||
|
||||
CREATE TABLE vsphere_sessions (
|
||||
id text PRIMARY KEY,
|
||||
username text NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
expires_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_sessions_expires_idx ON vsphere_sessions (expires_at);
|
||||
|
||||
CREATE TABLE vsphere_objects (
|
||||
moid text PRIMARY KEY,
|
||||
type text NOT NULL,
|
||||
name text NOT NULL,
|
||||
parent_moid text REFERENCES vsphere_objects (moid) ON DELETE SET NULL,
|
||||
props jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_objects_type_idx ON vsphere_objects (type);
|
||||
CREATE INDEX vsphere_objects_parent_idx ON vsphere_objects (parent_moid);
|
||||
CREATE INDEX vsphere_objects_name_idx ON vsphere_objects (name);
|
||||
|
||||
CREATE TABLE vsphere_credentials (
|
||||
username text PRIMARY KEY,
|
||||
password_hash text NOT NULL,
|
||||
roles text[] NOT NULL DEFAULT '{Administrator}'
|
||||
);
|
||||
@@ -0,0 +1,87 @@
|
||||
-- Tasks, snapshots, tagging, content library, datastore files, roles.
|
||||
|
||||
CREATE TABLE vsphere_tasks (
|
||||
id text PRIMARY KEY,
|
||||
description text NOT NULL DEFAULT '',
|
||||
status text NOT NULL CHECK (status IN ('PENDING', 'RUNNING', 'SUCCEEDED', 'FAILED')),
|
||||
service text NOT NULL DEFAULT '',
|
||||
operation text NOT NULL DEFAULT '',
|
||||
result jsonb,
|
||||
error jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
completed_at timestamptz
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_tasks_status_idx ON vsphere_tasks (status);
|
||||
|
||||
CREATE TABLE vsphere_snapshots (
|
||||
id text PRIMARY KEY,
|
||||
vm_moid text NOT NULL REFERENCES vsphere_objects (moid) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
description text NOT NULL DEFAULT '',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
props jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_snapshots_vm_idx ON vsphere_snapshots (vm_moid);
|
||||
|
||||
CREATE TABLE vsphere_tag_categories (
|
||||
id text PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
description text NOT NULL DEFAULT '',
|
||||
cardinality text NOT NULL DEFAULT 'MULTIPLE',
|
||||
associable_types text[] NOT NULL DEFAULT '{}'
|
||||
);
|
||||
|
||||
CREATE TABLE vsphere_tags (
|
||||
id text PRIMARY KEY,
|
||||
category_id text NOT NULL REFERENCES vsphere_tag_categories (id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
description text NOT NULL DEFAULT '',
|
||||
UNIQUE (category_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE vsphere_tag_associations (
|
||||
tag_id text NOT NULL REFERENCES vsphere_tags (id) ON DELETE CASCADE,
|
||||
object_type text NOT NULL,
|
||||
object_id text NOT NULL,
|
||||
PRIMARY KEY (tag_id, object_type, object_id)
|
||||
);
|
||||
|
||||
CREATE TABLE vsphere_libraries (
|
||||
id text PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
description text NOT NULL DEFAULT '',
|
||||
type text NOT NULL DEFAULT 'LOCAL',
|
||||
props jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
CREATE TABLE vsphere_library_items (
|
||||
id text PRIMARY KEY,
|
||||
library_id text NOT NULL REFERENCES vsphere_libraries (id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
type text NOT NULL DEFAULT 'ovf',
|
||||
description text NOT NULL DEFAULT '',
|
||||
props jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
UNIQUE (library_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE vsphere_datastore_files (
|
||||
id bigserial PRIMARY KEY,
|
||||
datastore_moid text NOT NULL REFERENCES vsphere_objects (moid) ON DELETE CASCADE,
|
||||
path text NOT NULL,
|
||||
size bigint NOT NULL DEFAULT 0,
|
||||
type text NOT NULL DEFAULT 'FILE',
|
||||
UNIQUE (datastore_moid, path)
|
||||
);
|
||||
|
||||
CREATE TABLE vsphere_permissions (
|
||||
id bigserial PRIMARY KEY,
|
||||
principal text NOT NULL,
|
||||
role text NOT NULL,
|
||||
entity_moid text,
|
||||
propagate boolean NOT NULL DEFAULT true
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_permissions_principal_idx ON vsphere_permissions (principal);
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Keyed JSON state for Broadcom Automation API surface (DB-backed stubs).
|
||||
|
||||
CREATE TABLE vsphere_api_state (
|
||||
state_key text PRIMARY KEY,
|
||||
verb text NOT NULL,
|
||||
path_template text NOT NULL,
|
||||
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_api_state_path_idx ON vsphere_api_state (path_template);
|
||||
CREATE INDEX vsphere_api_state_verb_idx ON vsphere_api_state (verb);
|
||||
@@ -0,0 +1,30 @@
|
||||
-- Durable content-library transfer sessions and NFC leases (no process memory).
|
||||
|
||||
CREATE TABLE vsphere_transfer_sessions (
|
||||
id text NOT NULL,
|
||||
kind text NOT NULL CHECK (kind IN ('download', 'update')),
|
||||
library_item_id text NOT NULL REFERENCES vsphere_library_items (id) ON DELETE CASCADE,
|
||||
state text NOT NULL DEFAULT 'ACTIVE',
|
||||
files jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (id, kind)
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_transfer_sessions_item_idx ON vsphere_transfer_sessions (library_item_id);
|
||||
CREATE INDEX vsphere_transfer_sessions_kind_idx ON vsphere_transfer_sessions (kind);
|
||||
|
||||
CREATE TABLE vsphere_nfc_leases (
|
||||
id text PRIMARY KEY,
|
||||
vm_moid text NOT NULL,
|
||||
state text NOT NULL DEFAULT 'ready',
|
||||
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_nfc_leases_vm_idx ON vsphere_nfc_leases (vm_moid);
|
||||
|
||||
-- Keep original seed document so DELETE can restore without Python templates.
|
||||
ALTER TABLE vsphere_api_state
|
||||
ADD COLUMN IF NOT EXISTS seed_payload jsonb;
|
||||
@@ -0,0 +1,19 @@
|
||||
-- Durable SOAP PropertyCollector views / page tokens / WaitForUpdates versions.
|
||||
|
||||
CREATE TABLE vsphere_pc_state (
|
||||
kind text NOT NULL CHECK (kind IN ('view', 'token', 'version', 'meta')),
|
||||
key text NOT NULL,
|
||||
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (kind, key)
|
||||
);
|
||||
|
||||
CREATE INDEX vsphere_pc_state_kind_idx ON vsphere_pc_state (kind);
|
||||
|
||||
-- Ephemeral console tickets issued by REST/SOAP.
|
||||
CREATE TABLE vsphere_console_tickets (
|
||||
ticket text PRIMARY KEY,
|
||||
vm_moid text NOT NULL REFERENCES vsphere_objects (moid) ON DELETE CASCADE,
|
||||
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
Reference in New Issue
Block a user