diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 6c84e928b..cc7b03046 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -36,6 +36,7 @@ import syslog import time import tempfile from configparser import RawConfigParser +from pkg_resources import parse_version from ipalib import api from ipalib import x509 @@ -428,7 +429,8 @@ class CAInstance(DogtagInstance): if promote: self.step("destroying installation admin user", self.teardown_admin) - self.step("deploying ACME service", self.setup_acme) + if minimum_acme_support(): + self.step("deploying ACME service", self.setup_acme) # Materialize config changes and new ACLs self.step("starting certificate server instance", self.start_instance) @@ -768,11 +770,10 @@ class CAInstance(DogtagInstance): self.basedn) conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember') - group_dn = DN(('cn', ACME_AGENT_GROUP), ('ou', 'groups'), - self.basedn) - conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember') - - conn.disconnect() + if minimum_acme_support(): + group_dn = DN(('cn', ACME_AGENT_GROUP), ('ou', 'groups'), + self.basedn) + conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember') def __get_ca_chain(self): try: @@ -1485,6 +1486,9 @@ class CAInstance(DogtagInstance): logger.debug('ACME service is already deployed') return False + if not minimum_acme_support(): + return False + self._ldap_mod('/usr/share/pki/acme/database/ds/schema.ldif') configure_acme_acls() @@ -1727,6 +1731,33 @@ def ensure_lightweight_cas_container(): ) +def minimum_acme_support(data=None): + """ + ACME with global enable/disable is required. + + This first shipped in dogtag version 10.10.0. + + Parse the version string to determine if the minimum version + is met. If parsing fails return False. + + :param: data: The string value to parse for version. Defaults to + reading from the filesystem. + """ + if not data: + with open('/usr/share/pki/VERSION', 'r') as fd: + data = fd.read() + + groups = re.match(r'.*\nSpecification-Version: ([\d+\.]*)\n.*', data) + if groups: + version_string = groups.groups(0)[0] + minimum_version = parse_version('10.10.0') + + return parse_version(version_string) >= minimum_version + else: + logger.debug('Unable to parse version from %s', data) + return False + + def ensure_acme_containers(): """ Create the ACME container objects under ou=acme,o=ipaca if diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py index 9185aba81..9d06dd035 100644 --- a/ipatests/test_integration/test_acme.py +++ b/ipatests/test_integration/test_acme.py @@ -12,6 +12,7 @@ from ipalib.constants import IPA_CA_RECORD from ipatests.test_integration.base import IntegrationTest from ipatests.pytest_ipa.integration import tasks from ipaplatform.osinfo import osinfo +from ipaserver.install import cainstance # RHEL does not have certbot. EPEL's version is broken with @@ -26,6 +27,8 @@ skip_mod_md_tests = osinfo.id not in ['rhel','fedora',] CERTBOT_DNS_IPA_SCRIPT = '/usr/libexec/ipa/acme/certbot-dns-ipa' +@pytest.mark.skipif(not cainstance.minimum_acme_support(), + reason="does not provide ACME") class TestACME(IntegrationTest): """ Test the FreeIPA ACME service by using ACME clients on a FreeIPA client.