diff --git a/0010-Don-t-rely-on-order-in-trust-agent-controller-role-c.patch b/0010-Don-t-rely-on-order-in-trust-agent-controller-role-c.patch new file mode 100644 index 0000000..2c67547 --- /dev/null +++ b/0010-Don-t-rely-on-order-in-trust-agent-controller-role-c.patch @@ -0,0 +1,139 @@ +From 7539b4aee19c7e28539ec853369a3230f2ae08f3 Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Mon, 23 Jun 2025 13:30:26 -0400 +Subject: [PATCH] Don't rely on order in trust agent/controller role check + +The code expected that the local server would always be the +first one returned. Instead loop through the returned list +to find the current server and set the state based on that. + +Fixes: https://github.com/freeipa/freeipa-healthcheck/issues/356 + +Signed-off-by: Rob Crittenden +--- + src/ipahealthcheck/ipa/plugin.py | 15 ++++--- + tests/test_ipa_trust.py | 71 +++++++++++++++++++++++++++++++- + 2 files changed, 79 insertions(+), 7 deletions(-) + +diff --git a/src/ipahealthcheck/ipa/plugin.py b/src/ipahealthcheck/ipa/plugin.py +index f1a325c..efaa947 100644 +--- a/src/ipahealthcheck/ipa/plugin.py ++++ b/src/ipahealthcheck/ipa/plugin.py +@@ -35,6 +35,13 @@ class IPARegistry(Registry): + self.trust_controller = False + self.ca_configured = False + ++ def has_role(self, roles): ++ for role in roles: ++ if role.get('server_server') == api.env.host: ++ if role.get('status') == 'enabled': ++ return True ++ return False ++ + def initialize(self, framework, config, options=None): + super().initialize(framework, config) + # deferred import for mock +@@ -81,12 +88,8 @@ class IPARegistry(Registry): + component_services=['ADTRUST'] + ), + ) +- role = roles[0].status(api)[0] +- if role.get('status') == 'enabled': +- self.trust_agent = True +- role = roles[1].status(api)[0] +- if role.get('status') == 'enabled': +- self.trust_controller = True ++ self.trust_agent = self.has_role(roles[0].status(api)) ++ self.trust_controller = self.has_role(roles[1].status(api)) + + + registry = IPARegistry() +diff --git a/tests/test_ipa_trust.py b/tests/test_ipa_trust.py +index 6c4754a..0faa702 100644 +--- a/tests/test_ipa_trust.py ++++ b/tests/test_ipa_trust.py +@@ -11,7 +11,8 @@ from util import capture_results + from util import m_api + + from ipahealthcheck.core import config, constants +-from ipahealthcheck.ipa.plugin import registry ++from ipahealthcheck.core.plugin import Results ++from ipahealthcheck.ipa.plugin import registry, IPARegistry + from ipahealthcheck.ipa.trust import (IPATrustAgentCheck, + IPATrustDomainsCheck, + IPADomainCheck, +@@ -1287,3 +1288,71 @@ class TestPackageCheck(BaseTest): + assert result.source == 'ipahealthcheck.ipa.trust' + assert result.check == 'IPATrustPackageCheck' + sys.modules['ipaserver.install'] = save ++ ++ ++class TestHasRole(BaseTest): ++ """Verify that the output of server-role-find which is used to ++ determine whether a host is a trust agent or controller ++ (or neither) isn't dependent upon the order the hosts are ++ returned. ++ ++ Only trust agent is tested here but there is no difference ++ between an agent and a trust in the way they are stored in ++ a server role. ++ """ ++ def test_role_last(self): ++ self.results = Results() ++ reg = IPARegistry() ++ ++ roles = [ ++ { ++ "role_servrole": "AD trust agent", ++ "server_server": "replica.ipa.example", ++ "status": "absent", ++ }, ++ { ++ "role_servrole": "AD trust agent", ++ "server_server": "server.ipa.example", ++ "status": "enabled", ++ }, ++ ] ++ ++ assert reg.has_role(roles) is True ++ ++ def test_role_first(self): ++ self.results = Results() ++ reg = IPARegistry() ++ ++ roles = [ ++ { ++ "role_servrole": "AD trust agent", ++ "server_server": "server.ipa.example", ++ "status": "enabled", ++ }, ++ { ++ "role_servrole": "AD trust agent", ++ "server_server": "replica.ipa.example", ++ "status": "absent", ++ }, ++ ] ++ ++ assert reg.has_role(roles) is True ++ ++ def test_no_role(self): ++ self.results = Results() ++ reg = IPARegistry() ++ ++ roles = [ ++ { ++ "role_servrole": "AD trust agent", ++ "server_server": "server.ipa.example", ++ "status": "absent", ++ }, ++ { ++ "role_servrole": "AD trust agent", ++ "server_server": "replica.ipa.example", ++ "status": "enabled", ++ }, ++ ] ++ ++ assert reg.has_role(roles) is False +-- +2.49.0 + diff --git a/ipa-healthcheck.spec b/ipa-healthcheck.spec index 80c585d..8a823de 100644 --- a/ipa-healthcheck.spec +++ b/ipa-healthcheck.spec @@ -8,7 +8,7 @@ Name: ipa-healthcheck Version: 0.12 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Health check tool for IdM BuildArch: noarch License: GPLv3 @@ -25,6 +25,7 @@ Patch0006: 0006-Fixes-log-file-permissions-as-per-CIS-benchmark.patch Patch0007: 0007-Fix-some-file-mode-format-issues.patch Patch0008: 0008-Allow-WARNING-in-the-files-test.patch Patch0009: 0009-Address-issues-uncovered-by-pylint-2.15.5.patch +Patch0010: 0010-Don-t-rely-on-order-in-trust-agent-controller-role-c.patch Requires: %{name}-core = %{version}-%{release} Requires: ipa-server @@ -129,6 +130,9 @@ install -p -m644 %{_builddir}/%{project}-%{shortname}-%{version}/man/man5/%{long %changelog +* Mon Jun 23 2025 Rob Crittenden - 0.12-6 +- Don't rely on order in trust roles (RHEL-99487) + * Thu Feb 27 2025 Rob Crittenden - 0.12-5 - Pull in lint fixes. Prevents exception when testing for AD trust (RHEL-79081) - Add direct requires on python3-libsss_nss_idmap.