diff --git a/database_admin/migrations/154_account_advisory.down.sql b/database_admin/migrations/154_account_advisory.down.sql new file mode 100644 index 000000000..d2de54398 --- /dev/null +++ b/database_admin/migrations/154_account_advisory.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS account_advisory; diff --git a/database_admin/migrations/154_account_advisory.up.sql b/database_admin/migrations/154_account_advisory.up.sql new file mode 100644 index 000000000..6ebb081dd --- /dev/null +++ b/database_admin/migrations/154_account_advisory.up.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS account_advisory +( + advisory_id BIGINT NOT NULL, + rh_account_id INT NOT NULL, + workspace_id UUID NOT NULL, + systems_applicable INT NOT NULL DEFAULT 0, + systems_installable INT NOT NULL DEFAULT 0, + notified TIMESTAMP WITH TIME ZONE NULL, + CONSTRAINT account_advisory_advisory_id + FOREIGN KEY (advisory_id) + REFERENCES advisory_metadata (id), + CONSTRAINT account_advisory_rh_account_id + FOREIGN KEY (rh_account_id) + REFERENCES rh_account (id), + PRIMARY KEY (rh_account_id, workspace_id, advisory_id) +) PARTITION BY HASH (rh_account_id); + +SELECT create_table_partitions('account_advisory', 32, + $$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05') + TABLESPACE pg_default$$); + +SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'manager'); +SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'evaluator'); +SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'listener'); +SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'vmaas_sync'); diff --git a/database_admin/schema/create_schema.sql b/database_admin/schema/create_schema.sql index 068cbbcc5..3baba9dbb 100644 --- a/database_admin/schema/create_schema.sql +++ b/database_admin/schema/create_schema.sql @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS schema_migrations INSERT INTO schema_migrations -VALUES (153, false); +VALUES (154, false); -- --------------------------------------------------------------------------- -- Functions @@ -783,6 +783,33 @@ GRANT SELECT, INSERT, UPDATE, DELETE ON advisory_account_data TO vmaas_sync; CREATE INDEX ON advisory_account_data (systems_applicable); CREATE INDEX ON advisory_account_data (systems_installable); +-- account_advisory +CREATE TABLE IF NOT EXISTS account_advisory +( + advisory_id BIGINT NOT NULL, + rh_account_id INT NOT NULL, + workspace_id UUID NOT NULL, + systems_applicable INT NOT NULL DEFAULT 0, + systems_installable INT NOT NULL DEFAULT 0, + notified TIMESTAMP WITH TIME ZONE NULL, + CONSTRAINT account_advisory_advisory_id + FOREIGN KEY (advisory_id) + REFERENCES advisory_metadata (id), + CONSTRAINT account_advisory_rh_account_id + FOREIGN KEY (rh_account_id) + REFERENCES rh_account (id), + PRIMARY KEY (rh_account_id, workspace_id, advisory_id) +) PARTITION BY HASH (rh_account_id); + +SELECT create_table_partitions('account_advisory', 32, + $$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05') + TABLESPACE pg_default$$); + +SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'manager'); +SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'evaluator'); +SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'listener'); +SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'account_advisory', 'vmaas_sync'); + -- repo CREATE TABLE IF NOT EXISTS repo ( diff --git a/dev/test_data.sql b/dev/test_data.sql index 386e7d17a..7987baaa2 100644 --- a/dev/test_data.sql +++ b/dev/test_data.sql @@ -7,6 +7,7 @@ DELETE FROM deleted_system; DELETE FROM repo; DELETE FROM timestamp_kv; DELETE FROM advisory_account_data; +DELETE FROM account_advisory; DELETE FROM package_account_data; DELETE FROM package; DELETE FROM package_name; diff --git a/docs/md/database.md b/docs/md/database.md index 25e3d9e4c..fa191a700 100644 --- a/docs/md/database.md +++ b/docs/md/database.md @@ -7,6 +7,7 @@ Main database tables description: - **advisory_metadata** - stores info about advisories (`description`, `summary`, `solution` etc.). It's synced and stored on trigger by `vmaas_sync` component. It allows to display detail information about the advisory. - **system_advisories** - stores info about advisories evaluated for particular systems (system - advisory M-N mapping table). `system_id` references **system_inventory.id**. Contains info when system advisory was firstly reported and patched (if so). Records are created and updated by `evaluator` component. It allows to display list of advisories related to a system. - **advisory_account_data** - stores info about all advisories detected within at least one system that belongs to a given account. So it provides overall statistics about system advisories displayed by the application. +- **account_advisory** - workspace-scoped version of `advisory_account_data`. Stores per-advisory aggregate counts (`systems_applicable`, `systems_installable`) and notification state for each workspace within an account. Keyed by `(rh_account_id, workspace_id, advisory_id)`, partitioned by `rh_account_id` (32 partitions). - **package_name** - names of the packages installed on systems - **package** - list of all packages versions, precisely all EVRAs (epoch-version-release-arch) - **system_package2** - list of packages installed on a system diff --git a/tasks/vmaas_sync/metrics_db_test.go b/tasks/vmaas_sync/metrics_db_test.go index f1437f974..2566436a0 100644 --- a/tasks/vmaas_sync/metrics_db_test.go +++ b/tasks/vmaas_sync/metrics_db_test.go @@ -17,12 +17,13 @@ func TestTableSizes(t *testing.T) { for _, item := range tableSizes { uniqueTables[item.Key] = true } - assert.Equal(t, 230, len(tableSizes)) - assert.Equal(t, 230, len(uniqueTables)) + assert.Equal(t, 263, len(tableSizes)) + assert.Equal(t, 263, len(uniqueTables)) assert.True(t, uniqueTables["public.system_inventory"]) // check whether table names were loaded assert.True(t, uniqueTables["public.system_patch"]) // check whether table names were loaded assert.True(t, uniqueTables["public.package"]) assert.True(t, uniqueTables["public.repo"]) + assert.True(t, uniqueTables["public.account_advisory"]) } func TestDatabaseSize(t *testing.T) {