diff --git a/migrate_missing_tables_20260427.sql b/migrate_missing_tables_20260427.sql new file mode 100644 index 0000000..bb1278a --- /dev/null +++ b/migrate_missing_tables_20260427.sql @@ -0,0 +1,577 @@ +-- Migration : ajout des 7 tables manquantes en local +-- (chassis, hypervisors, qualys_missing_servers, qualys_vuln_snapshot, +-- qualys_vuln_snapshot_run, secops_duty, server_databases) +-- DDL aligné sur prod CT 116 (PG 15.16) — idempotent + +-- 1. Extension requise (citext pour hostname case-insensitive) +CREATE EXTENSION IF NOT EXISTS citext; + +-- 2. Fonction trigger pour qualys_missing_servers +CREATE OR REPLACE FUNCTION public.qms_set_updated_at() +RETURNS trigger LANGUAGE plpgsql AS $function$ +BEGIN NEW.updated_at = now(); RETURN NEW; END; +$function$; + +-- 3. Tables (idempotent) +-- + +-- +-- Name: chassis; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE IF NOT EXISTS public.chassis ( + id integer NOT NULL, + hostname public.citext NOT NULL, + fqdn character varying(255), + site character varying(100), + domain_ltd character varying(50), + description text, + responsable_nom text, + moved_from_server_id integer, + created_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: chassis_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE IF NOT EXISTS public.chassis_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: chassis_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.chassis_id_seq OWNED BY public.chassis.id; + + +-- +-- Name: hypervisors; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE IF NOT EXISTS public.hypervisors ( + id integer NOT NULL, + hostname public.citext NOT NULL, + fqdn character varying(255), + cluster_name character varying(100), + underlying_server character varying(100), + site character varying(100), + domain_ltd character varying(50), + description text, + responsable_nom text, + moved_from_server_id integer, + created_at timestamp with time zone DEFAULT now(), + kind character varying(20) DEFAULT 'hypervisor'::character varying +); + + +-- +-- Name: hypervisors_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE IF NOT EXISTS public.hypervisors_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: hypervisors_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.hypervisors_id_seq OWNED BY public.hypervisors.id; + + +-- +-- Name: qualys_missing_servers; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE IF NOT EXISTS public.qualys_missing_servers ( + id integer NOT NULL, + hostname character varying(255) NOT NULL, + hostname_norm character varying(255) GENERATED ALWAYS AS (lower((hostname)::text)) STORED, + environnement character varying(50), + sources_present character varying(100), + in_cyberark boolean DEFAULT false, + in_sentinel boolean DEFAULT false, + in_itop boolean DEFAULT false, + server_id integer, + reason_category character varying(30), + reason_detail text, + status character varying(20) DEFAULT 'a_traiter'::character varying, + priority smallint DEFAULT 3, + notes text, + source_file character varying(100), + last_seen_at timestamp with time zone DEFAULT now(), + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now(), + CONSTRAINT qms_reason_check CHECK (((reason_category IS NULL) OR ((reason_category)::text = ANY (ARRAY[('appliance'::character varying)::text, ('ot_scada'::character varying)::text, ('virtualisation'::character varying)::text, ('embedded'::character varying)::text, ('oubli'::character varying)::text, ('decom'::character varying)::text, ('inconnu'::character varying)::text, ('other'::character varying)::text])))), + CONSTRAINT qms_status_check CHECK (((status)::text = ANY (ARRAY[('a_traiter'::character varying)::text, ('a_enroler'::character varying)::text, ('exempt'::character varying)::text, ('enrole'::character varying)::text, ('decom'::character varying)::text]))) +); + + +-- +-- Name: TABLE qualys_missing_servers; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON TABLE public.qualys_missing_servers IS 'Serveurs détectés ailleurs (CA/S1/iTop) mais absents de Qualys + raison'; + + +-- +-- Name: COLUMN qualys_missing_servers.reason_category; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.qualys_missing_servers.reason_category IS 'appliance, ot_scada, virtualisation (ESXi), embedded, oubli (à enrôler), decom, inconnu, other'; + + +-- +-- Name: COLUMN qualys_missing_servers.status; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.qualys_missing_servers.status IS 'a_traiter, a_enroler, exempt (légitimement hors Qualys), enrole (fait), decom'; + + +-- +-- Name: COLUMN qualys_missing_servers.priority; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.qualys_missing_servers.priority IS '1 urgent → 5 faible (auto-calc selon sources)'; + + +-- +-- Name: qualys_missing_servers_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE IF NOT EXISTS public.qualys_missing_servers_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: qualys_missing_servers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.qualys_missing_servers_id_seq OWNED BY public.qualys_missing_servers.id; + + +-- +-- Name: qualys_vuln_snapshot; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE IF NOT EXISTS public.qualys_vuln_snapshot ( + id integer NOT NULL, + run_id integer NOT NULL, + dimension character varying(20) NOT NULL, + dimension_value character varying(100), + dimension_value2 character varying(100), + total integer DEFAULT 0 NOT NULL, + critical integer DEFAULT 0 NOT NULL, + high integer DEFAULT 0 NOT NULL, + medium integer DEFAULT 0 NOT NULL, + sain integer DEFAULT 0 NOT NULL, + non_scanne integer DEFAULT 0 NOT NULL +); + + +-- +-- Name: qualys_vuln_snapshot_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE IF NOT EXISTS public.qualys_vuln_snapshot_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: qualys_vuln_snapshot_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.qualys_vuln_snapshot_id_seq OWNED BY public.qualys_vuln_snapshot.id; + + +-- +-- Name: qualys_vuln_snapshot_run; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE IF NOT EXISTS public.qualys_vuln_snapshot_run ( + id integer NOT NULL, + run_at timestamp with time zone DEFAULT now() NOT NULL, + status character varying(20) DEFAULT 'pending'::character varying NOT NULL, + asset_count integer DEFAULT 0 NOT NULL, + duration_sec integer DEFAULT 0 NOT NULL, + msg text, + triggered_by character varying(50) +); + + +-- +-- Name: qualys_vuln_snapshot_run_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE IF NOT EXISTS public.qualys_vuln_snapshot_run_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: qualys_vuln_snapshot_run_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.qualys_vuln_snapshot_run_id_seq OWNED BY public.qualys_vuln_snapshot_run.id; + + +-- +-- Name: secops_duty; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE IF NOT EXISTS public.secops_duty ( + id integer NOT NULL, + year smallint NOT NULL, + week_number smallint NOT NULL, + week_code character varying(5) NOT NULL, + week_start date, + week_end date, + absences text, + tdg_s1 character varying(50), + tdg_symantec character varying(50), + tdg_m365 character varying(50), + tdg_commvault character varying(50), + tdg_meteo character varying(50), + tdg_dmz character varying(50), + tdg_safenet character varying(50), + tdg_quarantaine character varying(50), + tdg_securisation character varying(50), + tdg_incident_majeur character varying(50), + tdg_incident_critique character varying(50), + emails_dest character varying(100), + created_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: TABLE secops_duty; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON TABLE public.secops_duty IS 'Tour de garde SecOps hebdomadaire (source: Tour de garde secops_2026.xlsx)'; + + +-- +-- Name: secops_duty_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE IF NOT EXISTS public.secops_duty_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: secops_duty_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.secops_duty_id_seq OWNED BY public.secops_duty.id; + + +-- +-- Name: server_databases; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE IF NOT EXISTS public.server_databases ( + id integer NOT NULL, + server_id integer, + hostname public.citext, + instance_name character varying(100), + db_type character varying(50), + db_version character varying(100), + db_edition character varying(50), + cluster_name character varying(100), + environnement character varying(50), + etat character varying(30), + description text, + created_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: server_databases_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE IF NOT EXISTS public.server_databases_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: server_databases_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.server_databases_id_seq OWNED BY public.server_databases.id; + + +-- +-- Name: chassis id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.chassis ALTER COLUMN id SET DEFAULT nextval('public.chassis_id_seq'::regclass); + + +-- +-- Name: hypervisors id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.hypervisors ALTER COLUMN id SET DEFAULT nextval('public.hypervisors_id_seq'::regclass); + + +-- +-- Name: qualys_missing_servers id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.qualys_missing_servers ALTER COLUMN id SET DEFAULT nextval('public.qualys_missing_servers_id_seq'::regclass); + + +-- +-- Name: qualys_vuln_snapshot id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.qualys_vuln_snapshot ALTER COLUMN id SET DEFAULT nextval('public.qualys_vuln_snapshot_id_seq'::regclass); + + +-- +-- Name: qualys_vuln_snapshot_run id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.qualys_vuln_snapshot_run ALTER COLUMN id SET DEFAULT nextval('public.qualys_vuln_snapshot_run_id_seq'::regclass); + + +-- +-- Name: secops_duty id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.secops_duty ALTER COLUMN id SET DEFAULT nextval('public.secops_duty_id_seq'::regclass); + + +-- +-- Name: server_databases id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.server_databases ALTER COLUMN id SET DEFAULT nextval('public.server_databases_id_seq'::regclass); + + +-- +-- Name: chassis chassis_hostname_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.chassis + ADD CONSTRAINT chassis_hostname_key UNIQUE (hostname); + + +-- +-- Name: chassis chassis_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.chassis + ADD CONSTRAINT chassis_pkey PRIMARY KEY (id); + + +-- +-- Name: hypervisors hypervisors_hostname_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.hypervisors + ADD CONSTRAINT hypervisors_hostname_key UNIQUE (hostname); + + +-- +-- Name: hypervisors hypervisors_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.hypervisors + ADD CONSTRAINT hypervisors_pkey PRIMARY KEY (id); + + +-- +-- Name: qualys_missing_servers qualys_missing_servers_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.qualys_missing_servers + ADD CONSTRAINT qualys_missing_servers_pkey PRIMARY KEY (id); + + +-- +-- Name: qualys_vuln_snapshot qualys_vuln_snapshot_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.qualys_vuln_snapshot + ADD CONSTRAINT qualys_vuln_snapshot_pkey PRIMARY KEY (id); + + +-- +-- Name: qualys_vuln_snapshot_run qualys_vuln_snapshot_run_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.qualys_vuln_snapshot_run + ADD CONSTRAINT qualys_vuln_snapshot_run_pkey PRIMARY KEY (id); + + +-- +-- Name: secops_duty secops_duty_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.secops_duty + ADD CONSTRAINT secops_duty_pkey PRIMARY KEY (id); + + +-- +-- Name: server_databases server_databases_hostname_instance_name_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.server_databases + ADD CONSTRAINT server_databases_hostname_instance_name_key UNIQUE (hostname, instance_name); + + +-- +-- Name: server_databases server_databases_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.server_databases + ADD CONSTRAINT server_databases_pkey PRIMARY KEY (id); + + +-- +-- Name: idx_srv_db_server; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS idx_srv_db_server ON public.server_databases USING btree (server_id); + + +-- +-- Name: idx_srv_db_type; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS idx_srv_db_type ON public.server_databases USING btree (db_type); + + +-- +-- Name: idx_vuln_run_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS idx_vuln_run_at ON public.qualys_vuln_snapshot_run USING btree (run_at DESC); + + +-- +-- Name: idx_vuln_snap_dim_val; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS idx_vuln_snap_dim_val ON public.qualys_vuln_snapshot USING btree (dimension, dimension_value); + + +-- +-- Name: idx_vuln_snap_run_dim; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS idx_vuln_snap_run_dim ON public.qualys_vuln_snapshot USING btree (run_id, dimension); + + +-- +-- Name: qms_hostname_norm_uniq; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX IF NOT EXISTS qms_hostname_norm_uniq ON public.qualys_missing_servers USING btree (hostname_norm); + + +-- +-- Name: qms_reason_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS qms_reason_idx ON public.qualys_missing_servers USING btree (reason_category); + + +-- +-- Name: qms_server_id_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS qms_server_id_idx ON public.qualys_missing_servers USING btree (server_id); + + +-- +-- Name: qms_status_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS qms_status_idx ON public.qualys_missing_servers USING btree (status); + + +-- +-- Name: secops_duty_week_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX IF NOT EXISTS secops_duty_week_idx ON public.secops_duty USING btree (year, week_number); + + +-- +-- Name: secops_duty_year_week_uniq; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX IF NOT EXISTS secops_duty_year_week_uniq ON public.secops_duty USING btree (year, week_number); + + +-- +-- Name: qualys_missing_servers qms_updated_at_trg; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER qms_updated_at_trg BEFORE UPDATE ON public.qualys_missing_servers FOR EACH ROW EXECUTE FUNCTION public.qms_set_updated_at(); + + +-- +-- Name: qualys_missing_servers qualys_missing_servers_server_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.qualys_missing_servers + ADD CONSTRAINT qualys_missing_servers_server_id_fkey FOREIGN KEY (server_id) REFERENCES public.servers(id) ON DELETE SET NULL; + + +-- +-- Name: qualys_vuln_snapshot qualys_vuln_snapshot_run_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.qualys_vuln_snapshot + ADD CONSTRAINT qualys_vuln_snapshot_run_id_fkey FOREIGN KEY (run_id) REFERENCES public.qualys_vuln_snapshot_run(id) ON DELETE CASCADE; + + +-- +-- Name: server_databases server_databases_server_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.server_databases + ADD CONSTRAINT server_databases_server_id_fkey FOREIGN KEY (server_id) REFERENCES public.servers(id) ON DELETE CASCADE; + + +--