Validate challenges in parallel instead of serially. (#617)

pull/620/head
Felix Fontein 2023-06-09 06:04:34 +02:00 committed by GitHub
parent 3a5d9129b2
commit d823382732
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 2 deletions

View File

@ -0,0 +1,2 @@
minor_changes:
- "acme_certificate - validate and wait for challenges in parallel instead handling them one after another (https://github.com/ansible-collections/community.crypto/pull/617)."

View File

@ -301,3 +301,21 @@ class Authorization(object):
self.status = 'deactivated' self.status = 'deactivated'
return True return True
return False return False
def wait_for_validation(authzs, client):
'''
Wait until a list of authz is valid. Fail if at least one of them is invalid or revoked.
'''
while authzs:
authzs_next = []
for authz in authzs:
authz.refresh(client)
if authz.status in ['valid', 'invalid', 'revoked']:
if authz.status != 'valid':
authz.raise_error('Status is not "valid"', module=client.module)
else:
authzs_next.append(authz)
if authzs_next:
time.sleep(2)
authzs = authzs_next

View File

@ -561,6 +561,7 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.account impo
from ansible_collections.community.crypto.plugins.module_utils.acme.challenges import ( from ansible_collections.community.crypto.plugins.module_utils.acme.challenges import (
combine_identifier, combine_identifier,
split_identifier, split_identifier,
wait_for_validation,
Authorization, Authorization,
) )
@ -747,11 +748,12 @@ class ACMECertificateClient(object):
self.authorizations.update(self.order.authorizations) self.authorizations.update(self.order.authorizations)
# Step 2: validate pending challenges # Step 2: validate pending challenges
authzs_to_wait_for = []
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)
if self.challenge is not None: if self.challenge is not None:
authz.call_validate(self.client, self.challenge) authz.call_validate(self.client, self.challenge, wait=False)
authzs_to_wait_for.append(authz)
# If there is no challenge, we must check whether the authz is valid # If there is no challenge, we must check whether the authz is valid
elif authz.status != 'valid': elif authz.status != 'valid':
authz.raise_error( authz.raise_error(
@ -760,6 +762,9 @@ class ACMECertificateClient(object):
) )
self.changed = True self.changed = True
# Step 3: wait for authzs to validate
wait_for_validation(authzs_to_wait_for, self.client)
def download_alternate_chains(self, cert): def download_alternate_chains(self, cert):
alternate_chains = [] alternate_chains = []
for alternate in cert.alternates: for alternate in cert.alternates: