mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-22 12:50:22 -07:00
ACME: add diff to acme_account, account_public_key to acme_account_facts, and general refactoring (#49410)
* Only one exit point. * Refactoring account handling. * Add diff support for acme_account. * Insert public_account_key into acme_account_facts result and into acme_account diff. * Add changelog.
This commit is contained in:
parent
62dd1fe29e
commit
b0c7efcc6b
9 changed files with 305 additions and 104 deletions
|
@ -646,12 +646,14 @@ class ACMEAccount(object):
|
|||
|
||||
def _new_reg(self, contact=None, agreement=None, terms_agreed=False, allow_creation=True):
|
||||
'''
|
||||
Registers a new ACME account. Returns True if the account was
|
||||
created and False if it already existed (e.g. it was not newly
|
||||
created).
|
||||
Registers a new ACME account. Returns a pair ``(created, data)``.
|
||||
Here, ``created`` is ``True`` if the account was created and
|
||||
``False`` if it already existed (e.g. it was not newly created),
|
||||
or does not exist. In case the account was created or exists,
|
||||
``data`` contains the account data; otherwise, it is ``None``.
|
||||
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3
|
||||
'''
|
||||
contact = [] if contact is None else contact
|
||||
contact = contact or []
|
||||
|
||||
if self.version == 1:
|
||||
new_reg = {
|
||||
|
@ -668,6 +670,7 @@ class ACMEAccount(object):
|
|||
'contact': contact
|
||||
}
|
||||
if not allow_creation:
|
||||
# https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3.1
|
||||
new_reg['onlyReturnExisting'] = True
|
||||
if terms_agreed:
|
||||
new_reg['termsOfServiceAgreed'] = True
|
||||
|
@ -679,7 +682,7 @@ class ACMEAccount(object):
|
|||
# Account did not exist
|
||||
if 'location' in info:
|
||||
self.set_account_uri(info['location'])
|
||||
return True
|
||||
return True, result
|
||||
elif info['status'] == (409 if self.version == 1 else 200):
|
||||
# Account did exist
|
||||
if result.get('status') == 'deactivated':
|
||||
|
@ -689,22 +692,22 @@ class ACMEAccount(object):
|
|||
# "Once an account is deactivated, the server MUST NOT accept further
|
||||
# requests authorized by that account's key."
|
||||
if not allow_creation:
|
||||
return False
|
||||
return False, None
|
||||
else:
|
||||
raise ModuleFailException("Account is deactivated")
|
||||
if 'location' in info:
|
||||
self.set_account_uri(info['location'])
|
||||
return False
|
||||
return False, result
|
||||
elif info['status'] == 400 and result['type'] == 'urn:ietf:params:acme:error:accountDoesNotExist' and not allow_creation:
|
||||
# Account does not exist (and we didn't try to create it)
|
||||
return False
|
||||
return False, None
|
||||
else:
|
||||
raise ModuleFailException("Error registering: {0} {1}".format(info['status'], result))
|
||||
|
||||
def get_account_data(self):
|
||||
'''
|
||||
Retrieve account information. Can only be called when the account
|
||||
URI is already known (such as after calling init_account).
|
||||
URI is already known (such as after calling setup_account).
|
||||
Return None if the account was deactivated, or a dict otherwise.
|
||||
'''
|
||||
if self.uri is None:
|
||||
|
@ -732,66 +735,82 @@ class ACMEAccount(object):
|
|||
raise ModuleFailException("Error getting account data from {2}: {0} {1}".format(info['status'], result, self.uri))
|
||||
return result
|
||||
|
||||
def init_account(self, contact, agreement=None, terms_agreed=False, allow_creation=True, update_contact=True, remove_account_uri_if_not_exists=False):
|
||||
def setup_account(self, contact=None, agreement=None, terms_agreed=False, allow_creation=True, remove_account_uri_if_not_exists=False):
|
||||
'''
|
||||
Create or update an account on the ACME server. For ACME v1,
|
||||
Detect or create an account on the ACME server. For ACME v1,
|
||||
as the only way (without knowing an account URI) to test if an
|
||||
account exists is to try and create one with the provided account
|
||||
key, this method will always result in an account being present
|
||||
(except on error situations). For ACME v2, a new account will
|
||||
only be created if allow_creation is set to True.
|
||||
only be created if ``allow_creation`` is set to True.
|
||||
|
||||
For ACME v2, check_mode is fully respected. For ACME v1, the account
|
||||
might be created if it does not yet exist.
|
||||
For ACME v2, ``check_mode`` is fully respected. For ACME v1, the
|
||||
account might be created if it does not yet exist.
|
||||
|
||||
If the account already exists and if update_contact is set to
|
||||
True, this method will update the contact information.
|
||||
Return a pair ``(created, account_data)``. Here, ``created`` will
|
||||
be ``True`` in case the account was created or would be created
|
||||
(check mode). ``account_data`` will be the current account data,
|
||||
or ``None`` if the account does not exist.
|
||||
|
||||
Return True in case something changed (account was created, contact
|
||||
info updated) or would be changed (check_mode). The account URI
|
||||
will be stored in self.uri; if it is None, the account does not
|
||||
exist.
|
||||
The account URI will be stored in ``self.uri``; if it is ``None``,
|
||||
the account does not exist.
|
||||
|
||||
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3
|
||||
'''
|
||||
|
||||
new_account = True
|
||||
changed = False
|
||||
if self.uri is not None:
|
||||
new_account = False
|
||||
if not update_contact:
|
||||
# Verify that the account key belongs to the URI.
|
||||
# (If update_contact is True, this will be done below.)
|
||||
if self.get_account_data() is None:
|
||||
if remove_account_uri_if_not_exists and not allow_creation:
|
||||
self.uri = None
|
||||
return False
|
||||
created = False
|
||||
# Verify that the account key belongs to the URI.
|
||||
# (If update_contact is True, this will be done below.)
|
||||
account_data = self.get_account_data()
|
||||
if account_data is None:
|
||||
if remove_account_uri_if_not_exists and not allow_creation:
|
||||
self.uri = None
|
||||
else:
|
||||
raise ModuleFailException("Account is deactivated or does not exist!")
|
||||
else:
|
||||
new_account = self._new_reg(
|
||||
created, account_data = self._new_reg(
|
||||
contact,
|
||||
agreement=agreement,
|
||||
terms_agreed=terms_agreed,
|
||||
allow_creation=allow_creation and not self.module.check_mode
|
||||
)
|
||||
if self.module.check_mode and self.uri is None and allow_creation:
|
||||
return True
|
||||
if not new_account and self.uri and update_contact:
|
||||
result = self.get_account_data()
|
||||
if result is None:
|
||||
if not allow_creation:
|
||||
self.uri = None
|
||||
return False
|
||||
raise ModuleFailException("Account is deactivated or does not exist!")
|
||||
created = True
|
||||
account_data = {
|
||||
'contact': contact or []
|
||||
}
|
||||
return created, account_data
|
||||
|
||||
# ...and check if update is necessary
|
||||
if result.get('contact', []) != contact:
|
||||
if not self.module.check_mode:
|
||||
upd_reg = result
|
||||
upd_reg['contact'] = contact
|
||||
result, dummy = self.send_signed_request(self.uri, upd_reg)
|
||||
changed = True
|
||||
return new_account or changed
|
||||
def update_account(self, account_data, contact=None):
|
||||
'''
|
||||
Update an account on the ACME server. Check mode is fully respected.
|
||||
|
||||
The current account data must be provided as ``account_data``.
|
||||
|
||||
Return a pair ``(updated, account_data)``, where ``updated`` is
|
||||
``True`` in case something changed (contact info updated) or
|
||||
would be changed (check mode), and ``account_data`` the updated
|
||||
account data.
|
||||
|
||||
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3.2
|
||||
'''
|
||||
# Create request
|
||||
update_request = {}
|
||||
if contact is not None and account_data.get('contact', []) != contact:
|
||||
update_request['contact'] = list(contact)
|
||||
|
||||
# No change?
|
||||
if not update_request:
|
||||
return False, dict(account_data)
|
||||
|
||||
# Apply change
|
||||
if self.module.check_mode:
|
||||
account_data = dict(account_data)
|
||||
account_data.update(update_request)
|
||||
else:
|
||||
account_data, dummy = self.send_signed_request(self.uri, update_request)
|
||||
return True, account_data
|
||||
|
||||
|
||||
def cryptography_get_csr_domains(module, csr_filename):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue