diff --git a/Makefile b/Makefile index 1316faff..a3a1e1d2 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,10 @@ test-migrate: $(TOOLS_DIR)/migrate test-database-integration: ./utils/run_integration_tests.sh +.PHONY: update-database-schema-docs +update-database-schema-docs: + ./utils/update_schema_doc.sh + .PHONY: verify verify: verify-go-lint diff --git a/README.md b/README.md index 108457ed..6d7c2e78 100644 --- a/README.md +++ b/README.md @@ -99,11 +99,25 @@ compliance service and a PostgreSQL database into a Kubernetes cluster. $ make deploy ``` -## Migrations +## Database + +### Migrations Please refer to the [migrations documentation](./migrations/README.md) for instructions on creating and managing database migrations. +### Schema + +The [schema](./migrations/schema.sql) for the service is documented alongside +the migrations. This schema is rendered after the database is fully updated. +Its goal is to reflect schema in its entirety. + +You can render the schema using: + +```console +$ make update-database-schema-docs +``` + ## gRPC API This API is marked as **EXPERIMENTAL** and may change in backwards incompatible diff --git a/migrations/schema.sql b/migrations/schema.sql new file mode 100644 index 00000000..9d52d492 --- /dev/null +++ b/migrations/schema.sql @@ -0,0 +1,303 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 14.4 (Debian 14.4-1.pgdg110+1) +-- Dumped by pg_dump version 14.4 (Debian 14.4-1.pgdg110+1) + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: assessments; Type: TABLE; Schema: public; Owner: dbadmin +-- + +CREATE TABLE public.assessments ( + id uuid NOT NULL, + name character varying(255), + metadata_id uuid +); + + +ALTER TABLE public.assessments OWNER TO dbadmin; + +-- +-- Name: catalogs; Type: TABLE; Schema: public; Owner: dbadmin +-- + +CREATE TABLE public.catalogs ( + id uuid NOT NULL, + name character varying(255), + metadata_id uuid, + content text +); + + +ALTER TABLE public.catalogs OWNER TO dbadmin; + +-- +-- Name: controls; Type: TABLE; Schema: public; Owner: dbadmin +-- + +CREATE TABLE public.controls ( + id uuid NOT NULL, + name character varying(255), + severity character varying(50), + profile_id uuid, + metadata_id uuid +); + + +ALTER TABLE public.controls OWNER TO dbadmin; + +-- +-- Name: metadata; Type: TABLE; Schema: public; Owner: dbadmin +-- + +CREATE TABLE public.metadata ( + id uuid NOT NULL, + created_at timestamp without time zone, + updated_at timestamp without time zone, + version character varying(50), + description text +); + + +ALTER TABLE public.metadata OWNER TO dbadmin; + +-- +-- Name: profiles; Type: TABLE; Schema: public; Owner: dbadmin +-- + +CREATE TABLE public.profiles ( + id uuid NOT NULL, + name character varying(255), + metadata_id uuid, + catalog_id uuid +); + + +ALTER TABLE public.profiles OWNER TO dbadmin; + +-- +-- Name: results; Type: TABLE; Schema: public; Owner: dbadmin +-- + +CREATE TABLE public.results ( + id uuid NOT NULL, + name character varying(255), + outcome character varying(255), + instruction text, + rationale text, + control_id uuid, + metadata_id uuid, + subject_id uuid, + assessment_id uuid +); + + +ALTER TABLE public.results OWNER TO dbadmin; + +-- +-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: dbadmin +-- + +CREATE TABLE public.schema_migrations ( + version bigint NOT NULL, + dirty boolean NOT NULL +); + + +ALTER TABLE public.schema_migrations OWNER TO dbadmin; + +-- +-- Name: subjects; Type: TABLE; Schema: public; Owner: dbadmin +-- + +CREATE TABLE public.subjects ( + id uuid NOT NULL, + name character varying(255), + type character varying(50), + parent_id uuid, + metadata_id uuid +); + + +ALTER TABLE public.subjects OWNER TO dbadmin; + +-- +-- Name: assessments assessments_pkey; Type: CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.assessments + ADD CONSTRAINT assessments_pkey PRIMARY KEY (id); + + +-- +-- Name: catalogs catalogs_pkey; Type: CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.catalogs + ADD CONSTRAINT catalogs_pkey PRIMARY KEY (id); + + +-- +-- Name: controls controls_pkey; Type: CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.controls + ADD CONSTRAINT controls_pkey PRIMARY KEY (id); + + +-- +-- Name: metadata metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.metadata + ADD CONSTRAINT metadata_pkey PRIMARY KEY (id); + + +-- +-- Name: profiles profiles_pkey; Type: CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.profiles + ADD CONSTRAINT profiles_pkey PRIMARY KEY (id); + + +-- +-- Name: results results_pkey; Type: CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.results + ADD CONSTRAINT results_pkey PRIMARY KEY (id); + + +-- +-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.schema_migrations + ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); + + +-- +-- Name: subjects subjects_pkey; Type: CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.subjects + ADD CONSTRAINT subjects_pkey PRIMARY KEY (id); + + +-- +-- Name: assessments fk_assessments_metadata_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.assessments + ADD CONSTRAINT fk_assessments_metadata_id FOREIGN KEY (metadata_id) REFERENCES public.metadata(id); + + +-- +-- Name: catalogs fk_catalogs_metadata_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.catalogs + ADD CONSTRAINT fk_catalogs_metadata_id FOREIGN KEY (metadata_id) REFERENCES public.metadata(id); + + +-- +-- Name: controls fk_controls_metadata_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.controls + ADD CONSTRAINT fk_controls_metadata_id FOREIGN KEY (metadata_id) REFERENCES public.metadata(id); + + +-- +-- Name: controls fk_controls_profile_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.controls + ADD CONSTRAINT fk_controls_profile_id FOREIGN KEY (profile_id) REFERENCES public.profiles(id); + + +-- +-- Name: profiles fk_profiles_catalog_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.profiles + ADD CONSTRAINT fk_profiles_catalog_id FOREIGN KEY (catalog_id) REFERENCES public.catalogs(id); + + +-- +-- Name: profiles fk_profiles_metadata_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.profiles + ADD CONSTRAINT fk_profiles_metadata_id FOREIGN KEY (metadata_id) REFERENCES public.metadata(id); + + +-- +-- Name: results fk_results_assessment_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.results + ADD CONSTRAINT fk_results_assessment_id FOREIGN KEY (assessment_id) REFERENCES public.assessments(id); + + +-- +-- Name: results fk_results_control_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.results + ADD CONSTRAINT fk_results_control_id FOREIGN KEY (control_id) REFERENCES public.controls(id); + + +-- +-- Name: results fk_results_metadata_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.results + ADD CONSTRAINT fk_results_metadata_id FOREIGN KEY (metadata_id) REFERENCES public.metadata(id); + + +-- +-- Name: results fk_results_subject_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.results + ADD CONSTRAINT fk_results_subject_id FOREIGN KEY (subject_id) REFERENCES public.subjects(id); + + +-- +-- Name: subjects fk_subjects_metadata_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.subjects + ADD CONSTRAINT fk_subjects_metadata_id FOREIGN KEY (metadata_id) REFERENCES public.metadata(id); + + +-- +-- Name: subjects fk_subjects_parent_id; Type: FK CONSTRAINT; Schema: public; Owner: dbadmin +-- + +ALTER TABLE ONLY public.subjects + ADD CONSTRAINT fk_subjects_parent_id FOREIGN KEY (parent_id) REFERENCES public.subjects(id); + + +-- +-- PostgreSQL database dump complete +-- + diff --git a/utils/update_schema_doc.sh b/utils/update_schema_doc.sh new file mode 100755 index 00000000..200f86f9 --- /dev/null +++ b/utils/update_schema_doc.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# This script updates the database schema documentation. This script should be +# invoked each time the schema is changed. + +UTILS_DIR=$(cd "$(dirname "${BASH_SOURCE:-$0}")" && pwd) +TOP_DIR=$(dirname "$UTILS_DIR") +# shellcheck source=utils/functions.sh +source "${UTILS_DIR}/functions.sh" + +set_container_runtime +set_database_environment_variables +trap cleanup_database_container EXIT +create_database_container +wait_for_db_init + + +POSTGRESQL_URL="postgres://$DB_USER:$DB_PASSWORD@$DB_HOST/$DB_NAME?sslmode=disable" +"$TOP_DIR/tools/migrate" -database "$POSTGRESQL_URL" -path "$TOP_DIR/migrations" up +podman exec -it postgres pg_dump --username dbadmin --schema-only compliance > "${TOP_DIR}/migrations/schema.sql"