From d4d3d5bb4070b81fad681d59f234a9c3d64f62dc Mon Sep 17 00:00:00 2001 From: Ian Ballou Date: Fri, 15 Nov 2024 16:40:31 -0500 Subject: [PATCH 1/2] Halt upgrades if evr is not owned by foreman --- .../check_external_db_evr_permissions.rb | 56 +++++++++++++++++++ definitions/scenarios/foreman_upgrade.rb | 1 + definitions/scenarios/satellite_upgrade.rb | 1 + 3 files changed, 58 insertions(+) create mode 100644 definitions/checks/foreman/check_external_db_evr_permissions.rb diff --git a/definitions/checks/foreman/check_external_db_evr_permissions.rb b/definitions/checks/foreman/check_external_db_evr_permissions.rb new file mode 100644 index 000000000..fa1e0b2df --- /dev/null +++ b/definitions/checks/foreman/check_external_db_evr_permissions.rb @@ -0,0 +1,56 @@ +module Checks + module Foreman + class CheckExternalDbEvrPermissions < ForemanMaintain::Check + metadata do + label :external_db_evr_permissions + for_feature :foreman_database + description 'Check that external DBs have proper EVR extension permissions' + tags :pre_upgrade + confine do + feature(:foreman_database) && !feature(:foreman_database).local? && feature(:katello) + end + end + + def run + return unless evr_exists? + + error_msg = 'The evr extension is not owned by the foreman DB owner. Please run the ' \ + 'following command to fix it: ' \ + 'UPDATE pg_extension SET extowner = (SELECT oid FROM pg_authid WHERE ' \ + "rolname='foreman') WHERE extname='evr';" + fail!(error_msg) unless foreman_owns_evr? + end + + private + + def evr_exists? + evr_exists = feature(:foreman_database).query(query_for_evr_existence) + if !evr_exists.empty? && evr_exists.first['evr_exists'] == '1' + return evr_exists.first['evr_exists'] == '1' + end + return false + end + + def foreman_owns_evr? + evr_owned_by_postgres = feature(:foreman_database).query(query_if_postgres_owns_evr) + unless evr_owned_by_postgres.empty? + return evr_owned_by_postgres.first['evr_owned_by_postgres'] == '0' + end + fail!('Could not determine if the evr extension is owned by the foreman DB owner') + end + + def query_for_evr_existence + <<-SQL + SELECT 1 AS evr_exists FROM pg_extension WHERE extname = 'evr' + SQL + end + + def query_if_postgres_owns_evr + <<-SQL + SELECT CASE WHEN r.rolname = 'foreman' THEN 0 ELSE 1 END AS evr_owned_by_postgres + FROM pg_extension e JOIN pg_roles r ON e.extowner = r.oid WHERE e.extname = 'evr' + SQL + end + end + end +end diff --git a/definitions/scenarios/foreman_upgrade.rb b/definitions/scenarios/foreman_upgrade.rb index b3a22dd69..583996a9f 100644 --- a/definitions/scenarios/foreman_upgrade.rb +++ b/definitions/scenarios/foreman_upgrade.rb @@ -40,6 +40,7 @@ def compose Checks::Disk::AvailableSpaceCandlepin, # if candlepin Checks::Disk::AvailableSpacePostgresql13, Checks::Foreman::ValidateExternalDbVersion, # if external database + Checks::Foreman::CheckExternalDbEvrPermissions, # if external database Checks::Foreman::CheckCorruptedRoles, Checks::Foreman::CheckDuplicatePermissions, Checks::Foreman::TuningRequirements, # if katello present diff --git a/definitions/scenarios/satellite_upgrade.rb b/definitions/scenarios/satellite_upgrade.rb index ae8de8f00..7da75ea8a 100644 --- a/definitions/scenarios/satellite_upgrade.rb +++ b/definitions/scenarios/satellite_upgrade.rb @@ -39,6 +39,7 @@ def compose Checks::Disk::AvailableSpace, Checks::Disk::AvailableSpaceCandlepin, # if candlepin Checks::Foreman::ValidateExternalDbVersion, # if external database + Checks::Foreman::CheckExternalDbEvrPermissions, # if external database Checks::Foreman::CheckCorruptedRoles, Checks::Foreman::CheckDuplicatePermissions, Checks::Foreman::TuningRequirements, # if katello present From e6dc6f15144edc8518cbc37d09445c744b60ae88 Mon Sep 17 00:00:00 2001 From: Ian Ballou Date: Mon, 18 Nov 2024 13:48:42 -0500 Subject: [PATCH 2/2] Allow different foreman DB usernames in evr check --- .../check_external_db_evr_permissions.rb | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/definitions/checks/foreman/check_external_db_evr_permissions.rb b/definitions/checks/foreman/check_external_db_evr_permissions.rb index fa1e0b2df..46991bd97 100644 --- a/definitions/checks/foreman/check_external_db_evr_permissions.rb +++ b/definitions/checks/foreman/check_external_db_evr_permissions.rb @@ -4,7 +4,7 @@ class CheckExternalDbEvrPermissions < ForemanMaintain::Check metadata do label :external_db_evr_permissions for_feature :foreman_database - description 'Check that external DBs have proper EVR extension permissions' + description 'Check that external databases have proper EVR extension permissions' tags :pre_upgrade confine do feature(:foreman_database) && !feature(:foreman_database).local? && feature(:katello) @@ -12,23 +12,25 @@ class CheckExternalDbEvrPermissions < ForemanMaintain::Check end def run - return unless evr_exists? + return true unless evr_exists? - error_msg = 'The evr extension is not owned by the foreman DB owner. Please run the ' \ - 'following command to fix it: ' \ + error_msg = 'The evr extension is not owned by the foreman database owner. ' \ + 'Please run the following command on the external foreman database to fix it: ' \ 'UPDATE pg_extension SET extowner = (SELECT oid FROM pg_authid WHERE ' \ - "rolname='foreman') WHERE extname='evr';" + "rolname='#{foreman_db_user}') WHERE extname='evr';" fail!(error_msg) unless foreman_owns_evr? end private + def foreman_db_user + feature(:foreman_database).configuration['username'] || 'foreman' + end + def evr_exists? evr_exists = feature(:foreman_database).query(query_for_evr_existence) - if !evr_exists.empty? && evr_exists.first['evr_exists'] == '1' - return evr_exists.first['evr_exists'] == '1' - end - return false + return false if evr_exists.empty? + return evr_exists.first['evr_exists'] == '1' end def foreman_owns_evr? @@ -36,7 +38,10 @@ def foreman_owns_evr? unless evr_owned_by_postgres.empty? return evr_owned_by_postgres.first['evr_owned_by_postgres'] == '0' end - fail!('Could not determine if the evr extension is owned by the foreman DB owner') + failure_msg = 'Could not determine if the evr extension is owned by the ' \ + 'foreman database owner. Check that the foreman database is accessible ' \ + "and that the database connection configuration is up to date." + fail!(failure_msg) end def query_for_evr_existence @@ -47,7 +52,7 @@ def query_for_evr_existence def query_if_postgres_owns_evr <<-SQL - SELECT CASE WHEN r.rolname = 'foreman' THEN 0 ELSE 1 END AS evr_owned_by_postgres + SELECT CASE WHEN r.rolname = '#{foreman_db_user}' THEN 0 ELSE 1 END AS evr_owned_by_postgres FROM pg_extension e JOIN pg_roles r ON e.extowner = r.oid WHERE e.extname = 'evr' SQL end