From d0d29ccc324bb9f95bffbe3162ee5c3c61c6086a Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Thu, 11 Jul 2019 15:17:04 +1000
Subject: [PATCH] move MSCSTemplate classes to ipalib
As we expand the integration tests for external CA functionality, it
is helpful (and avoids duplication) to use the MSCSTemplate*
classes. These currently live in ipaserver.install.cainstance, but
ipatests is no longer permitted to import from ipaserver (see commit
81714976e5e13131654c78eb734746a20237c933). So move these classes to
ipalib.
Part of: https://pagure.io/freeipa/issue/7548
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
install/tools/ipa-ca-install.in | 6 +-
ipalib/x509.py | 171 +++++++++++++++++
ipaserver/install/ca.py | 11 +-
ipaserver/install/cainstance.py | 180 +-----------------
ipaserver/install/ipa_cacert_manage.py | 14 +-
ipatests/test_integration/test_external_ca.py | 11 +-
ipatests/test_ipalib/test_x509.py | 115 +++++++++++
.../test_install/test_cainstance.py | 123 ------------
8 files changed, 307 insertions(+), 324 deletions(-)
delete mode 100644 ipatests/test_ipaserver/test_install/test_cainstance.py
diff --git a/install/tools/ipa-ca-install.in b/install/tools/ipa-ca-install.in
index 0700c0c38b..ce6d5fcb52 100644
--- a/install/tools/ipa-ca-install.in
+++ b/install/tools/ipa-ca-install.in
@@ -37,7 +37,7 @@ from ipaserver.install import cainstance, service
from ipaserver.install import custodiainstance
from ipaserver.masters import find_providing_server
from ipapython import version
-from ipalib import api
+from ipalib import api, x509
from ipalib.constants import DOMAIN_LEVEL_1
from ipapython.config import IPAOptionParser
from ipapython.ipa_log_manager import standard_logging_setup
@@ -68,13 +68,13 @@ def parse_options():
default=False, help="unattended installation never prompts the user")
parser.add_option("--external-ca", dest="external_ca", action="store_true",
default=False, help="Generate a CSR to be signed by an external CA")
- ext_cas = tuple(x.value for x in cainstance.ExternalCAType)
+ ext_cas = tuple(x.value for x in x509.ExternalCAType)
parser.add_option("--external-ca-type", dest="external_ca_type",
type="choice", choices=ext_cas,
metavar="{{{0}}}".format(",".join(ext_cas)),
help="Type of the external CA. Default: generic")
parser.add_option("--external-ca-profile", dest="external_ca_profile",
- type='constructor', constructor=cainstance.ExternalCAProfile,
+ type='constructor', constructor=x509.ExternalCAProfile,
default=None, metavar="PROFILE-SPEC",
help="Specify the certificate profile/template to use "
"at the external CA")
diff --git a/ipalib/x509.py b/ipalib/x509.py
index ab3c5f553d..1f612a3797 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -34,6 +34,7 @@
import os
import binascii
import datetime
+import enum
import ipaddress
import ssl
import base64
@@ -47,6 +48,7 @@
Encoding, PublicFormat, PrivateFormat, load_pem_private_key
)
import pyasn1
+import pyasn1.error
from pyasn1.type import univ, char, namedtype, tag
from pyasn1.codec.der import decoder, encoder
from pyasn1_modules import rfc2315, rfc2459
@@ -745,3 +747,172 @@ def format_datetime(t):
if t.tzinfo is None:
t = t.replace(tzinfo=UTC())
return unicode(t.strftime("%a %b %d %H:%M:%S %Y %Z"))
+
+
+class ExternalCAType(enum.Enum):
+ GENERIC = 'generic'
+ MS_CS = 'ms-cs'
+
+
+class ExternalCAProfile:
+ """
+ An external CA profile configuration. Currently the only
+ subclasses are for Microsoft CAs, for providing data in the
+ "Certificate Template" extension.
+
+ Constructing this class will actually return an instance of a
+ subclass.
+
+ Subclasses MUST set ``valid_for``.
+
+ """
+ def __init__(self, s=None):
+ self.unparsed_input = s
+
+ # Which external CA types is the data valid for?
+ # A set of VALUES of the ExternalCAType enum.
+ valid_for = set()
+
+ def __new__(cls, s=None):
+ """Construct the ExternalCAProfile value.
+
+ Return an instance of a subclass determined by
+ the format of the argument.
+
+ """
+ # we are directly constructing a subclass; instantiate
+ # it and be done
+ if cls is not ExternalCAProfile:
+ return super(ExternalCAProfile, cls).__new__(cls)
+
+ # construction via the base class; therefore the string
+ # argument is required, and is used to determine which
+ # subclass to construct
+ if s is None:
+ raise ValueError('string argument is required')
+
+ parts = s.split(':')
+
+ try:
+ # Is the first part on OID?
+ _oid = univ.ObjectIdentifier(parts[0])
+
+ # It is; construct a V2 template
+ # pylint: disable=too-many-function-args
+ return MSCSTemplateV2.__new__(MSCSTemplateV2, s)
+
+ except pyasn1.error.PyAsn1Error:
+ # It is not an OID; treat as a template name
+ # pylint: disable=too-many-function-args
+ return MSCSTemplateV1.__new__(MSCSTemplateV1, s)
+
+ def __getstate__(self):
+ return self.unparsed_input
+
+ def __setstate__(self, state):
+ # explicitly call __init__ method to initialise object
+ self.__init__(state)
+
+
+class MSCSTemplate(ExternalCAProfile):
+ """
+ An Microsoft AD-CS Template specifier.
+
+ Subclasses MUST set ext_oid.
+
+ Subclass constructors MUST set asn1obj.
+
+ """
+ valid_for = set([ExternalCAType.MS_CS.value])
+
+ ext_oid = None # extension OID, as a Python str
+ asn1obj = None # unencoded extension data
+
+ def get_ext_data(self):
+ """Return DER-encoded extension data."""
+ return encoder.encode(self.asn1obj)
+
+
+class MSCSTemplateV1(MSCSTemplate):
+ """
+ A v1 template specifier, per
+ https://msdn.microsoft.com/en-us/library/cc250011.aspx.
+
+ ::
+
+ CertificateTemplateName ::= SEQUENCE {
+ Name UTF8String
+ }
+
+ But note that a bare BMPString is used in practice.
+
+ """
+ ext_oid = "1.3.6.1.4.1.311.20.2"
+
+ def __init__(self, s):
+ super(MSCSTemplateV1, self).__init__(s)
+ parts = s.split(':')
+ if len(parts) > 1:
+ raise ValueError(
+ "Cannot specify certificate template version when using name.")
+ self.asn1obj = char.BMPString(str(parts[0]))
+
+
+class MSCSTemplateV2(MSCSTemplate):
+ """
+ A v2 template specifier, per
+ https://msdn.microsoft.com/en-us/library/windows/desktop/aa378274(v=vs.85).aspx
+
+ ::
+
+ CertificateTemplate ::= SEQUENCE {
+ templateID EncodedObjectID,
+ templateMajorVersion TemplateVersion,
+ templateMinorVersion TemplateVersion OPTIONAL
+ }
+
+ TemplateVersion ::= INTEGER (0..4294967295)
+
+ """
+ ext_oid = "1.3.6.1.4.1.311.21.7"
+
+ @staticmethod
+ def check_version_in_range(desc, n):
+ if n < 0 or n >= 2**32:
+ raise ValueError(
+ "Template {} version must be in range 0..4294967295"
+ .format(desc))
+
+ def __init__(self, s):
+ super(MSCSTemplateV2, self).__init__(s)
+
+ parts = s.split(':')
+
+ obj = CertificateTemplateV2()
+ if len(parts) < 2 or len(parts) > 3:
+ raise ValueError(
+ "Incorrect template specification; required format is: "
+ "<oid>:<majorVersion>[:<minorVersion>]")
+ try:
+ obj['templateID'] = univ.ObjectIdentifier(parts[0])
+
+ major = int(parts[1])
+ self.check_version_in_range("major", major)
+ obj['templateMajorVersion'] = major
+
+ if len(parts) > 2:
+ minor = int(parts[2])
+ self.check_version_in_range("minor", minor)
+ obj['templateMinorVersion'] = int(parts[2])
+
+ except pyasn1.error.PyAsn1Error:
+ raise ValueError("Could not parse certificate template specifier.")
+ self.asn1obj = obj
+
+
+class CertificateTemplateV2(univ.Sequence):
+ componentType = namedtype.NamedTypes(
+ namedtype.NamedType('templateID', univ.ObjectIdentifier()),
+ namedtype.NamedType('templateMajorVersion', univ.Integer()),
+ namedtype.OptionalNamedType('templateMinorVersion', univ.Integer())
+ )
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index 6b040b311a..8fb5e3ec91 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -28,7 +28,7 @@
from ipaplatform.paths import paths
from ipaserver.install import installutils, certs
from ipaserver.install.replication import replica_conn_check
-from ipalib import api, errors
+from ipalib import api, errors, x509
from ipapython.dn import DN
from . import conncheck, dogtag, cainstance
@@ -216,8 +216,7 @@ def install_check(standalone, replica_config, options):
paths.ROOT_IPA_CSR)
if not options.external_ca_type:
- options.external_ca_type = \
- cainstance.ExternalCAType.GENERIC.value
+ options.external_ca_type = x509.ExternalCAType.GENERIC.value
if options.external_ca_profile is not None:
# check that profile is valid for the external ca type
@@ -478,13 +477,11 @@ class CAInstallInterface(dogtag.DogtagInstallInterface,
external_ca = master_install_only(external_ca)
external_ca_type = knob(
- cainstance.ExternalCAType, None,
- description="Type of the external CA",
- )
+ x509.ExternalCAType, None, description="Type of the external CA")
external_ca_type = master_install_only(external_ca_type)
external_ca_profile = knob(
- type=cainstance.ExternalCAProfile,
+ type=x509.ExternalCAProfile,
default=None,
description=(
"Specify the certificate profile/template to use at the "
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 6e1fc724db..2295581870 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -26,7 +26,6 @@
import logging
import dbus
-import enum
import ldap
import os
import pwd
@@ -39,10 +38,6 @@
import tempfile
from configparser import RawConfigParser
-from pyasn1.codec.der import encoder
-from pyasn1.type import char, univ, namedtype
-import pyasn1.error
-
from ipalib import api
from ipalib import x509
from ipalib import errors
@@ -80,11 +75,6 @@
]
-class ExternalCAType(enum.Enum):
- GENERIC = 'generic'
- MS_CS = 'ms-cs'
-
-
def check_ports():
"""Check that dogtag ports (8080, 8443) are available.
@@ -367,7 +357,7 @@ def configure_instance(self, host_name, dm_password, admin_password,
if ca_type is not None:
self.ca_type = ca_type
else:
- self.ca_type = ExternalCAType.GENERIC.value
+ self.ca_type = x509.ExternalCAType.GENERIC.value
self.external_ca_profile = external_ca_profile
self.no_db_setup = promote
@@ -537,12 +527,12 @@ def __spawn_instance(self):
pki_ca_signing_csr_path=self.csr_file,
)
- if self.ca_type == ExternalCAType.MS_CS.value:
+ if self.ca_type == x509.ExternalCAType.MS_CS.value:
# Include MS template name extension in the CSR
template = self.external_ca_profile
if template is None:
# default template name
- template = MSCSTemplateV1(u"SubCA")
+ template = x509.MSCSTemplateV1(u"SubCA")
ext_data = binascii.hexlify(template.get_ext_data())
cfg.update(
@@ -2081,170 +2071,6 @@ def update_ipa_conf():
parser.write(f)
-class ExternalCAProfile:
- """
- An external CA profile configuration. Currently the only
- subclasses are for Microsoft CAs, for providing data in the
- "Certificate Template" extension.
-
- Constructing this class will actually return an instance of a
- subclass.
-
- Subclasses MUST set ``valid_for``.
-
- """
- def __init__(self, s=None):
- self.unparsed_input = s
-
- # Which external CA types is the data valid for?
- # A set of VALUES of the ExternalCAType enum.
- valid_for = set()
-
- def __new__(cls, s=None):
- """Construct the ExternalCAProfile value.
-
- Return an instance of a subclass determined by
- the format of the argument.
-
- """
- # we are directly constructing a subclass; instantiate
- # it and be done
- if cls is not ExternalCAProfile:
- return super(ExternalCAProfile, cls).__new__(cls)
-
- # construction via the base class; therefore the string
- # argument is required, and is used to determine which
- # subclass to construct
- if s is None:
- raise ValueError('string argument is required')
-
- parts = s.split(':')
-
- try:
- # Is the first part on OID?
- _oid = univ.ObjectIdentifier(parts[0])
-
- # It is; construct a V2 template
- # pylint: disable=too-many-function-args
- return MSCSTemplateV2.__new__(MSCSTemplateV2, s)
-
- except pyasn1.error.PyAsn1Error:
- # It is not an OID; treat as a template name
- # pylint: disable=too-many-function-args
- return MSCSTemplateV1.__new__(MSCSTemplateV1, s)
-
- def __getstate__(self):
- return self.unparsed_input
-
- def __setstate__(self, state):
- # explicitly call __init__ method to initialise object
- self.__init__(state)
-
-
-class MSCSTemplate(ExternalCAProfile):
- """
- An Microsoft AD-CS Template specifier.
-
- Subclasses MUST set ext_oid.
-
- Subclass constructors MUST set asn1obj.
-
- """
- valid_for = set([ExternalCAType.MS_CS.value])
-
- ext_oid = None # extension OID, as a Python str
- asn1obj = None # unencoded extension data
-
- def get_ext_data(self):
- """Return DER-encoded extension data."""
- return encoder.encode(self.asn1obj)
-
-
-class MSCSTemplateV1(MSCSTemplate):
- """
- A v1 template specifier, per
- https://msdn.microsoft.com/en-us/library/cc250011.aspx.
-
- ::
-
- CertificateTemplateName ::= SEQUENCE {
- Name UTF8String
- }
-
- But note that a bare BMPString is used in practice.
-
- """
- ext_oid = "1.3.6.1.4.1.311.20.2"
-
- def __init__(self, s):
- super(MSCSTemplateV1, self).__init__(s)
- parts = s.split(':')
- if len(parts) > 1:
- raise ValueError(
- "Cannot specify certificate template version when using name.")
- self.asn1obj = char.BMPString(str(parts[0]))
-
-
-class MSCSTemplateV2(MSCSTemplate):
- """
- A v2 template specifier, per
- https://msdn.microsoft.com/en-us/library/windows/desktop/aa378274(v=vs.85).aspx
-
- ::
-
- CertificateTemplate ::= SEQUENCE {
- templateID EncodedObjectID,
- templateMajorVersion TemplateVersion,
- templateMinorVersion TemplateVersion OPTIONAL
- }
-
- TemplateVersion ::= INTEGER (0..4294967295)
-
- """
- ext_oid = "1.3.6.1.4.1.311.21.7"
-
- @staticmethod
- def check_version_in_range(desc, n):
- if n < 0 or n >= 2**32:
- raise ValueError(
- "Template {} version must be in range 0..4294967295"
- .format(desc))
-
- def __init__(self, s):
- super(MSCSTemplateV2, self).__init__(s)
-
- parts = s.split(':')
-
- obj = CertificateTemplateV2()
- if len(parts) < 2 or len(parts) > 3:
- raise ValueError(
- "Incorrect template specification; required format is: "
- "<oid>:<majorVersion>[:<minorVersion>]")
- try:
- obj['templateID'] = univ.ObjectIdentifier(parts[0])
-
- major = int(parts[1])
- self.check_version_in_range("major", major)
- obj['templateMajorVersion'] = major
-
- if len(parts) > 2:
- minor = int(parts[2])
- self.check_version_in_range("minor", minor)
- obj['templateMinorVersion'] = int(parts[2])
-
- except pyasn1.error.PyAsn1Error:
- raise ValueError("Could not parse certificate template specifier.")
- self.asn1obj = obj
-
-
-class CertificateTemplateV2(univ.Sequence):
- componentType = namedtype.NamedTypes(
- namedtype.NamedType('templateID', univ.ObjectIdentifier()),
- namedtype.NamedType('templateMajorVersion', univ.Integer()),
- namedtype.OptionalNamedType('templateMinorVersion', univ.Integer())
- )
-
-
if __name__ == "__main__":
standard_logging_setup("install.log")
ds = dsinstance.DsInstance()
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
index 3f113c35bf..37dcc2befa 100644
--- a/ipaserver/install/ipa_cacert_manage.py
+++ b/ipaserver/install/ipa_cacert_manage.py
@@ -65,7 +65,7 @@ def add_options(cls, parser):
"--external-ca", dest='self_signed',
action='store_false',
help="Sign the renewed certificate by external CA")
- ext_cas = tuple(x.value for x in cainstance.ExternalCAType)
+ ext_cas = tuple(x.value for x in x509.ExternalCAType)
renew_group.add_option(
"--external-ca-type", dest="external_ca_type",
type="choice", choices=ext_cas,
@@ -73,7 +73,7 @@ def add_options(cls, parser):
help="Type of the external CA. Default: generic")
renew_group.add_option(
"--external-ca-profile", dest="external_ca_profile",
- type='constructor', constructor=cainstance.ExternalCAProfile,
+ type='constructor', constructor=x509.ExternalCAProfile,
default=None, metavar="PROFILE-SPEC",
help="Specify the certificate profile/template to use "
"at the external CA")
@@ -224,11 +224,11 @@ def renew_external_step_1(self, ca):
options = self.options
if not options.external_ca_type:
- options.external_ca_type = cainstance.ExternalCAType.GENERIC.value
+ options.external_ca_type = x509.ExternalCAType.GENERIC.value
- if options.external_ca_type == cainstance.ExternalCAType.MS_CS.value \
+ if options.external_ca_type == x509.ExternalCAType.MS_CS.value \
and options.external_ca_profile is None:
- options.external_ca_profile = cainstance.MSCSTemplateV1(u"SubCA")
+ options.external_ca_profile = x509.MSCSTemplateV1(u"SubCA")
if options.external_ca_profile is not None:
# check that profile is valid for the external ca type
@@ -352,11 +352,11 @@ def resubmit_request(self, ca=RENEWAL_CA_NAME, profile=None):
timeout = api.env.startup_timeout + 60
cm_profile = None
- if isinstance(profile, cainstance.MSCSTemplateV1):
+ if isinstance(profile, x509.MSCSTemplateV1):
cm_profile = profile.unparsed_input
cm_template = None
- if isinstance(profile, cainstance.MSCSTemplateV2):
+ if isinstance(profile, x509.MSCSTemplateV2):
cm_template = profile.unparsed_input
logger.debug("resubmitting certmonger request '%s'", self.request_id)
diff --git a/ipatests/test_integration/test_external_ca.py b/ipatests/test_integration/test_external_ca.py
index a42355217d..5aa2b7bba0 100644
--- a/ipatests/test_integration/test_external_ca.py
+++ b/ipatests/test_integration/test_external_ca.py
@@ -108,14 +108,14 @@ def check_ipaca_issuerDN(host, expected_dn):
assert "Issuer DN: {}".format(expected_dn) in result.stdout_text
-def check_mscs_extension(ipa_csr, oid, value):
+def check_mscs_extension(ipa_csr, template):
csr = x509.load_pem_x509_csr(ipa_csr, default_backend())
extensions = [
ext for ext in csr.extensions
- if ext.oid.dotted_string == oid
+ if ext.oid.dotted_string == template.ext_oid
]
assert extensions
- assert extensions[0].value.value == value
+ assert extensions[0].value.value == template.get_ext_data()
class TestExternalCA(IntegrationTest):
@@ -134,10 +134,7 @@ def test_external_ca(self):
# check CSR for extension
ipa_csr = self.master.get_file_contents(paths.ROOT_IPA_CSR)
- # Values for MSCSTemplateV1('SubCA')
- oid = "1.3.6.1.4.1.311.20.2"
- value = b'\x1e\n\x00S\x00u\x00b\x00C\x00A'
- check_mscs_extension(ipa_csr, oid, value)
+ check_mscs_extension(ipa_csr, ipa_x509.MSCSTemplateV1(u'SubCA'))
# Sign CA, transport it to the host and get ipa a root ca paths.
root_ca_fname, ipa_ca_fname = tasks.sign_ca_and_transport(
diff --git a/ipatests/test_ipalib/test_x509.py b/ipatests/test_ipalib/test_x509.py
index ff7e6de2f7..284b998316 100644
--- a/ipatests/test_ipalib/test_x509.py
+++ b/ipatests/test_ipalib/test_x509.py
@@ -22,7 +22,11 @@
"""
import base64
+from binascii import hexlify
+from configparser import RawConfigParser
import datetime
+from io import StringIO
+import pickle
import pytest
@@ -268,3 +272,114 @@ def test_ipa_demo_letsencrypt(self):
b'0 \x06\x03U\x1d%\x01\x01\xff\x04\x160\x14\x06\x08+\x06\x01'
b'\x05\x05\x07\x03\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x02'
)
+
+
+class test_ExternalCAProfile:
+ def test_MSCSTemplateV1_good(self):
+ o = x509.MSCSTemplateV1("MySubCA")
+ assert hexlify(o.get_ext_data()) == b'1e0e004d007900530075006200430041'
+
+ def test_MSCSTemplateV1_bad(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV1("MySubCA:1")
+
+ def test_MSCSTemplateV1_pickle_roundtrip(self):
+ o = x509.MSCSTemplateV1("MySubCA")
+ s = pickle.dumps(o)
+ assert o.get_ext_data() == pickle.loads(s).get_ext_data()
+
+ def test_MSCSTemplateV2_too_few_parts(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("1.2.3.4")
+
+ def test_MSCSTemplateV2_too_many_parts(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("1.2.3.4:100:200:300")
+
+ def test_MSCSTemplateV2_bad_oid(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("not_an_oid:1")
+
+ def test_MSCSTemplateV2_non_numeric_major_version(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("1.2.3.4:major:200")
+
+ def test_MSCSTemplateV2_non_numeric_minor_version(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("1.2.3.4:100:minor")
+
+ def test_MSCSTemplateV2_major_version_lt_zero(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("1.2.3.4:-1:200")
+
+ def test_MSCSTemplateV2_minor_version_lt_zero(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("1.2.3.4:100:-1")
+
+ def test_MSCSTemplateV2_major_version_gt_max(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("1.2.3.4:4294967296:200")
+
+ def test_MSCSTemplateV2_minor_version_gt_max(self):
+ with pytest.raises(ValueError):
+ x509.MSCSTemplateV2("1.2.3.4:100:4294967296")
+
+ def test_MSCSTemplateV2_good_major(self):
+ o = x509.MSCSTemplateV2("1.2.3.4:4294967295")
+ assert hexlify(o.get_ext_data()) == b'300c06032a0304020500ffffffff'
+
+ def test_MSCSTemplateV2_good_major_minor(self):
+ o = x509.MSCSTemplateV2("1.2.3.4:4294967295:0")
+ assert hexlify(o.get_ext_data()) \
+ == b'300f06032a0304020500ffffffff020100'
+
+ def test_MSCSTemplateV2_pickle_roundtrip(self):
+ o = x509.MSCSTemplateV2("1.2.3.4:4294967295:0")
+ s = pickle.dumps(o)
+ assert o.get_ext_data() == pickle.loads(s).get_ext_data()
+
+ def test_ExternalCAProfile_dispatch(self):
+ """
+ Test that constructing ExternalCAProfile actually returns an
+ instance of the appropriate subclass.
+ """
+ assert isinstance(
+ x509.ExternalCAProfile("MySubCA"),
+ x509.MSCSTemplateV1)
+ assert isinstance(
+ x509.ExternalCAProfile("1.2.3.4:100"),
+ x509.MSCSTemplateV2)
+
+ def test_write_pkispawn_config_file_MSCSTemplateV1(self):
+ template = x509.MSCSTemplateV1(u"SubCA")
+ expected = (
+ '[CA]\n'
+ 'pki_req_ext_oid = 1.3.6.1.4.1.311.20.2\n'
+ 'pki_req_ext_data = 1e0a00530075006200430041\n\n'
+ )
+ self._test_write_pkispawn_config_file(template, expected)
+
+ def test_write_pkispawn_config_file_MSCSTemplateV2(self):
+ template = x509.MSCSTemplateV2(u"1.2.3.4:4294967295")
+ expected = (
+ '[CA]\n'
+ 'pki_req_ext_oid = 1.3.6.1.4.1.311.21.7\n'
+ 'pki_req_ext_data = 300c06032a0304020500ffffffff\n\n'
+ )
+ self._test_write_pkispawn_config_file(template, expected)
+
+ def _test_write_pkispawn_config_file(self, template, expected):
+ """
+ Test that the values we read from an ExternalCAProfile
+ object can be used to produce a reasonable-looking pkispawn
+ configuration.
+ """
+ config = RawConfigParser()
+ config.optionxform = str
+ config.add_section("CA")
+ config.set("CA", "pki_req_ext_oid", template.ext_oid)
+ config.set("CA", "pki_req_ext_data",
+ hexlify(template.get_ext_data()).decode('ascii'))
+ out = StringIO()
+ config.write(out)
+ assert out.getvalue() == expected
diff --git a/ipatests/test_ipaserver/test_install/test_cainstance.py b/ipatests/test_ipaserver/test_install/test_cainstance.py
deleted file mode 100644
index 02d9758e4a..0000000000
--- a/ipatests/test_ipaserver/test_install/test_cainstance.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# Copyright (C) 2017 FreeIPA Contributors see COPYING for license
-#
-
-from binascii import hexlify
-from io import StringIO
-import pickle
-from configparser import RawConfigParser
-import pytest
-from ipaserver.install import cainstance
-
-pytestmark = pytest.mark.tier0
-
-
-class test_ExternalCAProfile:
- def test_MSCSTemplateV1_good(self):
- o = cainstance.MSCSTemplateV1("MySubCA")
- assert hexlify(o.get_ext_data()) == b'1e0e004d007900530075006200430041'
-
- def test_MSCSTemplateV1_bad(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV1("MySubCA:1")
-
- def test_MSCSTemplateV1_pickle_roundtrip(self):
- o = cainstance.MSCSTemplateV1("MySubCA")
- s = pickle.dumps(o)
- assert o.get_ext_data() == pickle.loads(s).get_ext_data()
-
- def test_MSCSTemplateV2_too_few_parts(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("1.2.3.4")
-
- def test_MSCSTemplateV2_too_many_parts(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("1.2.3.4:100:200:300")
-
- def test_MSCSTemplateV2_bad_oid(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("not_an_oid:1")
-
- def test_MSCSTemplateV2_non_numeric_major_version(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("1.2.3.4:major:200")
-
- def test_MSCSTemplateV2_non_numeric_minor_version(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("1.2.3.4:100:minor")
-
- def test_MSCSTemplateV2_major_version_lt_zero(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("1.2.3.4:-1:200")
-
- def test_MSCSTemplateV2_minor_version_lt_zero(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("1.2.3.4:100:-1")
-
- def test_MSCSTemplateV2_major_version_gt_max(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("1.2.3.4:4294967296:200")
-
- def test_MSCSTemplateV2_minor_version_gt_max(self):
- with pytest.raises(ValueError):
- cainstance.MSCSTemplateV2("1.2.3.4:100:4294967296")
-
- def test_MSCSTemplateV2_good_major(self):
- o = cainstance.MSCSTemplateV2("1.2.3.4:4294967295")
- assert hexlify(o.get_ext_data()) == b'300c06032a0304020500ffffffff'
-
- def test_MSCSTemplateV2_good_major_minor(self):
- o = cainstance.MSCSTemplateV2("1.2.3.4:4294967295:0")
- assert hexlify(o.get_ext_data()) \
- == b'300f06032a0304020500ffffffff020100'
-
- def test_MSCSTemplateV2_pickle_roundtrip(self):
- o = cainstance.MSCSTemplateV2("1.2.3.4:4294967295:0")
- s = pickle.dumps(o)
- assert o.get_ext_data() == pickle.loads(s).get_ext_data()
-
- def test_ExternalCAProfile_dispatch(self):
- """
- Test that constructing ExternalCAProfile actually returns an
- instance of the appropriate subclass.
- """
- assert isinstance(
- cainstance.ExternalCAProfile("MySubCA"),
- cainstance.MSCSTemplateV1)
- assert isinstance(
- cainstance.ExternalCAProfile("1.2.3.4:100"),
- cainstance.MSCSTemplateV2)
-
- def test_write_pkispawn_config_file_MSCSTemplateV1(self):
- template = cainstance.MSCSTemplateV1(u"SubCA")
- expected = (
- '[CA]\n'
- 'pki_req_ext_oid = 1.3.6.1.4.1.311.20.2\n'
- 'pki_req_ext_data = 1e0a00530075006200430041\n\n'
- )
- self._test_write_pkispawn_config_file(template, expected)
-
- def test_write_pkispawn_config_file_MSCSTemplateV2(self):
- template = cainstance.MSCSTemplateV2(u"1.2.3.4:4294967295")
- expected = (
- '[CA]\n'
- 'pki_req_ext_oid = 1.3.6.1.4.1.311.21.7\n'
- 'pki_req_ext_data = 300c06032a0304020500ffffffff\n\n'
- )
- self._test_write_pkispawn_config_file(template, expected)
-
- def _test_write_pkispawn_config_file(self, template, expected):
- """
- Test that the values we read from an ExternalCAProfile
- object can be used to produce a reasonable-looking pkispawn
- configuration.
- """
- config = RawConfigParser()
- config.optionxform = str
- config.add_section("CA")
- config.set("CA", "pki_req_ext_oid", template.ext_oid)
- config.set("CA", "pki_req_ext_data",
- hexlify(template.get_ext_data()).decode('ascii'))
- out = StringIO()
- config.write(out)
- assert out.getvalue() == expected
From e632b220798833bcd65c6b266610c800ed0914d7 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Fri, 12 Jul 2019 13:13:02 +1000
Subject: [PATCH] install: fix --external-ca-profile option
Commit dd47cfc75a69618f486abefb70f2649ebf8264e7 removed the ability
to set pki_req_ext_oid and pki_req_ext_data in the pkispawn config.
This results in the --external-ca-profile option never setting the
requested values in the CSR (the default V1 template type specifying
"SubCA" is always used).
Remove relevant fields from both ipaca_default.ini and
ipaca_customize.ini. This allows the IPA framework to set the
values (i.e. when --external-ca-type=ms-cs and
--external-ca-profile=... demand it). It also allows users to
override the pki_req_ext_* settings.
Part of: https://pagure.io/freeipa/issue/7548
Related: https://pagure.io/freeipa/issue/5608
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
install/share/ipaca_customize.ini | 5 -----
install/share/ipaca_default.ini | 1 -
2 files changed, 6 deletions(-)
diff --git a/install/share/ipaca_customize.ini b/install/share/ipaca_customize.ini
index 130ec2c102..6d58579af8 100644
--- a/install/share/ipaca_customize.ini
+++ b/install/share/ipaca_customize.ini
@@ -93,11 +93,6 @@ pki_ca_signing_key_type=%(ipa_ca_key_type)s
pki_ca_signing_signing_algorithm=%(ipa_ca_signing_algorithm)s
pki_ca_signing_token=%(pki_token_name)s
-# MS subca request ext data
-pki_req_ext_oid=1.3.6.1.4.1.311.20.2
-pki_req_ext_critical=False
-pki_req_ext_data=1E0A00530075006200430041
-
## ocspSigningCert cert-pki-ca
pki_ocsp_signing_key_algorithm=%(ipa_key_algorithm)s
pki_ocsp_signing_key_size=%(ipa_key_size)s
diff --git a/install/share/ipaca_default.ini b/install/share/ipaca_default.ini
index fedc1b9a74..2b9900286e 100644
--- a/install/share/ipaca_default.ini
+++ b/install/share/ipaca_default.ini
@@ -115,7 +115,6 @@ pki_ca_starting_crl_number=0
pki_external=False
pki_external_step_two=False
-pki_req_ext_add=False
pki_external_pkcs12_path=%(pki_pkcs12_path)s
pki_external_pkcs12_password=%(pki_pkcs12_password)s
From 71af731b3069fa1b2c0b51a3b917b5bc4da54350 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Fri, 12 Jul 2019 13:24:51 +1000
Subject: [PATCH] Fix use of incorrect variable
Part of: https://pagure.io/freeipa/issue/7548
Related: https://pagure.io/freeipa/issue/5608
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipaserver/install/dogtaginstance.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
index cc75d89746..5dca721d6c 100644
--- a/ipaserver/install/dogtaginstance.py
+++ b/ipaserver/install/dogtaginstance.py
@@ -853,7 +853,7 @@ def _verify_immutable(self, config, immutable_settings, filename):
if errs:
raise ValueError(
'{} overrides immutable options:\n{}'.format(
- filename, '\n'.join(errors)
+ filename, '\n'.join(errs)
)
)
From 83ed05725110de19a7098678274ecaaaf6a2c9c9 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <frase@frase.id.au>
Date: Wed, 20 Feb 2019 18:34:33 +1100
Subject: [PATCH] Add more tests for --external-ca-profile handling
Add tests for remaining untested scenarios of --external-ca-profile
handling in ipa-server-install.
ipa-ca-install and ipa-cacert-manage remain untested at present.
Fixes: https://pagure.io/freeipa/issue/7548
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_external_ca.py | 97 ++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/ipatests/test_integration/test_external_ca.py b/ipatests/test_integration/test_external_ca.py
index 5aa2b7bba0..dc9a09b43b 100644
--- a/ipatests/test_integration/test_external_ca.py
+++ b/ipatests/test_integration/test_external_ca.py
@@ -74,10 +74,10 @@ def match_in_journal(host, string, since='today', services=('certmonger',)):
return match
-def install_server_external_ca_step1(host, extra_args=()):
+def install_server_external_ca_step1(host, extra_args=(), raiseonerr=True):
"""Step 1 to install the ipa server with external ca"""
return tasks.install_master(
- host, external_ca=True, extra_args=extra_args
+ host, external_ca=True, extra_args=extra_args, raiseonerr=raiseonerr,
)
@@ -478,3 +478,96 @@ def test_master_install_ca2(self):
'certutil', '-L', '-d', paths.PKI_TOMCAT_ALIAS_DIR,
'-n', cert_nick])
assert "CN=RootCA2" in result.stdout_text
+
+
+def _step1_profile(master, s):
+ return install_server_external_ca_step1(
+ master,
+ extra_args=['--external-ca-type=ms-cs', f'--external-ca-profile={s}'],
+ raiseonerr=False,
+ )
+
+
+def _test_invalid_profile(master, profile):
+ result = _step1_profile(master, profile)
+ assert result.returncode != 0
+ assert '--external-ca-profile' in result.stderr_text
+
+
+def _test_valid_profile(master, profile_cls, profile):
+ result = _step1_profile(master, profile)
+ assert result.returncode == 0
+ ipa_csr = master.get_file_contents(paths.ROOT_IPA_CSR)
+ check_mscs_extension(ipa_csr, profile_cls(profile))
+
+
+class TestExternalCAProfileV1(IntegrationTest):
+ """
+ Test that --external-ca-profile=Foo gets propagated to the CSR.
+
+ The default template extension when --external-ca-type=ms-cs,
+ a V1 extension with value "SubCA", already gets tested by the
+ ``TestExternalCA`` class.
+
+ We only need to do Step 1 of installation, then check the CSR.
+
+ """
+ def test_invalid_v1_template(self):
+ _test_invalid_profile(self.master, 'NotAnOid:1')
+
+ def test_valid_v1_template(self):
+ _test_valid_profile(
+ self.master, ipa_x509.MSCSTemplateV1, 'TemplateOfAwesome')
+
+
+class TestExternalCAProfileV2MajorOnly(IntegrationTest):
+ """
+ Test that V2 template specifiers without minor version get
+ propagated to CSR. This class also tests all error modes in
+ specifying a V2 template, those being:
+
+ - no major version specified
+ - too many parts specified (i.e. major, minor, and then some more)
+ - major version is not an int
+ - major version is negative
+ - minor version is not an int
+ - minor version is negative
+
+ We only need to do Step 1 of installation, then check the CSR.
+
+ """
+ def test_v2_template_too_few_parts(self):
+ _test_invalid_profile(self.master, '1.2.3.4')
+
+ def test_v2_template_too_many_parts(self):
+ _test_invalid_profile(self.master, '1.2.3.4:100:200:300')
+
+ def test_v2_template_major_version_not_int(self):
+ _test_invalid_profile(self.master, '1.2.3.4:wat:200')
+
+ def test_v2_template_major_version_negative(self):
+ _test_invalid_profile(self.master, '1.2.3.4:-1:200')
+
+ def test_v2_template_minor_version_not_int(self):
+ _test_invalid_profile(self.master, '1.2.3.4:100:wat')
+
+ def test_v2_template_minor_version_negative(self):
+ _test_invalid_profile(self.master, '1.2.3.4:100:-2')
+
+ def test_v2_template_valid_major_only(self):
+ _test_valid_profile(
+ self.master, ipa_x509.MSCSTemplateV2, '1.2.3.4:100')
+
+
+class TestExternalCAProfileV2MajorMinor(IntegrationTest):
+ """
+ Test that V2 template specifiers _with_ minor version get
+ propagated to CSR. All error modes of V2 template specifiers
+ were tested in ``TestExternalCAProfileV2Major``.
+
+ We only need to do Step 1 of installation, then check the CSR.
+
+ """
+ def test_v2_template_valid_major_minor(self):
+ _test_valid_profile(
+ self.master, ipa_x509.MSCSTemplateV2, '1.2.3.4:100:200')
From a627df87c31e4d8399bd9fab43c0c4772ddd8955 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Thu, 11 Jul 2019 20:22:33 +1000
Subject: [PATCH] Collapse --external-ca-profile tests into single class
To avoid having to spawn new CI hosts for each kind of
--external-ca-profile argument we are testing, collapse the three
separate test classes into one. Uninstall the half-installed IPA
after each section of tests.
This change is in response to review comment
https://github.com/freeipa/freeipa/pull/2852#pullrequestreview-220442170.
Part of: https://pagure.io/freeipa/issue/7548
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_external_ca.py | 34 ++++++++++++++-----
1 file changed, 26 insertions(+), 8 deletions(-)
diff --git a/ipatests/test_integration/test_external_ca.py b/ipatests/test_integration/test_external_ca.py
index dc9a09b43b..714aebd4a8 100644
--- a/ipatests/test_integration/test_external_ca.py
+++ b/ipatests/test_integration/test_external_ca.py
@@ -501,8 +501,18 @@ def _test_valid_profile(master, profile_cls, profile):
check_mscs_extension(ipa_csr, profile_cls(profile))
-class TestExternalCAProfileV1(IntegrationTest):
+class TestExternalCAProfileScenarios(IntegrationTest):
"""
+ Test the various --external-ca-profile scenarios.
+ This test is broken into sections, with each section first
+ testing invalid arguments, then a valid argument, and finally
+ uninstalling the half-installed IPA.
+
+ """
+
+ '''
+ Tranche 1: version 1 templates.
+
Test that --external-ca-profile=Foo gets propagated to the CSR.
The default template extension when --external-ca-type=ms-cs,
@@ -511,7 +521,7 @@ class TestExternalCAProfileV1(IntegrationTest):
We only need to do Step 1 of installation, then check the CSR.
- """
+ '''
def test_invalid_v1_template(self):
_test_invalid_profile(self.master, 'NotAnOid:1')
@@ -519,9 +529,12 @@ def test_valid_v1_template(self):
_test_valid_profile(
self.master, ipa_x509.MSCSTemplateV1, 'TemplateOfAwesome')
+ def test_uninstall_1(self):
+ tasks.uninstall_master(self.master)
+
+ '''
+ Tranche 2: V2 templates without minor version.
-class TestExternalCAProfileV2MajorOnly(IntegrationTest):
- """
Test that V2 template specifiers without minor version get
propagated to CSR. This class also tests all error modes in
specifying a V2 template, those being:
@@ -535,7 +548,7 @@ class TestExternalCAProfileV2MajorOnly(IntegrationTest):
We only need to do Step 1 of installation, then check the CSR.
- """
+ '''
def test_v2_template_too_few_parts(self):
_test_invalid_profile(self.master, '1.2.3.4')
@@ -558,16 +571,21 @@ def test_v2_template_valid_major_only(self):
_test_valid_profile(
self.master, ipa_x509.MSCSTemplateV2, '1.2.3.4:100')
+ def test_uninstall_2(self):
+ tasks.uninstall_master(self.master)
+
+ '''
+ Tranche 3: V2 templates with minor version.
-class TestExternalCAProfileV2MajorMinor(IntegrationTest):
- """
Test that V2 template specifiers _with_ minor version get
propagated to CSR. All error modes of V2 template specifiers
were tested in ``TestExternalCAProfileV2Major``.
We only need to do Step 1 of installation, then check the CSR.
- """
+ '''
def test_v2_template_valid_major_minor(self):
_test_valid_profile(
self.master, ipa_x509.MSCSTemplateV2, '1.2.3.4:100:200')
+
+ # this is the end; no need to uninstall.
From 740964c3c47fd2cd216c233d8d9df1840eaa01ee Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Thu, 11 Jul 2019 20:27:02 +1000
Subject: [PATCH] ci: add --external-ca-profile tests to nightly
Part of: https://pagure.io/freeipa/issue/7548
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/prci_definitions/nightly_f28.yaml | 12 ++++++++++++
ipatests/prci_definitions/nightly_f29.yaml | 12 ++++++++++++
ipatests/prci_definitions/nightly_master.yaml | 12 ++++++++++++
ipatests/prci_definitions/nightly_master_pki.yaml | 12 ++++++++++++
ipatests/prci_definitions/nightly_rawhide.yaml | 12 ++++++++++++
5 files changed, 60 insertions(+)
diff --git a/ipatests/prci_definitions/nightly_f28.yaml b/ipatests/prci_definitions/nightly_f28.yaml
index fe86730444..d1605e6b5c 100644
--- a/ipatests/prci_definitions/nightly_f28.yaml
+++ b/ipatests/prci_definitions/nightly_f28.yaml
@@ -75,6 +75,18 @@ jobs:
timeout: 3600
topology: *master_1repl
+ fedora-28/external_ca_templates:
+ requires: [fedora-28/build]
+ priority: 50
+ job:
+ class: RunPytest
+ args:
+ build_url: '{fedora-28/build_url}'
+ test_suite: test_integration/test_external_ca.py::TestExternalCAProfileScenarios
+ template: *ci-master-f28
+ timeout: 3600
+ topology: *master_1repl
+
fedora-28/test_topologies:
requires: [fedora-28/build]
priority: 50
diff --git a/ipatests/prci_definitions/nightly_f29.yaml b/ipatests/prci_definitions/nightly_f29.yaml
index 57c1b624fe..ed88eb15c8 100644
--- a/ipatests/prci_definitions/nightly_f29.yaml
+++ b/ipatests/prci_definitions/nightly_f29.yaml
@@ -75,6 +75,18 @@ jobs:
timeout: 3600
topology: *master_1repl
+ fedora-29/external_ca_templates:
+ requires: [fedora-29/build]
+ priority: 50
+ job:
+ class: RunPytest
+ args:
+ build_url: '{fedora-29/build_url}'
+ test_suite: test_integration/test_external_ca.py::TestExternalCAProfileScenarios
+ template: *ci-master-f29
+ timeout: 3600
+ topology: *master_1repl
+
fedora-29/test_topologies:
requires: [fedora-29/build]
priority: 50
diff --git a/ipatests/prci_definitions/nightly_master.yaml b/ipatests/prci_definitions/nightly_master.yaml
index dc63f37426..0a66a13490 100644
--- a/ipatests/prci_definitions/nightly_master.yaml
+++ b/ipatests/prci_definitions/nightly_master.yaml
@@ -75,6 +75,18 @@ jobs:
timeout: 3600
topology: *master_1repl
+ fedora-30/external_ca_templates:
+ requires: [fedora-30/build]
+ priority: 50
+ job:
+ class: RunPytest
+ args:
+ build_url: '{fedora-30/build_url}'
+ test_suite: test_integration/test_external_ca.py::TestExternalCAProfileScenarios
+ template: *ci-master-f30
+ timeout: 3600
+ topology: *master_1repl
+
fedora-30/test_topologies:
requires: [fedora-30/build]
priority: 50
diff --git a/ipatests/prci_definitions/nightly_master_pki.yaml b/ipatests/prci_definitions/nightly_master_pki.yaml
index 1bb0af0244..ed2e38d3ed 100644
--- a/ipatests/prci_definitions/nightly_master_pki.yaml
+++ b/ipatests/prci_definitions/nightly_master_pki.yaml
@@ -75,6 +75,18 @@ jobs:
timeout: 3600
topology: *master_1repl
+ fedora-29/external_ca_templates:
+ requires: [fedora-29/build]
+ priority: 50
+ job:
+ class: RunPytest
+ args:
+ build_url: '{fedora-29/build_url}'
+ test_suite: test_integration/test_external_ca.py::TestExternalCAProfileScenarios
+ template: *pki-master-f29
+ timeout: 3600
+ topology: *master_1repl
+
fedora-29/test_vault:
requires: [fedora-29/build]
priority: 50
diff --git a/ipatests/prci_definitions/nightly_rawhide.yaml b/ipatests/prci_definitions/nightly_rawhide.yaml
index 301878467c..14433fcc0a 100644
--- a/ipatests/prci_definitions/nightly_rawhide.yaml
+++ b/ipatests/prci_definitions/nightly_rawhide.yaml
@@ -75,6 +75,18 @@ jobs:
timeout: 3600
topology: *master_1repl
+ fedora-rawhide/external_ca_templates:
+ requires: [fedora-rawhide/build]
+ priority: 50
+ job:
+ class: RunPytest
+ args:
+ build_url: '{fedora-rawhide/build_url}'
+ test_suite: test_integration/test_external_ca.py::TestExternalCAProfileScenarios
+ template: *ci-master-frawhide
+ timeout: 3600
+ topology: *master_1repl
+
fedora-rawhide/test_topologies:
requires: [fedora-rawhide/build]
priority: 50
From 011c5283cec28ea4361eff5d2ee98da9cd3db41a Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Thu, 11 Jul 2019 20:27:02 +1000
Subject: [PATCH] ci: add --external-ca-profile tests to gating
Part of: https://pagure.io/freeipa/issue/7548
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/prci_definitions/gating.yaml | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/ipatests/prci_definitions/gating.yaml b/ipatests/prci_definitions/gating.yaml
index 4d0107d956..81fa4bba10 100644
--- a/ipatests/prci_definitions/gating.yaml
+++ b/ipatests/prci_definitions/gating.yaml
@@ -87,6 +87,18 @@ jobs:
timeout: 3600
topology: *master_1repl
+ fedora-30/external_ca_templates:
+ requires: [fedora-30/build]
+ priority: 50
+ job:
+ class: RunPytest
+ args:
+ build_url: '{fedora-30/build_url}'
+ test_suite: test_integration/test_external_ca.py::TestExternalCAProfileScenarios
+ template: *ci-master-f30
+ timeout: 3600
+ topology: *master_1repl
+
fedora-30/test_topologies:
requires: [fedora-30/build]
priority: 50