Initial commit: stateful OpenStack API laboratory simulator.
Ship Keystone auth, multi-service handlers (Yoga→Dalmatian), Compose/Helm packaging, API contract packs, and pytest/Pulumi coverage labs.
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,137 @@
|
||||
-- OpenStack identity + core IaaS tables (iteration 2).
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_domains (
|
||||
id uuid PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
description text NOT NULL DEFAULT '',
|
||||
enabled boolean NOT NULL DEFAULT true
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_projects (
|
||||
id uuid PRIMARY KEY,
|
||||
domain_id uuid NOT NULL REFERENCES os_domains(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
description text NOT NULL DEFAULT '',
|
||||
enabled boolean NOT NULL DEFAULT true,
|
||||
UNIQUE (domain_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_users (
|
||||
id uuid PRIMARY KEY,
|
||||
domain_id uuid NOT NULL REFERENCES os_domains(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
password_hash text NOT NULL,
|
||||
enabled boolean NOT NULL DEFAULT true,
|
||||
UNIQUE (domain_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_roles (
|
||||
id uuid PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_role_assignments (
|
||||
id uuid PRIMARY KEY,
|
||||
role_id uuid NOT NULL REFERENCES os_roles(id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES os_users(id) ON DELETE CASCADE,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
UNIQUE (role_id, user_id, project_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_tokens (
|
||||
id text PRIMARY KEY,
|
||||
user_id uuid NOT NULL REFERENCES os_users(id) ON DELETE CASCADE,
|
||||
project_id uuid REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
expires_at timestamptz NOT NULL,
|
||||
issued_at timestamptz NOT NULL DEFAULT now(),
|
||||
revoked boolean NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS os_tokens_user_idx ON os_tokens(user_id);
|
||||
CREATE INDEX IF NOT EXISTS os_tokens_expires_idx ON os_tokens(expires_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_flavors (
|
||||
id text PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
vcpus integer NOT NULL,
|
||||
ram integer NOT NULL,
|
||||
disk integer NOT NULL,
|
||||
is_public boolean NOT NULL DEFAULT true
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_images (
|
||||
id uuid PRIMARY KEY,
|
||||
name text NOT NULL,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
visibility text NOT NULL DEFAULT 'public',
|
||||
size bigint NOT NULL DEFAULT 0,
|
||||
disk_format text NOT NULL DEFAULT 'qcow2',
|
||||
container_format text NOT NULL DEFAULT 'bare',
|
||||
owner_project_id uuid REFERENCES os_projects(id) ON DELETE SET NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_networks (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
status text NOT NULL DEFAULT 'ACTIVE',
|
||||
shared boolean NOT NULL DEFAULT false,
|
||||
admin_state_up boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_subnets (
|
||||
id uuid PRIMARY KEY,
|
||||
network_id uuid NOT NULL REFERENCES os_networks(id) ON DELETE CASCADE,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL DEFAULT '',
|
||||
cidr text NOT NULL,
|
||||
ip_version integer NOT NULL DEFAULT 4,
|
||||
gateway_ip text,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_ports (
|
||||
id uuid PRIMARY KEY,
|
||||
network_id uuid NOT NULL REFERENCES os_networks(id) ON DELETE CASCADE,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL DEFAULT '',
|
||||
status text NOT NULL DEFAULT 'ACTIVE',
|
||||
mac_address text NOT NULL,
|
||||
device_id text NOT NULL DEFAULT '',
|
||||
device_owner text NOT NULL DEFAULT '',
|
||||
fixed_ips jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_volumes (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL DEFAULT '',
|
||||
status text NOT NULL DEFAULT 'available',
|
||||
size integer NOT NULL,
|
||||
volume_type text NOT NULL DEFAULT 'lvmdriver-1',
|
||||
bootable boolean NOT NULL DEFAULT false,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_servers (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES os_users(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
status text NOT NULL DEFAULT 'ACTIVE',
|
||||
flavor_id text NOT NULL REFERENCES os_flavors(id),
|
||||
image_id uuid REFERENCES os_images(id) ON DELETE SET NULL,
|
||||
addresses jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS os_servers_project_idx ON os_servers(project_id);
|
||||
CREATE INDEX IF NOT EXISTS os_networks_project_idx ON os_networks(project_id);
|
||||
CREATE INDEX IF NOT EXISTS os_volumes_project_idx ON os_volumes(project_id);
|
||||
@@ -0,0 +1,142 @@
|
||||
-- Generic OpenStack object store + service-specific extras for full lab surface.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_api_objects (
|
||||
id uuid PRIMARY KEY,
|
||||
service text NOT NULL,
|
||||
resource_type text NOT NULL,
|
||||
project_id uuid REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL DEFAULT '',
|
||||
status text NOT NULL DEFAULT 'ACTIVE',
|
||||
data jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS os_api_objects_lookup_idx
|
||||
ON os_api_objects(service, resource_type, project_id);
|
||||
CREATE INDEX IF NOT EXISTS os_api_objects_name_idx
|
||||
ON os_api_objects(service, resource_type, name);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_keypairs (
|
||||
name text NOT NULL,
|
||||
user_id uuid NOT NULL REFERENCES os_users(id) ON DELETE CASCADE,
|
||||
fingerprint text NOT NULL,
|
||||
public_key text NOT NULL,
|
||||
type text NOT NULL DEFAULT 'ssh',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (user_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_security_groups (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
description text NOT NULL DEFAULT '',
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_security_group_rules (
|
||||
id uuid PRIMARY KEY,
|
||||
security_group_id uuid NOT NULL REFERENCES os_security_groups(id) ON DELETE CASCADE,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
direction text NOT NULL DEFAULT 'ingress',
|
||||
ethertype text NOT NULL DEFAULT 'IPv4',
|
||||
protocol text,
|
||||
port_range_min integer,
|
||||
port_range_max integer,
|
||||
remote_ip_prefix text,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_routers (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
status text NOT NULL DEFAULT 'ACTIVE',
|
||||
admin_state_up boolean NOT NULL DEFAULT true,
|
||||
external_gateway_info jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_floating_ips (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
floating_ip_address text NOT NULL,
|
||||
floating_network_id uuid,
|
||||
port_id uuid,
|
||||
fixed_ip_address text,
|
||||
router_id uuid,
|
||||
status text NOT NULL DEFAULT 'DOWN',
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_server_groups (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
policies jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
members jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_stacks (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
stack_name text NOT NULL,
|
||||
stack_status text NOT NULL DEFAULT 'CREATE_COMPLETE',
|
||||
description text NOT NULL DEFAULT '',
|
||||
template jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
parameters jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
outputs jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_swift_objects (
|
||||
id uuid PRIMARY KEY,
|
||||
account text NOT NULL,
|
||||
container text NOT NULL,
|
||||
name text NOT NULL,
|
||||
content_type text NOT NULL DEFAULT 'application/octet-stream',
|
||||
bytes integer NOT NULL DEFAULT 0,
|
||||
body bytea,
|
||||
meta jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (account, container, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_swift_containers (
|
||||
account text NOT NULL,
|
||||
name text NOT NULL,
|
||||
meta jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (account, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_nodes (
|
||||
id uuid PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
driver text NOT NULL DEFAULT 'ipmi',
|
||||
provision_state text NOT NULL DEFAULT 'available',
|
||||
power_state text NOT NULL DEFAULT 'power on',
|
||||
resource_class text NOT NULL DEFAULT 'baremetal',
|
||||
properties jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
driver_info jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
ports jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_loadbalancers (
|
||||
id uuid PRIMARY KEY,
|
||||
project_id uuid NOT NULL REFERENCES os_projects(id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
description text NOT NULL DEFAULT '',
|
||||
vip_address text,
|
||||
vip_subnet_id uuid,
|
||||
provisioning_status text NOT NULL DEFAULT 'ACTIVE',
|
||||
operating_status text NOT NULL DEFAULT 'ONLINE',
|
||||
listeners jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
pools jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1,56 @@
|
||||
-- Topology tables for demo cloud + marker for loaded profile.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_availability_zones (
|
||||
name text PRIMARY KEY,
|
||||
zone_state jsonb NOT NULL DEFAULT '{"available": true}'::jsonb
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_hypervisors (
|
||||
id integer PRIMARY KEY,
|
||||
hypervisor_hostname text NOT NULL UNIQUE,
|
||||
state text NOT NULL DEFAULT 'up',
|
||||
status text NOT NULL DEFAULT 'enabled',
|
||||
hypervisor_type text NOT NULL DEFAULT 'QEMU',
|
||||
hypervisor_version integer NOT NULL DEFAULT 201000,
|
||||
host_ip text,
|
||||
vcpus integer NOT NULL DEFAULT 64,
|
||||
vcpus_used integer NOT NULL DEFAULT 0,
|
||||
memory_mb integer NOT NULL DEFAULT 262144,
|
||||
memory_mb_used integer NOT NULL DEFAULT 0,
|
||||
local_gb integer NOT NULL DEFAULT 2000,
|
||||
local_gb_used integer NOT NULL DEFAULT 0,
|
||||
running_vms integer NOT NULL DEFAULT 0,
|
||||
service_host text,
|
||||
availability_zone text REFERENCES os_availability_zones(name),
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_aggregates (
|
||||
id integer PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE,
|
||||
availability_zone text,
|
||||
hosts jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_compute_services (
|
||||
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
"binary" text NOT NULL,
|
||||
host text NOT NULL,
|
||||
zone text,
|
||||
status text NOT NULL DEFAULT 'enabled',
|
||||
state text NOT NULL DEFAULT 'up',
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS os_demo_meta (
|
||||
key text PRIMARY KEY,
|
||||
value text NOT NULL,
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- Extra columns for richer server/volume demo metadata (idempotent).
|
||||
ALTER TABLE os_servers ADD COLUMN IF NOT EXISTS availability_zone text;
|
||||
ALTER TABLE os_servers ADD COLUMN IF NOT EXISTS host text;
|
||||
ALTER TABLE os_volumes ADD COLUMN IF NOT EXISTS description text NOT NULL DEFAULT '';
|
||||
Reference in New Issue
Block a user