diff --git a/database_admin/migrations/142_split_system_platform.down.sql b/database_admin/migrations/142_split_system_platform.down.sql new file mode 100644 index 000000000..402c3dd92 --- /dev/null +++ b/database_admin/migrations/142_split_system_platform.down.sql @@ -0,0 +1,443 @@ +-- system_platform +CREATE TABLE IF NOT EXISTS system_platform +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY, + inventory_id UUID NOT NULL, + rh_account_id INT NOT NULL, + vmaas_json TEXT CHECK (NOT empty(vmaas_json)), + json_checksum TEXT CHECK (NOT empty(json_checksum)), + last_updated TIMESTAMP WITH TIME ZONE NOT NULL, + unchanged_since TIMESTAMP WITH TIME ZONE NOT NULL, + last_evaluation TIMESTAMP WITH TIME ZONE, + installable_advisory_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_enh_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_bug_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_sec_count_cache INT NOT NULL DEFAULT 0, + last_upload TIMESTAMP WITH TIME ZONE, + stale_timestamp TIMESTAMP WITH TIME ZONE, + stale_warning_timestamp TIMESTAMP WITH TIME ZONE, + culled_timestamp TIMESTAMP WITH TIME ZONE, + stale BOOLEAN NOT NULL DEFAULT false, + display_name TEXT NOT NULL CHECK (NOT empty(display_name)), + packages_installed INT NOT NULL DEFAULT 0, + packages_installable INT NOT NULL DEFAULT 0, + reporter_id INT, + third_party BOOLEAN NOT NULL DEFAULT false, + yum_updates JSONB, + applicable_advisory_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_enh_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_bug_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_sec_count_cache INT NOT NULL DEFAULT 0, + satellite_managed BOOLEAN NOT NULL DEFAULT FALSE, + built_pkgcache BOOLEAN NOT NULL DEFAULT FALSE, + packages_applicable INT NOT NULL DEFAULT 0, + template_id BIGINT, + yum_checksum TEXT CHECK (NOT empty(yum_checksum)), + arch TEXT CHECK (NOT empty(arch)), + bootc BOOLEAN NOT NULL DEFAULT false +) PARTITION BY HASH (rh_account_id); + +-- PARTITIONING +SELECT create_table_partitions('system_platform', 16, + $$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05') + TABLESPACE pg_default$$); + +-- PRIVILEGES +GRANT SELECT, INSERT, UPDATE, DELETE ON system_platform TO listener; +-- evaluator needs to update last_evaluation +GRANT UPDATE ON system_platform TO evaluator; +-- manager needs to update cache and delete systems +GRANT SELECT, UPDATE, DELETE ON system_platform TO manager; +-- VMaaS sync needs to be able to perform system culling tasks +GRANT SELECT, UPDATE, DELETE ON system_platform to vmaas_sync; + +-- INSERT +INSERT INTO system_platform SELECT + si.id + si.inventory_id, + si.rh_account_id, + si.vmaas_json, + si.json_checksum, + si.last_updated, + si.unchanged_since, + sp.last_evaluation, + sp.installable_advisory_count_cache, + sp.installable_advisory_enh_count_cache, + sp.installable_advisory_bug_count_cache, + sp.installable_advisory_sec_count_cache, + si.last_upload, + si.stale_timestamp, + si.stale_warning_timestamp, + si.culled_timestamp, + si.stale, + si.display_name, + sp.packages_installed, + sp.packages_installable, + si.reporter_id, + sp.third_party, + si.yum_updates, + sp.applicable_advisory_count_cache, + sp.applicable_advisory_enh_count_cache, + sp.applicable_advisory_bug_count_cache, + sp.applicable_advisory_sec_count_cache, + si.satellite_managed, + si.built_pkgcache, + sp.packages_applicable, + si.template_id, + si.yum_checksum, + si.arch, + si.bootc +FROM system_inventory si JOIN system_patch sp + ON si.rh_account_id = sp.rh_account_id AND si.inventory_id = sp.inventory_id; + +SELECT setval('system_platform_id_seq', (SELECT MAX(id) FROM system_platform)); + +-- TRIGGERS +SELECT create_table_partition_triggers('system_platform_set_last_updated', + $$BEFORE INSERT OR UPDATE$$, + 'system_platform', + $$FOR EACH ROW EXECUTE PROCEDURE set_last_updated()$$); + +SELECT create_table_partition_triggers('system_platform_check_unchanged', + $$BEFORE INSERT OR UPDATE$$, + 'system_platform', + $$FOR EACH ROW EXECUTE PROCEDURE check_unchanged()$$); + +SELECT create_table_partition_triggers('system_platform_on_update', + $$AFTER UPDATE$$, + 'system_platform', + $$FOR EACH ROW EXECUTE PROCEDURE on_system_update()$$); + +-- CONSTRAINTS +ALTER TABLE system_platform +ADD PRIMARY KEY (rh_account_id, id), +ADD FOREIGN KEY (reporter_id) REFERENCES reporter (id), +ADD FOREIGN KEY (rh_account_id, template_id) REFERENCES template (rh_account_id, id), +ADD FOREIGN KEY (rh_account_id) REFERENCES rh_account (id), +ADD UNIQUE (rh_account_id, inventory_id); + +-- INDEXES +CREATE INDEX IF NOT EXISTS system_platform_inventory_id_idx + ON system_platform (inventory_id); + +-- UPDATE FUNCTIONS +CREATE OR REPLACE FUNCTION on_system_update() +-- this trigger updates advisory_account_data when server changes its stale flag + RETURNS TRIGGER +AS +$system_update$ +DECLARE + was_counted BOOLEAN; + should_count BOOLEAN; + change INT; +BEGIN + -- Ignore not yet evaluated systems + IF TG_OP != 'UPDATE' OR NEW.last_evaluation IS NULL THEN + RETURN NEW; + END IF; + + was_counted := OLD.stale = FALSE; + should_count := NEW.stale = FALSE; + + -- Determine what change we are performing + IF was_counted and NOT should_count THEN + change := -1; + ELSIF NOT was_counted AND should_count THEN + change := 1; + ELSE + -- No change + RETURN NEW; + END IF; + + -- insert/update advisories linked to the server + INSERT + INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable) + SELECT sa.advisory_id, NEW.rh_account_id, + case when sa.status_id = 0 then change else 0 end as systems_installable, + change as systems_applicable + FROM system_advisories sa + WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id + ORDER BY sa.advisory_id + ON CONFLICT (advisory_id, rh_account_id) DO UPDATE + SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable, + systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable; + RETURN NEW; +END; +$system_update$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION refresh_advisory_caches_multi(advisory_ids_in INTEGER[] DEFAULT NULL, + rh_account_id_in INTEGER DEFAULT NULL) + RETURNS VOID AS +$refresh_advisory$ +BEGIN + -- Lock rows + PERFORM aad.rh_account_id, aad.advisory_id + FROM advisory_account_data aad + WHERE (aad.advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL) + AND (aad.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) + FOR UPDATE OF aad; + + WITH current_counts AS ( + SELECT sa.advisory_id, sa.rh_account_id, + count(sa.*) filter (where sa.status_id = 0) as systems_installable, + count(sa.*) as systems_applicable + FROM system_advisories sa + JOIN system_platform sp + ON sa.rh_account_id = sp.rh_account_id AND sa.system_id = sp.id + WHERE sp.last_evaluation IS NOT NULL + AND sp.stale = FALSE + AND (sa.advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL) + AND (sp.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) + GROUP BY sa.advisory_id, sa.rh_account_id + ), + upserted AS ( + INSERT INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable) + SELECT advisory_id, rh_account_id, systems_installable, systems_applicable + FROM current_counts + ON CONFLICT (advisory_id, rh_account_id) DO UPDATE SET + systems_installable = EXCLUDED.systems_installable, + systems_applicable = EXCLUDED.systems_applicable + ) + DELETE FROM advisory_account_data + WHERE (advisory_id, rh_account_id) NOT IN (SELECT advisory_id, rh_account_id FROM current_counts) + AND (advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL) + AND (rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL); +END; +$refresh_advisory$ language plpgsql; + +CREATE OR REPLACE FUNCTION refresh_system_caches(system_id_in BIGINT DEFAULT NULL, + rh_account_id_in INTEGER DEFAULT NULL) + RETURNS INTEGER AS +$refresh_system$ +DECLARE + COUNT INTEGER; +BEGIN + WITH system_advisories_count AS ( + SELECT asp.rh_account_id, asp.id, + COUNT(advisory_id) FILTER (WHERE sa.status_id = 0) as installable_total, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 1 AND sa.status_id = 0) AS installable_enhancement, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 2 AND sa.status_id = 0) AS installable_bugfix, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 3 AND sa.status_id = 0) as installable_security, + COUNT(advisory_id) as applicable_total, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 1) AS applicable_enhancement, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 2) AS applicable_bugfix, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 3) as applicable_security + FROM system_platform asp -- this table ensures even systems without any system_advisories are in results + LEFT JOIN system_advisories sa + ON asp.rh_account_id = sa.rh_account_id AND asp.id = sa.system_id + LEFT JOIN advisory_metadata am + ON sa.advisory_id = am.id + WHERE (asp.id = system_id_in OR system_id_in IS NULL) + AND (asp.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) + GROUP BY asp.rh_account_id, asp.id + ORDER BY asp.rh_account_id, asp.id + ) + UPDATE system_platform sp + SET installable_advisory_count_cache = sc.installable_total, + installable_advisory_enh_count_cache = sc.installable_enhancement, + installable_advisory_bug_count_cache = sc.installable_bugfix, + installable_advisory_sec_count_cache = sc.installable_security, + applicable_advisory_count_cache = sc.applicable_total, + applicable_advisory_enh_count_cache = sc.applicable_enhancement, + applicable_advisory_bug_count_cache = sc.applicable_bugfix, + applicable_advisory_sec_count_cache = sc.applicable_security + FROM system_advisories_count sc + WHERE sp.rh_account_id = sc.rh_account_id AND sp.id = sc.id + AND (sp.id = system_id_in OR system_id_in IS NULL) + AND (sp.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL); + + GET DIAGNOSTICS COUNT = ROW_COUNT; + RETURN COUNT; +END; +$refresh_system$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION update_system_caches(system_id_in BIGINT) + RETURNS VOID AS +$update_system_caches$ +BEGIN + PERFORM refresh_system_caches(system_id_in, NULL); +END; +$update_system_caches$ + LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION refresh_all_cached_counts() + RETURNS void AS +$refresh_all_cached_counts$ +BEGIN + PERFORM refresh_system_caches(NULL, NULL); + PERFORM refresh_advisory_caches(NULL, NULL); +END; +$refresh_all_cached_counts$ + LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION refresh_account_cached_counts(rh_account_in varchar) + RETURNS void AS +$refresh_account_cached_counts$ +DECLARE + rh_account_id_in INT; +BEGIN + -- update advisory count for ordered systems + SELECT id FROM rh_account WHERE name = rh_account_in INTO rh_account_id_in; + + PERFORM refresh_system_caches(NULL, rh_account_id_in); + PERFORM refresh_advisory_caches(NULL, rh_account_id_in); +END; +$refresh_account_cached_counts$ + LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION refresh_system_cached_counts(inventory_id_in varchar) + RETURNS void AS +$refresh_system_cached_counts$ +DECLARE + system_id int; +BEGIN + + SELECT id FROM system_platform WHERE inventory_id = inventory_id_in INTO system_id; + + PERFORM refresh_system_caches(system_id, NULL); +END; +$refresh_system_cached_counts$ + LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION delete_system(inventory_id_in uuid) + RETURNS TABLE + ( + deleted_inventory_id uuid + ) +AS +$delete_system$ +DECLARE + v_system_id INT; + v_account_id INT; +BEGIN + -- opt out to refresh cache and then delete + SELECT id, rh_account_id + FROM system_platform + WHERE inventory_id = inventory_id_in + LIMIT 1 + FOR UPDATE OF system_platform + INTO v_system_id, v_account_id; + + IF v_system_id IS NULL OR v_account_id IS NULL THEN + RAISE NOTICE 'Not found'; + RETURN; + END IF; + + UPDATE system_platform + SET stale = true + WHERE rh_account_id = v_account_id + AND id = v_system_id; + + DELETE + FROM system_advisories + WHERE rh_account_id = v_account_id + AND system_id = v_system_id; + + DELETE + FROM system_repo + WHERE rh_account_id = v_account_id + AND system_id = v_system_id; + + DELETE + FROM system_package2 + WHERE rh_account_id = v_account_id + AND system_id = v_system_id; + + RETURN QUERY DELETE FROM system_platform + WHERE rh_account_id = v_account_id AND + id = v_system_id + RETURNING inventory_id; +END; +$delete_system$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION delete_systems(inventory_ids UUID[]) + RETURNS INTEGER +AS +$$ +DECLARE + tmp_cnt INTEGER; +BEGIN + + WITH systems as ( + SELECT rh_account_id, id + FROM system_platform + WHERE inventory_id = ANY (inventory_ids) + ORDER BY rh_account_id, id FOR UPDATE OF system_platform), + marked as ( + UPDATE system_platform sp + SET stale = true + WHERE (rh_account_id, id) in (select rh_account_id, id from systems) + ), + advisories as ( + DELETE + FROM system_advisories + WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) + ), + repos as ( + DELETE + FROM system_repo + WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) + ), + packages2 as ( + DELETE + FROM system_package2 + WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) + ), + deleted as ( + DELETE + FROM system_platform + WHERE (rh_account_id, id) in (select rh_account_id, id from systems) + RETURNING id + ) + SELECT count(*) + FROM deleted + INTO tmp_cnt; + + RETURN tmp_cnt; +END +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION delete_culled_systems(delete_limit INTEGER) + RETURNS INTEGER +AS +$$ +DECLARE + ids UUID[]; +BEGIN + ids := ARRAY( + SELECT inventory_id + FROM system_platform + WHERE culled_timestamp < now() + ORDER BY id + LIMIT delete_limit + ); + return delete_systems(ids); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION mark_stale_systems(mark_limit integer) + RETURNS INTEGER +AS +$$ +DECLARE + marked integer; +BEGIN + WITH ids AS ( + SELECT rh_account_id, id + FROM system_platform + WHERE stale_warning_timestamp < now() + AND stale = false + ORDER BY rh_account_id, id FOR UPDATE OF system_platform + LIMIT mark_limit + ) + UPDATE system_platform sp + SET stale = true + FROM ids + WHERE sp.rh_account_id = ids.rh_account_id + AND sp.id = ids.id; + GET DIAGNOSTICS marked = ROW_COUNT; + RETURN marked; +END; +$$ LANGUAGE plpgsql; + +-- inventory.hosts gets created by cyndi diff --git a/database_admin/migrations/142_split_system_platform.up.sql b/database_admin/migrations/142_split_system_platform.up.sql new file mode 100644 index 000000000..3f1523b23 --- /dev/null +++ b/database_admin/migrations/142_split_system_platform.up.sql @@ -0,0 +1,591 @@ +-- system_inventory +CREATE TABLE IF NOT EXISTS system_inventory +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY, + inventory_id UUID NOT NULL, + rh_account_id INT NOT NULL, + vmaas_json TEXT CHECK (NOT empty(vmaas_json)), + json_checksum TEXT CHECK (NOT empty(json_checksum)), + last_updated TIMESTAMPTZ NOT NULL, + unchanged_since TIMESTAMPTZ NOT NULL, + last_upload TIMESTAMPTZ, + stale BOOLEAN NOT NULL DEFAULT false, + display_name TEXT NOT NULL CHECK (NOT empty(display_name)), + reporter_id INT, + yum_updates JSONB, + yum_checksum TEXT CHECK (NOT empty(yum_checksum)), + satellite_managed BOOLEAN NOT NULL DEFAULT false, + built_pkgcache BOOLEAN NOT NULL DEFAULT false, + template_id BIGINT, + arch TEXT CHECK (NOT empty(arch)), + bootc BOOLEAN NOT NULL DEFAULT false, + tags JSONB NOT NULL, + created TIMESTAMPTZ NOT NULL, + insights_id UUID, + workspaces TEXT ARRAY, -- group IDs from system_platform.groups + stale_timestamp TIMESTAMPTZ NOT NULL, + stale_warning_timestamp TIMESTAMPTZ NOT NULL, + culled_timestamp TIMESTAMPTZ NOT NULL, + os_name TEXT CHECK (NOT empty(os_name)), + os_major SMALLINT, + os_minor SMALLINT, + rhsm_version TEXT CHECK (NOT empty(rhsm_version)), + owner_id UUID, + sap_workload BOOLEAN NOT NULL DEFAULT false, + sap_workload_sids TEXT ARRAY, + ansible_workload BOOLEAN NOT NULL DEFAULT false, + ansible_workload_controller_version TEXT CHECK (NOT empty(ansible_workload_controller_version)), + mssql_workload BOOLEAN NOT NULL DEFAULT false, + mssql_workload_version TEXT CHECK (NOT empty(mssql_workload_version)) +) PARTITION BY HASH (rh_account_id); + +-- PARTITIONING +SELECT create_table_partitions('system_inventory', 16, + $$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05') + TABLESPACE pg_default$$); + +-- PRIVILEGES (listener has write access) +GRANT SELECT, INSERT, UPDATE ON system_inventory TO listener; +GRANT SELECT, UPDATE, DELETE ON system_inventory TO vmaas_sync; -- vmaas_sync performs system culling +GRANT SELECT, UPDATE (stale) ON system_inventory TO manager; -- manager needs to be able to update opt_out column +GRANT SELECT ON system_inventory TO evaluator; +SELECT grant_table_partitions('SELECT', 'system_inventory', 'evaluator'); +SELECT grant_table_partitions('SELECT', 'system_inventory', 'listener'); +SELECT grant_table_partitions('SELECT', 'system_inventory', 'manager'); +SELECT grant_table_partitions('SELECT', 'system_inventory', 'vmaas_sync'); +GRANT SELECT, USAGE ON SEQUENCE system_inventory_id_seq TO evaluator; +GRANT SELECT, USAGE ON SEQUENCE system_inventory_id_seq TO listener; +GRANT SELECT, USAGE ON SEQUENCE system_inventory_id_seq TO vmaas_sync; + +-- LOAD DATA +CREATE OR REPLACE FUNCTION safe_to_int(input_text TEXT) +RETURNS SMALLINT AS $$ +BEGIN + RETURN input_text::SMALLINT; +EXCEPTION WHEN OTHERS THEN + RETURN NULL; +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION safe_to_uuid(input_text TEXT) +RETURNS UUID AS $$ +BEGIN + RETURN input_text::UUID; +EXCEPTION WHEN OTHERS THEN + RETURN NULL; +END; +$$ LANGUAGE plpgsql; + +INSERT INTO system_inventory SELECT + sp.id, + sp.inventory_id, + sp.rh_account_id, + sp.vmaas_json, + sp.json_checksum, + sp.last_updated, + sp.unchanged_since, + sp.last_upload, + sp.stale, + COALESCE(sp.display_name, ih.display_name), + sp.reporter_id, + sp.yum_updates, + sp.yum_checksum, + sp.satellite_managed, + sp.built_pkgcache, + sp.template_id, + sp.arch, + sp.bootc, + ih.tags, + ih.created, + ih.insights_id, + ARRAY(SELECT jsonb_array_elements(ih.groups)->>'id') AS workspaces, + COALESCE(ih.stale_timestamp, sp.stale_timestamp), + COALESCE(ih.stale_warning_timestamp, sp.stale_warning_timestamp), + COALESCE(ih.culled_timestamp, sp.culled_timestamp), + ih.system_profile->'operating_system'->>'name' AS os_name, + safe_to_int(ih.system_profile->'operating_system'->>'major') AS os_major, + safe_to_int(ih.system_profile->'operating_system'->>'minor') AS os_minor, + ih.system_profile->'rhsm'->>'version' AS rhsm_version, + safe_to_uuid(ih.system_profile->>'owner_id') AS owner_id, + COALESCE((ih.system_profile->'workloads'->'sap'->>'sap_system')::BOOLEAN, false) AS sap_workload, + ARRAY(SELECT jsonb_array_elements_text(ih.system_profile->'workloads'->'sap'->'sids')) AS sap_workload_sids, + COALESCE(LENGTH(ih.system_profile->'workloads'->>'ansible') > 2, false) AS ansible_workload, + ih.system_profile->'workloads'->'ansible'->>'controller_version' AS ansible_workload_controller_version, + COALESCE(LENGTH(ih.system_profile->'workloads'->>'mssql') > 2, false) AS mssql_workload, + ih.system_profile->'workloads'->'mssql'->>'version' AS mssql_workload_version +FROM inventory.hosts ih JOIN system_platform sp ON ih.id = sp.inventory_id +WHERE sp.stale = false; + +SELECT setval('system_inventory_id_seq', (SELECT MAX(id) FROM system_inventory)); + +DROP FUNCTION safe_to_int; +DROP FUNCTION safe_to_uuid; + +-- TRIGGERS +SELECT create_table_partition_triggers('system_inventory_set_last_updated', + $$BEFORE INSERT OR UPDATE$$, + 'system_inventory', + $$FOR EACH ROW EXECUTE PROCEDURE set_last_updated()$$); + +SELECT create_table_partition_triggers('system_inventory_check_unchanged', + $$BEFORE INSERT OR UPDATE$$, + 'system_inventory', + $$FOR EACH ROW EXECUTE PROCEDURE check_unchanged()$$); + +SELECT create_table_partition_triggers('system_inventory_on_update', + $$AFTER UPDATE$$, + 'system_inventory', + $$FOR EACH ROW EXECUTE PROCEDURE on_system_update()$$); + +-- CONSTRAINTS +ALTER TABLE IF EXISTS system_inventory +ADD PRIMARY KEY (rh_account_id, id), +ADD FOREIGN KEY (rh_account_id) REFERENCES rh_account (id), +ADD FOREIGN KEY (reporter_id) REFERENCES reporter (id), +ADD FOREIGN KEY (rh_account_id, template_id) REFERENCES template (rh_account_id, id), +ADD UNIQUE (rh_account_id, inventory_id); + +-- INDEXES +CREATE INDEX IF NOT EXISTS system_inventory_inventory_id_idx ON system_inventory (inventory_id); +CREATE INDEX IF NOT EXISTS system_inventory_tags_index ON system_inventory USING GIN (tags JSONB_PATH_OPS); +CREATE INDEX IF NOT EXISTS system_inventory_stale_timestamp_index ON system_inventory (stale_timestamp); +CREATE INDEX IF NOT EXISTS system_inventory_workspaces_index ON system_inventory USING GIN (workspaces); + +-- UPDATE FKEYS +ALTER TABLE IF EXISTS system_repo +DROP CONSTRAINT system_platform_id, +ADD CONSTRAINT system_inventory_id + FOREIGN KEY (rh_account_id, system_id) + REFERENCES system_inventory (rh_account_id, id); + +ALTER TABLE IF EXISTS system_advisories +DROP CONSTRAINT system_platform_id, +ADD CONSTRAINT system_inventory_id + FOREIGN KEY (rh_account_id, system_id) + REFERENCES system_inventory (rh_account_id, id); + +ALTER TABLE IF EXISTS system_package2 +DROP CONSTRAINT system_package2_rh_account_id_system_id_fkey, +ADD CONSTRAINT system_inventory_id + FOREIGN KEY (rh_account_id, system_id) + REFERENCES system_inventory (rh_account_id, id); + +-- UPDATE FUNCTIONS +CREATE OR REPLACE FUNCTION on_system_update() +-- this trigger updates advisory_account_data when server changes its stale flag + RETURNS TRIGGER +AS +$system_update$ +DECLARE + was_counted BOOLEAN; + should_count BOOLEAN; + change INT; +BEGIN + -- Ignore not yet evaluated systems + IF TG_OP != 'UPDATE' OR NOT EXISTS ( + SELECT 1 + FROM system_patch + WHERE system_id = NEW.id + AND rh_account_id = NEW.rh_account_id + AND last_evaluation IS NOT NULL + ) THEN + RETURN NEW; + END IF; + + was_counted := OLD.stale = FALSE; + should_count := NEW.stale = FALSE; + + -- Determine what change we are performing + IF was_counted and NOT should_count THEN + change := -1; + ELSIF NOT was_counted AND should_count THEN + change := 1; + ELSE + -- No change + RETURN NEW; + END IF; + + -- insert/update advisories linked to the server + INSERT + INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable) + SELECT sa.advisory_id, NEW.rh_account_id, + case when sa.status_id = 0 then change else 0 end as systems_installable, + change as systems_applicable + FROM system_advisories sa + WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id + ORDER BY sa.advisory_id + ON CONFLICT (advisory_id, rh_account_id) DO UPDATE + SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable, + systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable; + RETURN NEW; +END; +$system_update$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION refresh_advisory_caches_multi(advisory_ids_in INTEGER[] DEFAULT NULL, + rh_account_id_in INTEGER DEFAULT NULL) + RETURNS VOID AS +$refresh_advisory$ +BEGIN + -- Lock rows + PERFORM aad.rh_account_id, aad.advisory_id + FROM advisory_account_data aad + WHERE (aad.advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL) + AND (aad.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) + FOR UPDATE OF aad; + + WITH current_counts AS ( + SELECT sa.advisory_id, sa.rh_account_id, + count(sa.*) filter (where sa.status_id = 0) as systems_installable, + count(sa.*) as systems_applicable + FROM system_advisories sa + JOIN system_inventory si + ON sa.rh_account_id = si.rh_account_id AND sa.system_id = si.id + JOIN system_patch sp + ON si.id = sp.system_id AND sp.rh_account_id = si.rh_account_id + WHERE sp.last_evaluation IS NOT NULL + AND si.stale = FALSE + AND (sa.advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL) + AND (si.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) + GROUP BY sa.advisory_id, sa.rh_account_id + ), + upserted AS ( + INSERT INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable) + SELECT advisory_id, rh_account_id, systems_installable, systems_applicable + FROM current_counts + ON CONFLICT (advisory_id, rh_account_id) DO UPDATE SET + systems_installable = EXCLUDED.systems_installable, + systems_applicable = EXCLUDED.systems_applicable + ) + DELETE FROM advisory_account_data + WHERE (advisory_id, rh_account_id) NOT IN (SELECT advisory_id, rh_account_id FROM current_counts) + AND (advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL) + AND (rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL); +END; +$refresh_advisory$ language plpgsql; + +CREATE OR REPLACE FUNCTION refresh_system_caches(system_id_in BIGINT DEFAULT NULL, + rh_account_id_in INTEGER DEFAULT NULL) + RETURNS INTEGER AS +$refresh_system$ +DECLARE + COUNT INTEGER; +BEGIN + WITH system_advisories_count AS ( + SELECT si.rh_account_id, si.id, + COUNT(advisory_id) FILTER (WHERE sa.status_id = 0) as installable_total, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 1 AND sa.status_id = 0) AS installable_enhancement, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 2 AND sa.status_id = 0) AS installable_bugfix, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 3 AND sa.status_id = 0) as installable_security, + COUNT(advisory_id) as applicable_total, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 1) AS applicable_enhancement, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 2) AS applicable_bugfix, + COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 3) as applicable_security + FROM system_inventory si -- this table ensures even systems without any system_advisories are in results + LEFT JOIN system_advisories sa + ON si.rh_account_id = sa.rh_account_id AND si.id = sa.system_id + LEFT JOIN advisory_metadata am + ON sa.advisory_id = am.id + WHERE (si.id = system_id_in OR system_id_in IS NULL) + AND (si.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) + GROUP BY si.rh_account_id, si.id + ORDER BY si.rh_account_id, si.id + ) + UPDATE system_patch sp + SET installable_advisory_count_cache = sc.installable_total, + installable_advisory_enh_count_cache = sc.installable_enhancement, + installable_advisory_bug_count_cache = sc.installable_bugfix, + installable_advisory_sec_count_cache = sc.installable_security, + applicable_advisory_count_cache = sc.applicable_total, + applicable_advisory_enh_count_cache = sc.applicable_enhancement, + applicable_advisory_bug_count_cache = sc.applicable_bugfix, + applicable_advisory_sec_count_cache = sc.applicable_security + FROM system_advisories_count sc + WHERE sp.rh_account_id = sc.rh_account_id AND sp.system_id = sc.id + AND (sp.system_id = system_id_in OR system_id_in IS NULL) + AND (sp.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL); + + GET DIAGNOSTICS COUNT = ROW_COUNT; + RETURN COUNT; +END; +$refresh_system$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION refresh_system_cached_counts(inventory_id_in varchar) + RETURNS void AS +$refresh_system_cached_counts$ +DECLARE + system_id int; +BEGIN + + SELECT id FROM system_inventory WHERE inventory_id = inventory_id_in INTO system_id; + + PERFORM refresh_system_caches(system_id, NULL); +END; +$refresh_system_cached_counts$ + LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION delete_system(inventory_id_in uuid) + RETURNS TABLE + ( + deleted_inventory_id uuid + ) +AS +$delete_system$ +DECLARE + v_system_id INT; + v_account_id INT; +BEGIN + -- opt out to refresh cache and then delete + SELECT id, rh_account_id + FROM system_inventory + WHERE inventory_id = inventory_id_in + LIMIT 1 + FOR UPDATE OF system_inventory + INTO v_system_id, v_account_id; + + IF v_system_id IS NULL OR v_account_id IS NULL THEN + RAISE NOTICE 'Not found'; + RETURN; + END IF; + + UPDATE system_inventory + SET stale = true + WHERE rh_account_id = v_account_id + AND id = v_system_id; + + DELETE + FROM system_advisories + WHERE rh_account_id = v_account_id + AND system_id = v_system_id; + + DELETE + FROM system_repo + WHERE rh_account_id = v_account_id + AND system_id = v_system_id; + + DELETE + FROM system_package2 + WHERE rh_account_id = v_account_id + AND system_id = v_system_id; + + DELETE + FROM system_patch + WHERE rh_account_id = v_account_id + AND system_id = v_system_id; + + RETURN QUERY DELETE FROM system_inventory + WHERE rh_account_id = v_account_id AND + id = v_system_id + RETURNING inventory_id; +END; +$delete_system$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION delete_systems(inventory_ids UUID[]) + RETURNS INTEGER +AS +$$ +DECLARE + tmp_cnt INTEGER; +BEGIN + + WITH systems as ( + SELECT rh_account_id, id + FROM system_inventory + WHERE inventory_id = ANY (inventory_ids) + ORDER BY rh_account_id, id FOR UPDATE OF system_inventory), + marked as ( + UPDATE system_inventory sp + SET stale = true + WHERE (rh_account_id, id) in (select rh_account_id, id from systems) + ), + advisories as ( + DELETE + FROM system_advisories + WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) + ), + repos as ( + DELETE + FROM system_repo + WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) + ), + packages2 as ( + DELETE + FROM system_package2 + WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) + ), + patch_systems as ( + DELETE + FROM system_patch + WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) + ), + deleted as ( + DELETE + FROM system_inventory + WHERE (rh_account_id, id) in (select rh_account_id, id from systems) + RETURNING id + ) + SELECT count(*) + FROM deleted + INTO tmp_cnt; + + RETURN tmp_cnt; +END +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION delete_culled_systems(delete_limit INTEGER) + RETURNS INTEGER +AS +$fun$ +DECLARE + ids UUID[]; +BEGIN + ids := ARRAY( + SELECT inventory_id + FROM system_inventory + WHERE culled_timestamp < now() + ORDER BY id + LIMIT delete_limit + ); + return delete_systems(ids); +END; +$fun$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION mark_stale_systems(mark_limit integer) + RETURNS INTEGER +AS +$fun$ +DECLARE + marked integer; +BEGIN + WITH ids AS ( + SELECT rh_account_id, id, stale_warning_timestamp < now() as expired + FROM system_inventory + WHERE stale != (stale_warning_timestamp < now()) + ORDER BY rh_account_id, id FOR UPDATE OF system_inventory + LIMIT mark_limit + ) + UPDATE system_inventory si + SET stale = ids.expired + FROM ids + WHERE si.rh_account_id = ids.rh_account_id + AND si.id = ids.id; + GET DIAGNOSTICS marked = ROW_COUNT; + RETURN marked; +END; +$fun$ LANGUAGE plpgsql; + + + +-- system_patch +CREATE TABLE IF NOT EXISTS system_patch +( + system_id BIGINT NOT NULL, + rh_account_id INT NOT NULL, + last_evaluation TIMESTAMPTZ, + installable_advisory_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_enh_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_bug_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_sec_count_cache INT NOT NULL DEFAULT 0, + packages_installed INT NOT NULL DEFAULT 0, + packages_installable INT NOT NULL DEFAULT 0, + packages_applicable INT NOT NULL DEFAULT 0, + third_party BOOLEAN NOT NULL DEFAULT false, + applicable_advisory_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_enh_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_bug_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_sec_count_cache INT NOT NULL DEFAULT 0 +) PARTITION BY HASH (rh_account_id); + +-- PARTITIONING +SELECT create_table_partitions('system_patch', 16, + $$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05') + TABLESPACE pg_default$$); + +-- PRIVILEGES (evaluator has write access) +GRANT SELECT, UPDATE ON system_patch TO evaluator; +GRANT SELECT, UPDATE (installable_advisory_count_cache, + installable_advisory_enh_count_cache, + installable_advisory_bug_count_cache, + installable_advisory_sec_count_cache, + applicable_advisory_count_cache, + applicable_advisory_enh_count_cache, + applicable_advisory_bug_count_cache, + applicable_advisory_sec_count_cache) ON system_patch TO manager; +GRANT SELECT, UPDATE, DELETE ON system_patch to vmaas_sync; -- vmaas_sync performs system culling +SELECT grant_table_partitions('SELECT', 'system_patch', 'evaluator'); +SELECT grant_table_partitions('SELECT', 'system_patch', 'listener'); +SELECT grant_table_partitions('SELECT', 'system_patch', 'manager'); +SELECT grant_table_partitions('SELECT', 'system_patch', 'vmaas_sync'); + +INSERT INTO system_patch SELECT + id, + rh_account_id, + last_evaluation, + installable_advisory_count_cache, + installable_advisory_enh_count_cache, + installable_advisory_bug_count_cache, + installable_advisory_sec_count_cache, + packages_installed, + packages_installable, + packages_applicable, + third_party, + applicable_advisory_count_cache, + applicable_advisory_enh_count_cache, + applicable_advisory_bug_count_cache, + applicable_advisory_sec_count_cache +FROM system_platform sp +WHERE sp.stale = false; + +-- CONSTRAINTS +ALTER TABLE IF EXISTS system_patch +ADD PRIMARY KEY (rh_account_id, system_id), +ADD FOREIGN KEY (system_id, rh_account_id) REFERENCES system_inventory (id, rh_account_id); + + + +-- system_platform +DROP TABLE IF EXISTS system_platform; +CREATE OR REPLACE VIEW system_platform AS SELECT + si.id, + si.inventory_id, + si.rh_account_id, + si.vmaas_json, + si.json_checksum, + si.last_updated, + si.unchanged_since, + sp.last_evaluation, + sp.installable_advisory_count_cache, + sp.installable_advisory_enh_count_cache, + sp.installable_advisory_bug_count_cache, + sp.installable_advisory_sec_count_cache, + si.last_upload, + si.stale_timestamp, + si.stale_warning_timestamp, + si.culled_timestamp, + si.stale, + si.display_name, + sp.packages_installed, + sp.packages_installable, + si.reporter_id, + sp.third_party, + si.yum_updates, + sp.applicable_advisory_count_cache, + sp.applicable_advisory_enh_count_cache, + sp.applicable_advisory_bug_count_cache, + sp.applicable_advisory_sec_count_cache, + si.satellite_managed, + si.built_pkgcache, + sp.packages_applicable, + si.template_id, + si.yum_checksum, + si.arch, + si.bootc +FROM system_inventory si JOIN system_patch sp + ON si.id = sp.system_id AND si.rh_account_id = sp.rh_account_id; + +GRANT SELECT, INSERT, UPDATE, DELETE ON system_platform TO listener; +-- evaluator needs to update last_evaluation +GRANT SELECT, UPDATE ON system_platform TO evaluator; +-- manager needs to update cache and delete systems +GRANT SELECT, UPDATE, DELETE ON system_platform TO manager; +-- VMaaS sync needs to be able to perform system culling tasks +GRANT SELECT, UPDATE, DELETE ON system_platform to vmaas_sync; diff --git a/database_admin/schema/create_schema.sql b/database_admin/schema/create_schema.sql index 8dfc150b9..4deba2cab 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 (141, false); +VALUES (142, false); -- --------------------------------------------------------------------------- -- Functions @@ -77,7 +77,13 @@ DECLARE change INT; BEGIN -- Ignore not yet evaluated systems - IF TG_OP != 'UPDATE' OR NEW.last_evaluation IS NULL THEN + IF TG_OP != 'UPDATE' OR NOT EXISTS ( + SELECT 1 + FROM system_patch + WHERE system_id = NEW.id + AND rh_account_id = NEW.rh_account_id + AND last_evaluation IS NOT NULL + ) THEN RETURN NEW; END IF; @@ -127,12 +133,14 @@ BEGIN count(sa.*) filter (where sa.status_id = 0) as systems_installable, count(sa.*) as systems_applicable FROM system_advisories sa - JOIN system_platform sp - ON sa.rh_account_id = sp.rh_account_id AND sa.system_id = sp.id + JOIN system_inventory si + ON sa.rh_account_id = si.rh_account_id AND sa.system_id = si.id + JOIN system_patch sp + ON si.id = sp.system_id AND sp.rh_account_id = si.rh_account_id WHERE sp.last_evaluation IS NOT NULL - AND sp.stale = FALSE + AND si.stale = FALSE AND (sa.advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL) - AND (sp.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) + AND (si.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) GROUP BY sa.advisory_id, sa.rh_account_id ), upserted AS ( @@ -171,7 +179,7 @@ DECLARE COUNT INTEGER; BEGIN WITH system_advisories_count AS ( - SELECT asp.rh_account_id, asp.id, + SELECT si.rh_account_id, si.id, COUNT(advisory_id) FILTER (WHERE sa.status_id = 0) as installable_total, COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 1 AND sa.status_id = 0) AS installable_enhancement, COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 2 AND sa.status_id = 0) AS installable_bugfix, @@ -180,17 +188,17 @@ BEGIN COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 1) AS applicable_enhancement, COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 2) AS applicable_bugfix, COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 3) as applicable_security - FROM system_platform asp -- this table ensures even systems without any system_advisories are in results + FROM system_inventory si -- this table ensures even systems without any system_advisories are in results LEFT JOIN system_advisories sa - ON asp.rh_account_id = sa.rh_account_id AND asp.id = sa.system_id + ON si.rh_account_id = sa.rh_account_id AND si.id = sa.system_id LEFT JOIN advisory_metadata am ON sa.advisory_id = am.id - WHERE (asp.id = system_id_in OR system_id_in IS NULL) - AND (asp.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) - GROUP BY asp.rh_account_id, asp.id - ORDER BY asp.rh_account_id, asp.id + WHERE (si.id = system_id_in OR system_id_in IS NULL) + AND (si.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL) + GROUP BY si.rh_account_id, si.id + ORDER BY si.rh_account_id, si.id ) - UPDATE system_platform sp + UPDATE system_patch sp SET installable_advisory_count_cache = sc.installable_total, installable_advisory_enh_count_cache = sc.installable_enhancement, installable_advisory_bug_count_cache = sc.installable_bugfix, @@ -200,8 +208,8 @@ BEGIN applicable_advisory_bug_count_cache = sc.applicable_bugfix, applicable_advisory_sec_count_cache = sc.applicable_security FROM system_advisories_count sc - WHERE sp.rh_account_id = sc.rh_account_id AND sp.id = sc.id - AND (sp.id = system_id_in OR system_id_in IS NULL) + WHERE sp.rh_account_id = sc.rh_account_id AND sp.system_id = sc.id + AND (sp.system_id = system_id_in OR system_id_in IS NULL) AND (sp.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL); GET DIAGNOSTICS COUNT = ROW_COUNT; @@ -284,7 +292,7 @@ DECLARE system_id int; BEGIN - SELECT id FROM system_platform WHERE inventory_id = inventory_id_in INTO system_id; + SELECT id FROM system_inventory WHERE inventory_id = inventory_id_in INTO system_id; PERFORM refresh_system_caches(system_id, NULL); END; @@ -305,10 +313,10 @@ DECLARE BEGIN -- opt out to refresh cache and then delete SELECT id, rh_account_id - FROM system_platform + FROM system_inventory WHERE inventory_id = inventory_id_in LIMIT 1 - FOR UPDATE OF system_platform + FOR UPDATE OF system_inventory INTO v_system_id, v_account_id; IF v_system_id IS NULL OR v_account_id IS NULL THEN @@ -316,7 +324,7 @@ BEGIN RETURN; END IF; - UPDATE system_platform + UPDATE system_inventory SET stale = true WHERE rh_account_id = v_account_id AND id = v_system_id; @@ -336,7 +344,12 @@ BEGIN WHERE rh_account_id = v_account_id AND system_id = v_system_id; - RETURN QUERY DELETE FROM system_platform + DELETE + FROM system_patch + WHERE rh_account_id = v_account_id + AND system_id = v_system_id; + + RETURN QUERY DELETE FROM system_inventory WHERE rh_account_id = v_account_id AND id = v_system_id RETURNING inventory_id; @@ -353,11 +366,11 @@ BEGIN WITH systems as ( SELECT rh_account_id, id - FROM system_platform + FROM system_inventory WHERE inventory_id = ANY (inventory_ids) - ORDER BY rh_account_id, id FOR UPDATE OF system_platform), + ORDER BY rh_account_id, id FOR UPDATE OF system_inventory), marked as ( - UPDATE system_platform sp + UPDATE system_inventory sp SET stale = true WHERE (rh_account_id, id) in (select rh_account_id, id from systems) ), @@ -376,9 +389,14 @@ BEGIN FROM system_package2 WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) ), + patch_systems as ( + DELETE + FROM system_patch + WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems) + ), deleted as ( DELETE - FROM system_platform + FROM system_inventory WHERE (rh_account_id, id) in (select rh_account_id, id from systems) RETURNING id ) @@ -399,7 +417,7 @@ DECLARE BEGIN ids := ARRAY( SELECT inventory_id - FROM system_platform + FROM system_inventory WHERE culled_timestamp < now() ORDER BY id LIMIT delete_limit @@ -417,16 +435,16 @@ DECLARE BEGIN WITH ids AS ( SELECT rh_account_id, id, stale_warning_timestamp < now() as expired - FROM system_platform + FROM system_inventory WHERE stale != (stale_warning_timestamp < now()) - ORDER BY rh_account_id, id FOR UPDATE OF system_platform + ORDER BY rh_account_id, id FOR UPDATE OF system_inventory LIMIT mark_limit ) - UPDATE system_platform sp + UPDATE system_inventory si SET stale = ids.expired FROM ids - WHERE sp.rh_account_id = ids.rh_account_id - AND sp.id = ids.id; + WHERE si.rh_account_id = ids.rh_account_id + AND si.id = ids.id; GET DIAGNOSTICS marked = ROW_COUNT; RETURN marked; END; @@ -632,88 +650,78 @@ SELECT grant_table_partitions('SELECT, INSERT, UPDATE, DELETE', 'template', 'lis SELECT grant_table_partitions('SELECT', 'template', 'evaluator'); SELECT grant_table_partitions('SELECT', 'template', 'vmaas_sync'); --- system_platform -CREATE TABLE IF NOT EXISTS system_platform +-- system_inventory +CREATE TABLE IF NOT EXISTS system_inventory ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY, - inventory_id UUID NOT NULL, - rh_account_id INT NOT NULL, - vmaas_json TEXT CHECK (NOT empty(vmaas_json)), - json_checksum TEXT CHECK (NOT empty(json_checksum)), - last_updated TIMESTAMP WITH TIME ZONE NOT NULL, - unchanged_since TIMESTAMP WITH TIME ZONE NOT NULL, - last_evaluation TIMESTAMP WITH TIME ZONE, - installable_advisory_count_cache INT NOT NULL DEFAULT 0, - installable_advisory_enh_count_cache INT NOT NULL DEFAULT 0, - installable_advisory_bug_count_cache INT NOT NULL DEFAULT 0, - installable_advisory_sec_count_cache INT NOT NULL DEFAULT 0, - last_upload TIMESTAMP WITH TIME ZONE, - stale_timestamp TIMESTAMP WITH TIME ZONE, - stale_warning_timestamp TIMESTAMP WITH TIME ZONE, - culled_timestamp TIMESTAMP WITH TIME ZONE, - stale BOOLEAN NOT NULL DEFAULT false, - display_name TEXT NOT NULL CHECK (NOT empty(display_name)), - packages_installed INT NOT NULL DEFAULT 0, - packages_installable INT NOT NULL DEFAULT 0, - reporter_id INT, - third_party BOOLEAN NOT NULL DEFAULT false, - yum_updates JSONB, - applicable_advisory_count_cache INT NOT NULL DEFAULT 0, - applicable_advisory_enh_count_cache INT NOT NULL DEFAULT 0, - applicable_advisory_bug_count_cache INT NOT NULL DEFAULT 0, - applicable_advisory_sec_count_cache INT NOT NULL DEFAULT 0, - satellite_managed BOOLEAN NOT NULL DEFAULT FALSE, - built_pkgcache BOOLEAN NOT NULL DEFAULT FALSE, - packages_applicable INT NOT NULL DEFAULT 0, - template_id BIGINT, - yum_checksum TEXT CHECK (NOT empty(yum_checksum)), - arch TEXT CHECK (NOT empty(arch)), - bootc BOOLEAN NOT NULL DEFAULT false, + id BIGINT GENERATED BY DEFAULT AS IDENTITY, + inventory_id UUID NOT NULL, + rh_account_id INT NOT NULL REFERENCES rh_account (id), + vmaas_json TEXT CHECK (NOT empty(vmaas_json)), + json_checksum TEXT CHECK (NOT empty(json_checksum)), + last_updated TIMESTAMPTZ NOT NULL, + unchanged_since TIMESTAMPTZ NOT NULL, + last_upload TIMESTAMPTZ, + stale BOOLEAN NOT NULL DEFAULT false, + display_name TEXT NOT NULL CHECK (NOT empty(display_name)), + reporter_id INT REFERENCES reporter (id), + yum_updates JSONB, + yum_checksum TEXT CHECK (NOT empty(yum_checksum)), + satellite_managed BOOLEAN NOT NULL DEFAULT false, + built_pkgcache BOOLEAN NOT NULL DEFAULT false, + template_id BIGINT, + arch TEXT CHECK (NOT empty(arch)), + bootc BOOLEAN NOT NULL DEFAULT false, + tags JSONB NOT NULL, + created TIMESTAMPTZ NOT NULL, + insights_id UUID, + workspaces TEXT ARRAY, -- group IDs from system_platform.groups + stale_timestamp TIMESTAMPTZ NOT NULL, + stale_warning_timestamp TIMESTAMPTZ NOT NULL, + culled_timestamp TIMESTAMPTZ NOT NULL, + os_name TEXT CHECK (NOT empty(os_name)), + os_major SMALLINT, + os_minor SMALLINT, + rhsm_version TEXT CHECK (NOT empty(rhsm_version)), + owner_id UUID, + sap_workload BOOLEAN NOT NULL DEFAULT false, + sap_workload_sids TEXT ARRAY, + ansible_workload BOOLEAN NOT NULL DEFAULT false, + ansible_workload_controller_version TEXT CHECK (NOT empty(ansible_workload_controller_version)), + mssql_workload BOOLEAN NOT NULL DEFAULT false, + mssql_workload_version TEXT CHECK (NOT empty(mssql_workload_version)), PRIMARY KEY (rh_account_id, id), - UNIQUE (rh_account_id, inventory_id), - CONSTRAINT reporter_id FOREIGN KEY (reporter_id) REFERENCES reporter (id), - CONSTRAINT template_id FOREIGN KEY (rh_account_id, template_id) REFERENCES template (rh_account_id, id) + FOREIGN KEY (rh_account_id, template_id) REFERENCES template (rh_account_id, id), + UNIQUE (rh_account_id, inventory_id) ) PARTITION BY HASH (rh_account_id); -SELECT create_table_partitions('system_platform', 16, +SELECT create_table_partitions('system_inventory', 16, $$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05') TABLESPACE pg_default$$); -SELECT create_table_partition_triggers('system_platform_set_last_updated', +GRANT SELECT, INSERT, UPDATE ON system_inventory TO listener; +GRANT SELECT, UPDATE, DELETE ON system_inventory TO vmaas_sync; -- vmaas_sync performs system culling +GRANT SELECT, UPDATE (stale) ON system_inventory TO manager; -- manager needs to be able to update opt_out column +GRANT SELECT ON system_inventory TO evaluator; + +SELECT create_table_partition_triggers('system_inventory_set_last_updated', $$BEFORE INSERT OR UPDATE$$, - 'system_platform', + 'system_inventory', $$FOR EACH ROW EXECUTE PROCEDURE set_last_updated()$$); -SELECT create_table_partition_triggers('system_platform_check_unchanged', +SELECT create_table_partition_triggers('system_inventory_check_unchanged', $$BEFORE INSERT OR UPDATE$$, - 'system_platform', + 'system_inventory', $$FOR EACH ROW EXECUTE PROCEDURE check_unchanged()$$); -SELECT create_table_partition_triggers('system_platform_on_update', +SELECT create_table_partition_triggers('system_inventory_on_update', $$AFTER UPDATE$$, - 'system_platform', + 'system_inventory', $$FOR EACH ROW EXECUTE PROCEDURE on_system_update()$$); -CREATE INDEX IF NOT EXISTS system_platform_inventory_id_idx - ON system_platform (inventory_id); - -GRANT SELECT, INSERT, UPDATE, DELETE ON system_platform TO listener; --- evaluator needs to update last_evaluation -GRANT UPDATE ON system_platform TO evaluator; --- manager needs to update cache and delete systems -GRANT UPDATE (installable_advisory_count_cache, - installable_advisory_enh_count_cache, - installable_advisory_bug_count_cache, - installable_advisory_sec_count_cache), DELETE ON system_platform TO manager; -GRANT UPDATE (applicable_advisory_count_cache, - applicable_advisory_enh_count_cache, - applicable_advisory_bug_count_cache, - applicable_advisory_sec_count_cache), DELETE ON system_platform TO manager; - -GRANT SELECT, UPDATE, DELETE ON system_platform TO manager; - --- VMaaS sync needs to be able to perform system culling tasks -GRANT SELECT, UPDATE, DELETE ON system_platform to vmaas_sync; +CREATE INDEX IF NOT EXISTS system_inventory_inventory_id_idx ON system_inventory (inventory_id); +CREATE INDEX IF NOT EXISTS system_inventory_tags_index ON system_inventory USING GIN (tags JSONB_PATH_OPS); +CREATE INDEX IF NOT EXISTS system_inventory_stale_timestamp_index ON system_inventory (stale_timestamp); +CREATE INDEX IF NOT EXISTS system_inventory_workspaces_index ON system_inventory USING GIN (workspaces); CREATE TABLE IF NOT EXISTS deleted_system ( @@ -833,8 +841,6 @@ SELECT create_table_partitions('system_advisories', 32, GRANT SELECT, INSERT, UPDATE, DELETE ON system_advisories TO evaluator; -- manager needs to be able to update things like 'status' on a sysid/advisory combination, also needs to delete GRANT UPDATE, DELETE ON system_advisories TO manager; --- manager needs to be able to update opt_out column -GRANT UPDATE (stale) ON system_platform TO manager; -- listener deletes systems, TODO: temporary added evaluator permissions to listener GRANT SELECT, INSERT, UPDATE, DELETE ON system_advisories TO listener; -- vmaas_sync needs to delete culled systems, which cascades to system_advisories @@ -893,9 +899,9 @@ CREATE TABLE IF NOT EXISTS system_repo repo_id BIGINT NOT NULL, rh_account_id INT NOT NULL, UNIQUE (rh_account_id, system_id, repo_id), - CONSTRAINT system_platform_id + CONSTRAINT system_inventory_id FOREIGN KEY (rh_account_id, system_id) - REFERENCES system_platform (rh_account_id, id), + REFERENCES system_inventory (rh_account_id, id), CONSTRAINT repo_id FOREIGN KEY (repo_id) REFERENCES repo (id) @@ -911,16 +917,12 @@ GRANT SELECT, DELETE on system_repo to vmaas_sync; -- the following constraints are enabled here not directly in the table definitions -- to make new schema equal to the migrated schema ALTER TABLE system_advisories - ADD CONSTRAINT system_platform_id + ADD CONSTRAINT system_inventory_id FOREIGN KEY (rh_account_id, system_id) - REFERENCES system_platform (rh_account_id, id), + REFERENCES system_inventory (rh_account_id, id), ADD CONSTRAINT status_id FOREIGN KEY (status_id) REFERENCES status (id); -ALTER TABLE system_platform - ADD CONSTRAINT rh_account_id - FOREIGN KEY (rh_account_id) - REFERENCES rh_account (id); CREATE TABLE IF NOT EXISTS package_name ( @@ -971,7 +973,9 @@ CREATE TABLE IF NOT EXISTS system_package2 applicable_id BIGINT REFERENCES package (id), PRIMARY KEY (rh_account_id, system_id, package_id), - FOREIGN KEY (rh_account_id, system_id) REFERENCES system_platform (rh_account_id, id) + CONSTRAINT system_inventory_id + FOREIGN KEY (rh_account_id, system_id) + REFERENCES system_inventory (rh_account_id, id) ) PARTITION BY HASH (rh_account_id); CREATE INDEX IF NOT EXISTS system_package2_account_pkg_name_idx @@ -1023,6 +1027,91 @@ GRANT SELECT, INSERT, UPDATE, DELETE ON timestamp_kv TO vmaas_sync; GRANT DELETE ON system_advisories TO vmaas_sync; GRANT DELETE ON advisory_account_data TO vmaas_sync; +-- system_patch +CREATE TABLE IF NOT EXISTS system_patch +( + system_id BIGINT NOT NULL, + rh_account_id INT NOT NULL, + last_evaluation TIMESTAMPTZ, + installable_advisory_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_enh_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_bug_count_cache INT NOT NULL DEFAULT 0, + installable_advisory_sec_count_cache INT NOT NULL DEFAULT 0, + packages_installed INT NOT NULL DEFAULT 0, + packages_installable INT NOT NULL DEFAULT 0, + packages_applicable INT NOT NULL DEFAULT 0, + third_party BOOLEAN NOT NULL DEFAULT false, + applicable_advisory_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_enh_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_bug_count_cache INT NOT NULL DEFAULT 0, + applicable_advisory_sec_count_cache INT NOT NULL DEFAULT 0, + PRIMARY KEY (rh_account_id, system_id), + FOREIGN KEY (system_id, rh_account_id) REFERENCES system_inventory (id, rh_account_id) +) PARTITION BY HASH (rh_account_id); + +SELECT create_table_partitions('system_patch', 16, + $$WITH (fillfactor = '70', autovacuum_vacuum_scale_factor = '0.05') + TABLESPACE pg_default$$); + +GRANT SELECT, UPDATE ON system_patch TO evaluator; +GRANT SELECT, UPDATE (installable_advisory_count_cache, + installable_advisory_enh_count_cache, + installable_advisory_bug_count_cache, + installable_advisory_sec_count_cache, + applicable_advisory_count_cache, + applicable_advisory_enh_count_cache, + applicable_advisory_bug_count_cache, + applicable_advisory_sec_count_cache) ON system_patch TO manager; +GRANT SELECT, UPDATE, DELETE ON system_patch to vmaas_sync; -- vmaas_sync performs system culling + +-- system_platform +DROP TABLE IF EXISTS system_platform; +CREATE OR REPLACE VIEW system_platform AS SELECT + si.id, + si.inventory_id, + si.rh_account_id, + si.vmaas_json, + si.json_checksum, + si.last_updated, + si.unchanged_since, + sp.last_evaluation, + sp.installable_advisory_count_cache, + sp.installable_advisory_enh_count_cache, + sp.installable_advisory_bug_count_cache, + sp.installable_advisory_sec_count_cache, + si.last_upload, + si.stale_timestamp, + si.stale_warning_timestamp, + si.culled_timestamp, + si.stale, + si.display_name, + sp.packages_installed, + sp.packages_installable, + si.reporter_id, + sp.third_party, + si.yum_updates, + sp.applicable_advisory_count_cache, + sp.applicable_advisory_enh_count_cache, + sp.applicable_advisory_bug_count_cache, + sp.applicable_advisory_sec_count_cache, + si.satellite_managed, + si.built_pkgcache, + sp.packages_applicable, + si.template_id, + si.yum_checksum, + si.arch, + si.bootc +FROM system_inventory si JOIN system_patch sp + ON si.id = sp.system_id AND si.rh_account_id = sp.rh_account_id; + +GRANT SELECT, INSERT, UPDATE, DELETE ON system_platform TO listener; +-- evaluator needs to update last_evaluation +GRANT UPDATE ON system_platform TO evaluator; +-- manager needs to update cache and delete systems +GRANT SELECT, UPDATE, DELETE ON system_platform TO manager; +-- VMaaS sync needs to be able to perform system culling tasks +GRANT SELECT, UPDATE, DELETE ON system_platform to vmaas_sync; + -- ---------------------------------------------------------------------------- -- Read access for all users -- ---------------------------------------------------------------------------- diff --git a/dev/test_data.sql b/dev/test_data.sql index 10e44916e..6fa712eb7 100644 --- a/dev/test_data.sql +++ b/dev/test_data.sql @@ -1,7 +1,8 @@ DELETE FROM system_advisories; DELETE FROM system_repo; DELETE FROM system_package2; -DELETE FROM system_platform; +DELETE FROM system_patch; +DELETE FROM system_inventory; DELETE FROM deleted_system; DELETE FROM repo; DELETE FROM timestamp_kv; @@ -24,36 +25,59 @@ INSERT INTO template (id, rh_account_id, uuid, environment_id, name, description (3, 1, '99900000-0000-0000-0000-000000000003', '99900000000000000000000000000003', 'temp3-1', NULL, '{"to_time": "2000-01-01T00:00:00+00:00"}', 'x86_64', '8', 'user3'), (4, 3, '99900000-0000-0000-0000-000000000004', '99900000000000000000000000000004', 'temp4-3', 'desc4', '{"to_time": "2000-01-01T00:00:00+00:00"}', 'x86_64', '8', 'user4'); -INSERT INTO system_platform (id, inventory_id, display_name, rh_account_id, reporter_id, vmaas_json, json_checksum, last_evaluation, last_upload, packages_installed, packages_installable, packages_applicable, third_party, template_id, arch) VALUES -(1, '00000000-0000-0000-0000-000000000001','00000000-0000-0000-0000-000000000001', 1, 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2020-09-22 12:00:00-04',0,0,0, true, 1, 'x86_64'), -(2, '00000000-0000-0000-0000-000000000002','00000000-0000-0000-0000-000000000002', 1, 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-09-22 12:00:00-04',0,0,0, false, 1, 'x86_64'), -(3, '00000000-0000-0000-0000-000000000003','00000000-0000-0000-0000-000000000003', 1, 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-09-18 12:00:00-04',0,0,0, false, 2, 'x86_64'), -(4, '00000000-0000-0000-0000-000000000004','00000000-0000-0000-0000-000000000004', 1, 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-09-18 12:00:00-04',0,0,0, false, NULL, 'x86_64'), -(5, '00000000-0000-0000-0000-000000000005','00000000-0000-0000-0000-000000000005', 1, 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-09-18 12:00:00-04',0,0,0, false, NULL, 'x86_64'), -(6, '00000000-0000-0000-0000-000000000006','00000000-0000-0000-0000-000000000006', 1, 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-08-26 12:00:00-04',0,0,0, false, NULL, 'x86_64'); - -INSERT INTO system_platform (id, inventory_id, display_name, rh_account_id, vmaas_json, json_checksum, last_updated, unchanged_since, last_upload, packages_installed, packages_installable, packages_applicable, arch) VALUES -(7, '00000000-0000-0000-0000-000000000007','00000000-0000-0000-0000-000000000007', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-10-04 14:13:12-04', '2018-09-22 12:00:00-04', '2018-08-26 12:00:00-04',0,0,0, 'x86_64'); - -INSERT INTO system_platform (id, inventory_id, display_name, rh_account_id, vmaas_json, json_checksum, last_evaluation, last_upload, packages_installed, packages_installable, packages_applicable, arch) VALUES -(8, '00000000-0000-0000-0000-000000000008','00000000-0000-0000-0000-000000000008', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-08-26 12:00:00-04',0,0,0, 'x86_64'), -(9, '00000000-0000-0000-0000-000000000009','00000000-0000-0000-0000-000000000009', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04',0,0,0, 'x86_64'), -(10, '00000000-0000-0000-0000-000000000010','00000000-0000-0000-0000-000000000010', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04',0,0,0, 'x86_64'), -(11, '00000000-0000-0000-0000-000000000011','00000000-0000-0000-0000-000000000011', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04',0,0,0, 'x86_64'), -(12, '00000000-0000-0000-0000-000000000012','00000000-0000-0000-0000-000000000012', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04',2,2,2, 'x86_64'); - -INSERT INTO system_platform (id, inventory_id, display_name, rh_account_id, vmaas_json, json_checksum, last_evaluation, last_upload, packages_installed, packages_installable, packages_applicable, yum_updates) VALUES -(13, '00000000-0000-0000-0000-000000000013','00000000-0000-0000-0000-000000000013', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04', 1,0,0, NULL), -(14, '00000000-0000-0000-0000-000000000014','00000000-0000-0000-0000-000000000014', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04', 0,0,0, NULL), -(15, '00000000-0000-0000-0000-000000000015','00000000-0000-0000-0000-000000000015', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04', 0,0,0, - '{"update_list": {"suricata-0:6.0.3-2.fc35.i686": {"available_updates": [{"erratum": "RHSA-2021:3801", "basearch": "i686", "releasever": "ser1", "repository": "group_oisf:suricata-6.0", "package": "suricata-0:6.0.4-2.fc35.i686"}]}}, "basearch": "i686", "releasever": "ser1"}'); - -INSERT INTO system_platform (id, inventory_id, display_name, rh_account_id, vmaas_json, json_checksum, last_evaluation, last_upload, packages_installed, packages_installable, packages_applicable, yum_updates, template_id) VALUES -(16, '00000000-0000-0000-0000-000000000016','00000000-0000-0000-0000-000000000016', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04', 1,1,1, NULL, 4), -(17, '00000000-0000-0000-0000-000000000017','00000000-0000-0000-0000-000000000017', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2018-01-22 12:00:00-04',2,2,2, NULL, NULL); - -INSERT INTO system_platform (id, inventory_id, display_name, rh_account_id, reporter_id, vmaas_json, json_checksum, last_evaluation, last_upload, packages_installed, packages_installable, packages_applicable, third_party, template_id, arch) VALUES -(18, '00000000-0000-0000-0000-000000000018','00000000-0000-0000-0000-000000000018', 1, 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '2020-09-22 12:00:00-04',0,0,0, true, NULL, 'x86_64'); +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, reporter_id, template_id, arch, tags, created, insights_id, workspaces, stale_timestamp, stale_warning_timestamp, culled_timestamp, os_name, os_major, os_minor, rhsm_version, owner_id, sap_workload, sap_workload_sids, mssql_workload, mssql_workload_version) VALUES +(1, '00000000-0000-0000-0000-000000000001', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2020-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000001', 1, 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"},{"key": "k2", "value": "val2", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0001-000000000001', ARRAY['inventory-group-1'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 10, '8.10', NULL, true, ARRAY['ABC', 'DEF', 'GHI'], false, NULL), +(2, '00000000-0000-0000-0000-000000000002', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000002', 1, 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"},{"key": "k2", "value": "val2", "namespace": "ns1"},{"key": "k3", "value": "val3", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0002-000000000001', ARRAY['inventory-group-1'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 1, '8.1', NULL, true, ARRAY['ABC'], false, NULL), +(3, '00000000-0000-0000-0000-000000000003', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000003', 1, 2, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}, {"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0003-000000000001', ARRAY['inventory-group-1'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 1, '8.0', NULL, true, NULL, false, NULL), +(4, '00000000-0000-0000-0000-000000000004', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000004', 1, NULL, 'x86_64', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0004-000000000001', ARRAY['inventory-group-1'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 2, '8.3', 'cccccccc-0000-0000-0001-000000000004', true, NULL, false, NULL), +(5, '00000000-0000-0000-0000-000000000005', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000005', 1, NULL, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0005-000000000001', ARRAY['inventory-group-1'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 3, '8.3', 'cccccccc-0000-0000-0001-000000000005', true, NULL, false, NULL), +(6, '00000000-0000-0000-0000-000000000006', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000006', 1, NULL, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0006-000000000001', ARRAY['inventory-group-1'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 7, 3, '7.3', NULL, true, NULL, true, '15.3.0'); +INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, third_party) VALUES +(1, 1, '2018-09-22 12:00:00-04', true), +(2, 1, '2018-09-22 12:00:00-04', false), +(3, 1, '2018-09-22 12:00:00-04', false), +(4, 1, '2018-09-22 12:00:00-04', false), +(5, 1, '2018-09-22 12:00:00-04', false), +(6, 1, '2018-09-22 12:00:00-04', false); + +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_updated, unchanged_since, last_upload, display_name, arch, tags, created, insights_id, workspaces, stale_timestamp, stale_warning_timestamp, culled_timestamp, os_name, os_major, rhsm_version, owner_id, sap_workload, ansible_workload, ansible_workload_controller_version) VALUES +(7, '00000000-0000-0000-0000-000000000007', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-10-04 14:13:12-04', '2018-09-22 12:00:00-04', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000007', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0007-000000000001', ARRAY['inventory-group-2'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, '8.x', 'cccccccc-0000-0000-0001-000000000007', true, true, '1.0'); +INSERT INTO system_patch (system_id, rh_account_id) VALUES +(7, 1); + +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, arch, tags, created, insights_id, workspaces, stale_timestamp, stale_warning_timestamp, culled_timestamp, os_name, os_major, os_minor, rhsm_version, owner_id, sap_workload) VALUES +( 8, '00000000-0000-0000-0000-000000000008', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000008', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0008-000000000001', ARRAY['inventory-group-2'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 3, '8.3', 'cccccccc-0000-0000-0001-000000000008', true), +( 9, '00000000-0000-0000-0000-000000000009', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000009', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0009-000000000001', NULL, '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 1, '8.1', NULL, true), +(10, '00000000-0000-0000-0000-000000000010', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000010', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0010-000000000001', NULL, '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 2, '8.2', NULL, true), +(11, '00000000-0000-0000-0000-000000000011', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000011', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0011-000000000001', ARRAY[]::TEXT[], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 3, '8.3', NULL, true), +(12, '00000000-0000-0000-0000-000000000012', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000012', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0012-000000000001', ARRAY[]::TEXT[], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 1, '8.1', NULL, true); +INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, packages_installed, packages_installable, packages_applicable) VALUES +( 8, 1, '2018-09-22 12:00:00-04', 0, 0, 0), +( 9, 2, '2018-09-22 12:00:00-04', 0, 0, 0), +(10, 2, '2018-09-22 12:00:00-04', 0, 0, 0), +(11, 2, '2018-09-22 12:00:00-04', 0, 0, 0), +(12, 3, '2018-09-22 12:00:00-04', 2, 2, 2); + +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, yum_updates, tags, created, insights_id, workspaces, stale_timestamp, stale_warning_timestamp, culled_timestamp, os_name, os_major, os_minor, rhsm_version, sap_workload) VALUES +(13, '00000000-0000-0000-0000-000000000013', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000013', NULL, '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0013-000000000001', ARRAY[]::TEXT[], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 2, '8.2', true), +(14, '00000000-0000-0000-0000-000000000014', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000014', NULL, '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0014-000000000001', ARRAY[]::TEXT[], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 3, NULL, true), +(15, '00000000-0000-0000-0000-000000000015', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000015', '{"update_list": {"suricata-0:6.0.3-2.fc35.i686": {"available_updates": [{"erratum": "RHSA-2021:3801", "basearch": "i686", "releasever": "ser1", "repository": "group_oisf:suricata-6.0", "package": "suricata-0:6.0.4-2.fc35.i686"}]}}, "basearch": "i686", "releasever": "ser1"}', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0015-000000000001', ARRAY[]::TEXT[], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 1, '8.1', false); +INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, packages_installed) VALUES +(13, 3, '2018-09-22 12:00:00-04', 1), +(14, 3, '2018-09-22 12:00:00-04', 0), +(15, 3, '2018-09-22 12:00:00-04', 0); + +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, template_id, tags, created, insights_id, workspaces, stale_timestamp, stale_warning_timestamp, culled_timestamp, os_name, os_major, os_minor, rhsm_version, ansible_workload, ansible_workload_controller_version, mssql_workload, mssql_workload_version) VALUES +(16, '00000000-0000-0000-0000-000000000016', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000016', 4, '[]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0016-000000000001', ARRAY[]::TEXT[], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 2, '8.2', false, NULL, false, NULL), +(17, '00000000-0000-0000-0000-000000000017', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000017', NULL, '[]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0017-000000000001', ARRAY[]::TEXT[], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 1, '8.1', true, '1.0', true, '15.3.0'); +INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, packages_installed, packages_installable, packages_applicable) VALUES +(16, 3, '2018-09-22 12:00:00-04', 1, 1, 1), +(17, 1, '2018-09-22 12:00:00-04', 2, 2, 2); + +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, reporter_id, arch, tags, created, insights_id, workspaces, stale_timestamp, stale_warning_timestamp, culled_timestamp, os_name, os_major, os_minor, rhsm_version, owner_id, sap_workload) VALUES +(18, '00000000-0000-0000-0000-000000000018', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2020-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000018', 1, 'x86_64', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '00000000-0000-0000-0018-000000000001', ARRAY['inventory-group-1'], '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '2018-09-09 12:00:00-04', 'RHEL', 8, 2, '8.3', '99999999-9999-9999-9999-999999999404', true); +INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, third_party) VALUES +(18, 1, '2018-09-22 12:00:00-04', true); INSERT INTO advisory_metadata (id, name, description, synopsis, summary, solution, advisory_type_id, public_date, modified_date, url, severity_id, cve_list, release_versions) VALUES @@ -233,13 +257,13 @@ INSERT INTO inventory.hosts_v1_0 (id, insights_id, account, display_name, tags, '{"rhsm": {"version": "8.1"}, "operating_system": {"name": "RHEL", "major": 8, "minor": 1}, "workloads": {"ansible": {"controller_version": "1.0", "hub_version": "3.4.1", "catalog_worker_version": "100.387.9846.12", "sso_version": "1.28.3.52641.10000513168495123"}, "mssql": { "version": "15.3.0"}}}', 'puptoo', '{}', 'org_3', '[]'), ('00000000000000000000000000000018', '00000000-0000-0000-0018-000000000001', '1', '00000000-0000-0000-0000-000000000018', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', - '2018-09-22 12:00:00-04', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '{"workloads": {"sap": {"sap_system": true}}, "operating_system": {"name": "RHEL", "major": 8, "minor": 2}, "rhsm": {"version": "8.3"}, "owner_id": "return_404"}', + '2018-09-22 12:00:00-04', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '{"workloads": {"sap": {"sap_system": true}}, "operating_system": {"name": "RHEL", "major": 8, "minor": 2}, "rhsm": {"version": "8.3"}, "owner_id": "99999999-9999-9999-9999-999999999404"}', 'puptoo', '{}', 'org_1', '[{"id": "inventory-group-1", "name": "group1"}]'); SELECT refresh_all_cached_counts(); ALTER TABLE advisory_metadata ALTER COLUMN id RESTART WITH 100; -ALTER TABLE system_platform ALTER COLUMN id RESTART WITH 100; +ALTER TABLE system_inventory ALTER COLUMN id RESTART WITH 100; ALTER TABLE rh_account ALTER COLUMN id RESTART WITH 100; ALTER TABLE repo ALTER COLUMN id RESTART WITH 100; ALTER TABLE package ALTER COLUMN id RESTART WITH 100; diff --git a/platform/candlepin.go b/platform/candlepin.go index 290183493..2ccf538e8 100644 --- a/platform/candlepin.go +++ b/platform/candlepin.go @@ -16,7 +16,7 @@ func candlepinConsumersPutHandler(c *gin.Context) { consumer := c.Param("consumer") jsonData, _ := io.ReadAll(c.Request.Body) utils.LogInfo("PUT consumer", consumer, "body", string(jsonData)) - if consumer == "return_404" { + if consumer == "return_404" || consumer == "99999999-9999-9999-9999-999999999404" { c.Data(http.StatusNotFound, gin.MIMEJSON, []byte{}) return } @@ -26,7 +26,7 @@ func candlepinConsumersPutHandler(c *gin.Context) { func candlepinConsumersGetHandler(c *gin.Context) { consumer := c.Param("consumer") utils.LogInfo("GET consumer", consumer, "body") - if consumer == "return_404" { + if consumer == "return_404" || consumer == "99999999-9999-9999-9999-999999999404" { c.Data(http.StatusNotFound, gin.MIMEJSON, []byte{}) return } @@ -51,7 +51,8 @@ func candlepinConsumersEnvironmentsHandler(c *gin.Context) { return } utils.LogInfo("ConsumerUuids", req.ConsumerUuids) - if slices.Contains(req.ConsumerUuids, "return_404") { + if slices.Contains(req.ConsumerUuids, "return_404") || + slices.Contains(req.ConsumerUuids, "99999999-9999-9999-9999-999999999404") { c.Data(http.StatusNotFound, gin.MIMEJSON, []byte{}) return }