URL: https://github.com/freeipa/freeipa/pull/437 Author: tomaskrizek Title: #437: FIPS: replica install check Action: synchronized
To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/437/head:pr437 git checkout pr437
From 0db599ed71fbabcaacff0082eb369b2a737df866 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Mon, 6 Feb 2017 13:08:11 +0100 Subject: [PATCH 1/5] Add fips_mode variable to env Variable fips_mode indicating whether machine is running in FIPS-enabled mode was added to env. https://fedorahosted.org/freeipa/ticket/5695 --- ipalib/config.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..c7caeef 100644 --- a/ipalib/config.py +++ b/ipalib/config.py @@ -44,6 +44,10 @@ from ipalib.constants import CONFIG_SECTION from ipalib.constants import OVERRIDE_ERROR, SET_ERROR, DEL_ERROR from ipalib import errors +try: + from ipaplatform.tasks import tasks +except ImportError: + tasks = None if six.PY3: unicode = str @@ -440,6 +444,10 @@ def _bootstrap(self, **overrides): self.bin = path.dirname(self.script) self.home = os.environ.get('HOME', None) + # Set fips_mode only if ipaplatform module was loaded + if tasks is not None: + self.fips_mode = tasks.is_fips_enabled() + # Merge in overrides: self._merge(**overrides) From c149adbe68d6c28c0cdbefe652b4d1b2eb57782f Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Wed, 8 Feb 2017 16:53:44 +0100 Subject: [PATCH 2/5] test_config: fix tests for env.fips_mode Add optional key fips_mode to Env object in tests. https://fedorahosted.org/freeipa/ticket/5695 --- ipatests/test_ipalib/test_config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ipatests/test_ipalib/test_config.py b/ipatests/test_ipalib/test_config.py index 1df9a39..5ef4487 100644 --- a/ipatests/test_ipalib/test_config.py +++ b/ipatests/test_ipalib/test_config.py @@ -562,6 +562,7 @@ def test_finalize_core(self): # Test using DEFAULT_CONFIG: defaults = dict(constants.DEFAULT_CONFIG) + defaults['fips_mode'] = None (o, home) = self.finalize_core(None, **defaults) assert list(o) == sorted(defaults) for (key, value) in defaults.items(): From 957f6dd533b507243ffcc8fa573aa86e2fe962e0 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Mon, 6 Feb 2017 17:17:49 +0100 Subject: [PATCH 3/5] check_remote_version: update exception and docstring Refactor function to use ScriptError exception and provide docstring. --- ipaserver/install/server/replicainstall.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 0d3a69f..783a716 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -512,6 +512,13 @@ def promote_openldap_conf(hostname, master): def check_remote_version(api): + """ + Perform a check to verify remote server's version + + :param api: remote API + + :raises: ``ScriptError`` if the checks fails + """ client = rpc.jsonclient(api) client.finalize() @@ -524,7 +531,7 @@ def check_remote_version(api): remote_version = parse_version(env['version']) api_version = parse_version(api.env.version) if remote_version > api_version: - raise RuntimeError( + raise ScriptError( "Cannot install replica of a server of higher version ({}) than" "the local version ({})".format(remote_version, api_version)) From 183de2e6f7af61b5777a666ac24aa9dfec1d5a8b Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Tue, 7 Feb 2017 10:42:54 +0100 Subject: [PATCH 4/5] replicainstall: add context manager for rpc client Abstract creating rpc client into a context manager to allow re-use. --- ipaserver/install/server/replicainstall.py | 33 ++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 783a716..216ed55 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -4,6 +4,7 @@ from __future__ import print_function +import contextlib import dns.exception as dnsexception import dns.name as dnsname import dns.resolver as dnsresolver @@ -511,29 +512,37 @@ def promote_openldap_conf(hostname, master): root_logger.info("Failed to update {}: {}".format(ldap_conf, e)) -def check_remote_version(api): +@contextlib.contextmanager +def rpc_client(api): """ - Perform a check to verify remote server's version + Context manager for JSON RPC client. - :param api: remote API - - :raises: ``ScriptError`` if the checks fails + :param api: api to initiate the RPC client """ client = rpc.jsonclient(api) client.finalize() - client.connect() + try: - env = client.forward(u'env', u'version')['result'] + yield client finally: client.disconnect() + +def check_remote_version(client, local_version): + """ + Verify remote server's version is not higher than this server's version + + :param client: RPC client + :param local_version: API version of local server + :raises: ScriptError: if the checks fails + """ + env = client.forward(u'env', u'version')['result'] remote_version = parse_version(env['version']) - api_version = parse_version(api.env.version) - if remote_version > api_version: + if remote_version > local_version: raise ScriptError( "Cannot install replica of a server of higher version ({}) than" - "the local version ({})".format(remote_version, api_version)) + "the local version ({})".format(remote_version, local_version)) def common_check(no_ntp): @@ -745,6 +754,7 @@ def install_check(installer): ldap_uri=ldapuri) remote_api.finalize() installer._remote_api = remote_api + conn = remote_api.Backend.ldap2 replman = None try: @@ -1083,7 +1093,8 @@ def promote_check(installer): remote_api.finalize() installer._remote_api = remote_api - check_remote_version(remote_api) + with rpc_client(remote_api) as client: + check_remote_version(client, api.env.version) conn = remote_api.Backend.ldap2 replman = None From 144bbed3c30c9204f526ef08ae27214603d789c4 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Tue, 7 Feb 2017 12:00:09 +0100 Subject: [PATCH 5/5] FIPS: perform replica installation check Check status of remote server's FIPS mode and proceed with installation only if it matches the current replica's FIPS mode. https://fedorahosted.org/freeipa/ticket/5695 --- ipaserver/install/server/replicainstall.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 216ed55..e8b8185 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -529,6 +529,27 @@ def rpc_client(api): client.disconnect() +def check_remote_fips_mode(client, local_fips_mode): + """ + Verify remote server's fips-mode is the same as this server's fips-mode + + :param client: RPC client + :param local_fips_mode: boolean indicating whether FIPS mode is turned on + :raises: ScriptError: if the checks fails + """ + env = client.forward(u'env', u'fips_mode')['result'] + remote_fips_mode = env.get('fips_mode', False) + if local_fips_mode != remote_fips_mode: + if local_fips_mode: + raise ScriptError( + "Cannot join FIPS-enabled replica into existing topology: " + "FIPS is not enabled on the master server.") + else: + raise ScriptError( + "Cannot join replica into existing FIPS-enabled topology: " + "FIPS has to be enabled locally first.") + + def check_remote_version(client, local_version): """ Verify remote server's version is not higher than this server's version @@ -1095,6 +1116,7 @@ def promote_check(installer): with rpc_client(remote_api) as client: check_remote_version(client, api.env.version) + check_remote_fips_mode(client, api.env.fips_mode) conn = remote_api.Backend.ldap2 replman = None
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code