126 lines
6.0 KiB
SQL
126 lines
6.0 KiB
SQL
CREATE TABLE IF NOT EXISTS vpn_connections (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
|
|
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
target_endpoint JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
protocol_family TEXT NOT NULL DEFAULT 'generic',
|
|
credential_ref TEXT,
|
|
mode TEXT NOT NULL DEFAULT 'single_active',
|
|
desired_state TEXT NOT NULL DEFAULT 'disabled',
|
|
allowed_node_policy JSONB NOT NULL DEFAULT '{"mode":"explicit","node_ids":[]}'::JSONB,
|
|
routing_usage JSONB NOT NULL DEFAULT '[]'::JSONB,
|
|
route_policy JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
qos_policy JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
placement_policy JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
status TEXT NOT NULL DEFAULT 'disabled',
|
|
metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
updated_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT vpn_connections_mode_check
|
|
CHECK (mode IN ('single_active')),
|
|
CONSTRAINT vpn_connections_desired_state_check
|
|
CHECK (desired_state IN ('enabled', 'disabled')),
|
|
CONSTRAINT vpn_connections_status_check
|
|
CHECK (status IN ('disabled', 'enabled', 'connecting', 'active', 'degraded', 'failed')),
|
|
CONSTRAINT vpn_connections_protocol_family_check
|
|
CHECK (protocol_family IN ('generic', 'wireguard', 'ipsec', 'openvpn'))
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_vpn_connections_cluster_org_name
|
|
ON vpn_connections(cluster_id, organization_id, lower(name));
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_vpn_connections_cluster_org_state
|
|
ON vpn_connections(cluster_id, organization_id, desired_state, status);
|
|
|
|
CREATE TABLE IF NOT EXISTS vpn_connection_allowed_nodes (
|
|
vpn_connection_id UUID NOT NULL REFERENCES vpn_connections(id) ON DELETE CASCADE,
|
|
cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
|
|
node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
|
|
role_preference TEXT NOT NULL DEFAULT 'candidate',
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
PRIMARY KEY (vpn_connection_id, node_id),
|
|
CONSTRAINT vpn_connection_allowed_nodes_membership_fk
|
|
FOREIGN KEY (cluster_id, node_id)
|
|
REFERENCES cluster_memberships(cluster_id, node_id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vpn_connection_allowed_nodes_preference_check
|
|
CHECK (role_preference IN ('candidate', 'standby', 'preferred')),
|
|
CONSTRAINT vpn_connection_allowed_nodes_status_check
|
|
CHECK (status IN ('active', 'disabled'))
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_vpn_connection_allowed_nodes_cluster_node
|
|
ON vpn_connection_allowed_nodes(cluster_id, node_id, status);
|
|
|
|
CREATE TABLE IF NOT EXISTS vpn_connection_route_policies (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
vpn_connection_id UUID NOT NULL REFERENCES vpn_connections(id) ON DELETE CASCADE,
|
|
cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
|
|
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
route_type TEXT NOT NULL,
|
|
destination TEXT NOT NULL,
|
|
action TEXT NOT NULL DEFAULT 'allow',
|
|
service_type TEXT,
|
|
priority INTEGER NOT NULL DEFAULT 100,
|
|
policy JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT vpn_connection_route_policies_route_type_check
|
|
CHECK (route_type IN ('cidr', 'dns_suffix', 'service', 'resource')),
|
|
CONSTRAINT vpn_connection_route_policies_action_check
|
|
CHECK (action IN ('allow', 'deny')),
|
|
CONSTRAINT vpn_connection_route_policies_status_check
|
|
CHECK (status IN ('active', 'disabled'))
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_vpn_connection_route_policies_connection
|
|
ON vpn_connection_route_policies(vpn_connection_id, status, priority);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_vpn_connection_route_policies_cluster_org
|
|
ON vpn_connection_route_policies(cluster_id, organization_id, route_type, status);
|
|
|
|
CREATE TABLE IF NOT EXISTS vpn_connection_leases (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
vpn_connection_id UUID NOT NULL REFERENCES vpn_connections(id) ON DELETE CASCADE,
|
|
cluster_id UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
|
|
owner_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
|
|
lease_generation BIGINT NOT NULL,
|
|
fencing_token TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
acquired_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
renewed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
released_at TIMESTAMPTZ,
|
|
fenced_at TIMESTAMPTZ,
|
|
metadata JSONB NOT NULL DEFAULT '{}'::JSONB,
|
|
CONSTRAINT vpn_connection_leases_membership_fk
|
|
FOREIGN KEY (cluster_id, owner_node_id)
|
|
REFERENCES cluster_memberships(cluster_id, node_id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vpn_connection_leases_status_check
|
|
CHECK (status IN ('active', 'released', 'expired', 'fenced')),
|
|
CONSTRAINT vpn_connection_leases_expiry_check
|
|
CHECK (expires_at > acquired_at)
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_vpn_connection_leases_generation
|
|
ON vpn_connection_leases(vpn_connection_id, lease_generation);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_vpn_connection_leases_single_active
|
|
ON vpn_connection_leases(vpn_connection_id)
|
|
WHERE status = 'active';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_vpn_connection_leases_owner
|
|
ON vpn_connection_leases(cluster_id, owner_node_id, status, expires_at);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_vpn_connection_leases_connection_time
|
|
ON vpn_connection_leases(vpn_connection_id, acquired_at DESC);
|