acme_certificate: allow 'no challenge' (#615)
* Allow 'no challenge'. * Fix undefined variable.pull/617/head
parent
9305bfe190
commit
17702d1a76
|
@ -0,0 +1,4 @@
|
||||||
|
minor_changes:
|
||||||
|
- "acme_certificate - allow to use no challenge by providing ``no challenge`` for the ``challenge`` option.
|
||||||
|
This is needed for ACME servers where validation is done without challenges
|
||||||
|
(https://github.com/ansible-collections/community.crypto/issues/613, https://github.com/ansible-collections/community.crypto/pull/615)."
|
|
@ -124,10 +124,19 @@ options:
|
||||||
type: bool
|
type: bool
|
||||||
default: true
|
default: true
|
||||||
challenge:
|
challenge:
|
||||||
description: The challenge to be performed.
|
description:
|
||||||
|
- The challenge to be performed.
|
||||||
|
- If set to C(no challenge), no challenge will be used. This is necessary for some private
|
||||||
|
CAs which use External Account Binding and other means of validating certificate assurance.
|
||||||
|
For example, an account could be allowed to issue certificates for C(foo.example.com)
|
||||||
|
without any further validation for a certain period of time.
|
||||||
type: str
|
type: str
|
||||||
default: 'http-01'
|
default: 'http-01'
|
||||||
choices: [ 'http-01', 'dns-01', 'tls-alpn-01' ]
|
choices:
|
||||||
|
- 'http-01'
|
||||||
|
- 'dns-01'
|
||||||
|
- 'tls-alpn-01'
|
||||||
|
- 'no challenge'
|
||||||
csr:
|
csr:
|
||||||
description:
|
description:
|
||||||
- "File containing the CSR for the new certificate."
|
- "File containing the CSR for the new certificate."
|
||||||
|
@ -578,6 +587,9 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.utils import
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
NO_CHALLENGE = 'no challenge'
|
||||||
|
|
||||||
|
|
||||||
class ACMECertificateClient(object):
|
class ACMECertificateClient(object):
|
||||||
'''
|
'''
|
||||||
ACME client class. Uses an ACME account object and a CSR to
|
ACME client class. Uses an ACME account object and a CSR to
|
||||||
|
@ -589,6 +601,9 @@ class ACMECertificateClient(object):
|
||||||
self.module = module
|
self.module = module
|
||||||
self.version = module.params['acme_version']
|
self.version = module.params['acme_version']
|
||||||
self.challenge = module.params['challenge']
|
self.challenge = module.params['challenge']
|
||||||
|
# We use None instead of a magic string for 'no challenge'
|
||||||
|
if self.challenge == NO_CHALLENGE:
|
||||||
|
self.challenge = None
|
||||||
self.csr = module.params['csr']
|
self.csr = module.params['csr']
|
||||||
self.csr_content = module.params['csr_content']
|
self.csr_content = module.params['csr_content']
|
||||||
self.dest = module.params.get('dest')
|
self.dest = module.params.get('dest')
|
||||||
|
@ -696,7 +711,7 @@ class ACMECertificateClient(object):
|
||||||
continue
|
continue
|
||||||
# We drop the type from the key to preserve backwards compatibility
|
# We drop the type from the key to preserve backwards compatibility
|
||||||
data[identifier] = authz.get_challenge_data(self.client)
|
data[identifier] = authz.get_challenge_data(self.client)
|
||||||
if first_step and self.challenge not in data[identifier]:
|
if first_step and self.challenge is not None and self.challenge not in data[identifier]:
|
||||||
raise ModuleFailException("Found no challenge of type '{0}' for identifier {1}!".format(
|
raise ModuleFailException("Found no challenge of type '{0}' for identifier {1}!".format(
|
||||||
self.challenge, type_identifier))
|
self.challenge, type_identifier))
|
||||||
# Get DNS challenge data
|
# Get DNS challenge data
|
||||||
|
@ -735,7 +750,14 @@ class ACMECertificateClient(object):
|
||||||
for type_identifier, authz in self.authorizations.items():
|
for type_identifier, authz in self.authorizations.items():
|
||||||
if authz.status == 'pending':
|
if authz.status == 'pending':
|
||||||
identifier_type, identifier = split_identifier(type_identifier)
|
identifier_type, identifier = split_identifier(type_identifier)
|
||||||
|
if self.challenge is not None:
|
||||||
authz.call_validate(self.client, self.challenge)
|
authz.call_validate(self.client, self.challenge)
|
||||||
|
# If there is no challenge, we must check whether the authz is valid
|
||||||
|
elif authz.status != 'valid':
|
||||||
|
authz.raise_error(
|
||||||
|
'Status is not "valid", even though no challenge should be necessary',
|
||||||
|
module=self.client.module,
|
||||||
|
)
|
||||||
self.changed = True
|
self.changed = True
|
||||||
|
|
||||||
def download_alternate_chains(self, cert):
|
def download_alternate_chains(self, cert):
|
||||||
|
@ -832,7 +854,7 @@ def main():
|
||||||
account_email=dict(type='str'),
|
account_email=dict(type='str'),
|
||||||
agreement=dict(type='str'),
|
agreement=dict(type='str'),
|
||||||
terms_agreed=dict(type='bool', default=False),
|
terms_agreed=dict(type='bool', default=False),
|
||||||
challenge=dict(type='str', default='http-01', choices=['http-01', 'dns-01', 'tls-alpn-01']),
|
challenge=dict(type='str', default='http-01', choices=['http-01', 'dns-01', 'tls-alpn-01', NO_CHALLENGE]),
|
||||||
csr=dict(type='path', aliases=['src']),
|
csr=dict(type='path', aliases=['src']),
|
||||||
csr_content=dict(type='str'),
|
csr_content=dict(type='str'),
|
||||||
data=dict(type='dict'),
|
data=dict(type='dict'),
|
||||||
|
|
Loading…
Reference in New Issue