From 38c8e5e4551e0c395e11e6f70a4a5d5cfc91c5cb Mon Sep 17 00:00:00 2001 From: Hadar Artzi Date: Thu, 19 Nov 2020 12:37:57 -0500 Subject: [PATCH] update sql function annotation_update_textsearch to check for resource_id existance Without checking if resource_id existance, queries can fail due to a foreign key constraint. Related post: https://discuss.cyberarkcommons.org/t/database-error-after-backup-restore/474/11 --- CHANGELOG.md | 4 + ...834_update_annotation_update_textsearch.rb | 77 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 db/migrate/20201119122834_update_annotation_update_textsearch.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index bcd574613c..8208856441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. will be published to RedHat Container Registry. [cyberark/conjur#1883](https://github.com/cyberark/conjur/issues/1883) +### Fixed +- Policy loading no longer fails when attempting to update the annotation + search index for a resource that no longer exists. [cyberark/conjur#1948](https://github.com/cyberark/conjur/issues/1948) + ## [1.11.0] - 2020-11-06 ### Added - GCP authenticator (`authn-gcp`) supports authenticating from Google Cloud Function (GCF) diff --git a/db/migrate/20201119122834_update_annotation_update_textsearch.rb b/db/migrate/20201119122834_update_annotation_update_textsearch.rb new file mode 100644 index 0000000000..80df6157b0 --- /dev/null +++ b/db/migrate/20201119122834_update_annotation_update_textsearch.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +# This migration addresses an issue highlight in this post +# https://discuss.cyberarkcommons.org/t/database-error-after-backup-restore/474/11. +# Where a foreign key constraint leads to an internal error +Sequel.migration do + up do + run "CREATE OR REPLACE FUNCTION annotation_update_textsearch() RETURNS trigger + -- The loader orchestration logic changes the search path temporarily, which causes + -- these triggers to be unable to find the tables and functions they need. Fix this + -- by setting the search path from the current schema each time. Added for Conjur OSS. + SET search_path FROM CURRENT + LANGUAGE plpgsql + AS $annotation_update_textsearch$ + BEGIN + IF TG_OP IN ('INSERT', 'UPDATE') THEN + UPDATE resources_textsearch rts + SET textsearch = ( + SELECT r.tsvector FROM resources r + WHERE r.resource_id = rts.resource_id + ) WHERE resource_id = NEW.resource_id; + END IF; + + IF TG_OP IN ('UPDATE', 'DELETE') THEN + BEGIN + UPDATE resources_textsearch rts + SET textsearch = ( + SELECT r.tsvector FROM resources r + WHERE r.resource_id = rts.resource_id + ) WHERE resource_id = OLD.resource_id; + EXCEPTION WHEN foreign_key_violation THEN + /* + It's possible when an annotation is deleted that the entire resource + has been deleted. When this is the case, attempting to update the + search text will raise a foreign key violation on the missing + resource_id. + */ + RAISE WARNING 'Cannot update search text for % because it no longer exists', OLD.resource_id; + RETURN NULL; + END; + END IF; + + RETURN NULL; + END + $annotation_update_textsearch$" + end + + down do + run "CREATE FUNCTION OR REPLACE annotation_update_textsearch() RETURNS trigger + -- The loader orchestration logic changes the search path temporarily, which causes + -- these triggers to be unable to find the tables and functions they need. Fix this + -- by setting the search path from the current schema each time. Added for Conjur OSS. + SET search_path FROM CURRENT + LANGUAGE plpgsql + AS $annotation_update_textsearch$ + BEGIN + IF TG_OP IN ('INSERT', 'UPDATE') THEN + UPDATE resources_textsearch rts + SET textsearch = ( + SELECT r.tsvector FROM resources r + WHERE r.resource_id = rts.resource_id + ) WHERE resource_id = NEW.resource_id; + END IF; + + IF TG_OP IN ('UPDATE', 'DELETE') THEN + UPDATE resources_textsearch rts + SET textsearch = ( + SELECT r.tsvector FROM resources r + WHERE r.resource_id = rts.resource_id + ) WHERE resource_id = OLD.resource_id; + END IF; + + RETURN NULL; + END + $annotation_update_textsearch$;" + end +end