Files
EvoFirewall/packages/db/migrations/002_policy_sets.sql
T
DenozordecandCursor 0bed4367c7
Build and Push EvoFirewall Docker Image / build-and-push (push) Successful in 1m44s
Build and Push EvoFirewall Docker Image / create-release (push) Skipped
feat(policy): именованные наборы правил с DNS и M:N привязкой к агентам
Правила живут в policy_sets; evaluate мержит назначенные наборы; источник list|CIDR|hostname с кэшем DNS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 22:11:03 +07:00

133 lines
3.7 KiB
SQL

-- Policy sets + DNS hostname rules (v2)
CREATE TABLE IF NOT EXISTS policy_sets (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
CHECK (enabled IN (0, 1)),
CHECK (length(trim(name)) > 0)
);
CREATE TABLE IF NOT EXISTS agent_policy_sets (
agent_id TEXT NOT NULL REFERENCES agents (id) ON DELETE CASCADE,
set_id TEXT NOT NULL REFERENCES policy_sets (id) ON DELETE CASCADE,
sort INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (agent_id, set_id)
);
CREATE INDEX IF NOT EXISTS idx_agent_policy_sets_set ON agent_policy_sets (set_id);
-- Rebuild policy_rules with set_id + hostname (drop agent_id)
CREATE TABLE IF NOT EXISTS policy_rules_v2 (
id TEXT PRIMARY KEY,
set_id TEXT NOT NULL REFERENCES policy_sets (id) ON DELETE CASCADE,
priority INTEGER NOT NULL,
action TEXT NOT NULL,
list_id TEXT REFERENCES ip_lists (id) ON DELETE CASCADE,
cidr TEXT,
hostname TEXT,
comment TEXT,
created_by_user_id TEXT,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
CHECK (action IN ('allow', 'deny')),
CHECK (priority >= 1 AND priority <= 10000)
);
-- Shared default set
INSERT OR IGNORE INTO policy_sets (id, name, description, enabled)
VALUES (
'set-shared-default',
'Общие',
'Набор по умолчанию (бывшие tenant-правила). Назначается approved-агентам.',
1
);
-- Per-agent sets for agents that already have rules
INSERT OR IGNORE INTO policy_sets (id, name, description, enabled)
SELECT
'set-agent-' || a.id,
'Агент: ' || a.name,
'Мигрировано из правил агента',
1
FROM agents a
WHERE EXISTS (
SELECT 1 FROM policy_rules r WHERE r.agent_id = a.id
);
-- Copy tenant rules → Общие
INSERT INTO policy_rules_v2 (
id, set_id, priority, action, list_id, cidr, hostname, comment,
created_by_user_id, created_at, updated_at
)
SELECT
id,
'set-shared-default',
priority,
action,
list_id,
cidr,
NULL,
comment,
created_by_user_id,
created_at,
updated_at
FROM policy_rules
WHERE agent_id IS NULL;
-- Copy agent rules → per-agent sets
INSERT INTO policy_rules_v2 (
id, set_id, priority, action, list_id, cidr, hostname, comment,
created_by_user_id, created_at, updated_at
)
SELECT
id,
'set-agent-' || agent_id,
priority,
action,
list_id,
cidr,
NULL,
comment,
created_by_user_id,
created_at,
updated_at
FROM policy_rules
WHERE agent_id IS NOT NULL;
DROP TABLE policy_rules;
ALTER TABLE policy_rules_v2 RENAME TO policy_rules;
CREATE UNIQUE INDEX IF NOT EXISTS idx_policy_rules_set_priority
ON policy_rules (set_id, priority);
-- Assign «Общие» to all approved agents
INSERT OR IGNORE INTO agent_policy_sets (agent_id, set_id, sort)
SELECT id, 'set-shared-default', 0
FROM agents
WHERE status = 'approved';
-- Assign per-agent migrated sets
INSERT OR IGNORE INTO agent_policy_sets (agent_id, set_id, sort)
SELECT
substr(id, length('set-agent-') + 1),
id,
10
FROM policy_sets
WHERE id LIKE 'set-agent-%';
CREATE TABLE IF NOT EXISTS policy_rule_resolved (
id TEXT PRIMARY KEY,
rule_id TEXT NOT NULL REFERENCES policy_rules (id) ON DELETE CASCADE,
cidr TEXT NOT NULL,
resolved_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_policy_rule_resolved_rule_cidr
ON policy_rule_resolved (rule_id, cidr);
CREATE INDEX IF NOT EXISTS idx_policy_rule_resolved_rule
ON policy_rule_resolved (rule_id);