-- +goose Up -- +goose StatementBegin -- Unbound zones. zone_type 'local' = local-data records served -- authoritatively (e.g. eg.cluster). 'forward' = stub-zone forwarded -- to a specific upstream. The eg.cluster zone is auto-managed by -- internal/cluster; user-defined zones land here too. CREATE TABLE IF NOT EXISTS dns_zones ( id BIGSERIAL PRIMARY KEY, name TEXT NOT NULL, zone_type TEXT NOT NULL DEFAULT 'local', description TEXT, managed_by TEXT NOT NULL DEFAULT 'user', active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT dns_zones_name_unique UNIQUE (name), CONSTRAINT dns_zones_type_check CHECK (zone_type IN ('local', 'forward')) ); -- DNS records. record_type matches RFC 1035 / RFC 3596 mnemonics -- (A, AAAA, CNAME, TXT, MX, SRV, ...). value is the record's RDATA in -- text form (priority + value for MX/SRV are concatenated, e.g. -- "10 mail.example.com"). CREATE TABLE IF NOT EXISTS dns_records ( id BIGSERIAL PRIMARY KEY, zone_id BIGINT NOT NULL REFERENCES dns_zones(id) ON DELETE CASCADE, name TEXT NOT NULL, record_type TEXT NOT NULL, value TEXT NOT NULL, ttl INTEGER NOT NULL DEFAULT 300, active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT dns_records_type_check CHECK (record_type IN ('A', 'AAAA', 'CNAME', 'TXT', 'MX', 'SRV', 'NS', 'PTR', 'CAA')) ); CREATE INDEX IF NOT EXISTS idx_dns_records_zone ON dns_records (zone_id); CREATE INDEX IF NOT EXISTS idx_dns_records_active ON dns_records (active) WHERE active; -- +goose StatementEnd -- +goose Down -- +goose StatementBegin DROP TABLE IF EXISTS dns_records; DROP TABLE IF EXISTS dns_zones; -- +goose StatementEnd