mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-23 05:10: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
|
@ -166,43 +166,51 @@ def main():
|
|||
|
||||
try:
|
||||
account = ACMEAccount(module)
|
||||
changed = False
|
||||
state = module.params.get('state')
|
||||
diff_before = {}
|
||||
diff_after = {}
|
||||
if state == 'absent':
|
||||
changed = account.init_account(
|
||||
[],
|
||||
allow_creation=False,
|
||||
update_contact=False,
|
||||
)
|
||||
if changed:
|
||||
raise AssertionError('Unwanted account change')
|
||||
if account.uri is not None:
|
||||
# Account does exist
|
||||
account_data = account.get_account_data()
|
||||
if account_data is not None:
|
||||
# Account is not yet deactivated
|
||||
if not module.check_mode:
|
||||
# Deactivate it
|
||||
payload = {
|
||||
'status': 'deactivated'
|
||||
}
|
||||
result, info = account.send_signed_request(account.uri, payload)
|
||||
if info['status'] != 200:
|
||||
raise ModuleFailException('Error deactivating account: {0} {1}'.format(info['status'], result))
|
||||
module.exit_json(changed=True, account_uri=account.uri)
|
||||
module.exit_json(changed=False, account_uri=account.uri)
|
||||
created, account_data = account.setup_account(allow_creation=False)
|
||||
if account_data:
|
||||
diff_before = dict(account_data)
|
||||
diff_before['public_account_key'] = account.key_data['jwk']
|
||||
if created:
|
||||
raise AssertionError('Unwanted account creation')
|
||||
if account_data is not None:
|
||||
# Account is not yet deactivated
|
||||
if not module.check_mode:
|
||||
# Deactivate it
|
||||
payload = {
|
||||
'status': 'deactivated'
|
||||
}
|
||||
result, info = account.send_signed_request(account.uri, payload)
|
||||
if info['status'] != 200:
|
||||
raise ModuleFailException('Error deactivating account: {0} {1}'.format(info['status'], result))
|
||||
changed = True
|
||||
elif state == 'present':
|
||||
allow_creation = module.params.get('allow_creation')
|
||||
# Make sure contact is a list of strings (unfortunately, Ansible doesn't do that for us)
|
||||
contact = [str(v) for v in module.params.get('contact')]
|
||||
terms_agreed = module.params.get('terms_agreed')
|
||||
changed = account.init_account(
|
||||
created, account_data = account.setup_account(
|
||||
contact,
|
||||
terms_agreed=terms_agreed,
|
||||
allow_creation=allow_creation,
|
||||
)
|
||||
if account.uri is None:
|
||||
if account_data is None:
|
||||
raise ModuleFailException(msg='Account does not exist or is deactivated.')
|
||||
module.exit_json(changed=changed, account_uri=account.uri)
|
||||
if created:
|
||||
diff_before = {}
|
||||
else:
|
||||
diff_before = dict(account_data)
|
||||
diff_before['public_account_key'] = account.key_data['jwk']
|
||||
updated = False
|
||||
if not created:
|
||||
updated, account_data = account.update_account(account_data, contact)
|
||||
changed = created or updated
|
||||
diff_after = dict(account_data)
|
||||
diff_after['public_account_key'] = account.key_data['jwk']
|
||||
elif state == 'changed_key':
|
||||
# Parse new account key
|
||||
error, new_key_data = account.parse_key(
|
||||
|
@ -212,15 +220,13 @@ def main():
|
|||
if error:
|
||||
raise ModuleFailException("error while parsing account key: %s" % error)
|
||||
# Verify that the account exists and has not been deactivated
|
||||
changed = account.init_account(
|
||||
[],
|
||||
allow_creation=False,
|
||||
update_contact=False,
|
||||
)
|
||||
if changed:
|
||||
raise AssertionError('Unwanted account change')
|
||||
if account.uri is None or account.get_account_data() is None:
|
||||
created, account_data = account.setup_account(allow_creation=False)
|
||||
if created:
|
||||
raise AssertionError('Unwanted account creation')
|
||||
if account_data is None:
|
||||
raise ModuleFailException(msg='Account does not exist or is deactivated.')
|
||||
diff_before = dict(account_data)
|
||||
diff_before['public_account_key'] = account.key_data['jwk']
|
||||
# Now we can start the account key rollover
|
||||
if not module.check_mode:
|
||||
# Compose inner signed message
|
||||
|
@ -241,7 +247,25 @@ def main():
|
|||
result, info = account.send_signed_request(url, data)
|
||||
if info['status'] != 200:
|
||||
raise ModuleFailException('Error account key rollover: {0} {1}'.format(info['status'], result))
|
||||
module.exit_json(changed=True, account_uri=account.uri)
|
||||
if module._diff:
|
||||
account.key_data = new_key_data
|
||||
account.jws_header['alg'] = new_key_data['alg']
|
||||
diff_after = account.get_account_data()
|
||||
elif module._diff:
|
||||
# Kind of fake diff_after
|
||||
diff_after = dict(diff_before)
|
||||
diff_after['public_account_key'] = new_key_data['jwk']
|
||||
changed = True
|
||||
result = {
|
||||
'changed': changed,
|
||||
'account_uri': account.uri,
|
||||
}
|
||||
if module._diff:
|
||||
result['diff'] = {
|
||||
'before': diff_before,
|
||||
'after': diff_after,
|
||||
}
|
||||
module.exit_json(**result)
|
||||
except ModuleFailException as e:
|
||||
e.do_fail(module)
|
||||
|
||||
|
|
|
@ -89,6 +89,11 @@ account:
|
|||
returned: always
|
||||
type: str
|
||||
sample: https://example.ca/account/1/orders
|
||||
public_account_key:
|
||||
description: the public account key as a L(JSON Web Key,https://tools.ietf.org/html/rfc7517).
|
||||
returned: always
|
||||
type: str
|
||||
sample: https://example.ca/account/1/orders
|
||||
'''
|
||||
|
||||
from ansible.module_utils.acme import (
|
||||
|
@ -129,24 +134,25 @@ def main():
|
|||
try:
|
||||
account = ACMEAccount(module)
|
||||
# Check whether account exists
|
||||
changed = account.init_account(
|
||||
created, account_data = account.setup_account(
|
||||
[],
|
||||
allow_creation=False,
|
||||
update_contact=False,
|
||||
remove_account_uri_if_not_exists=True,
|
||||
)
|
||||
if changed:
|
||||
raise AssertionError('Unwanted account change')
|
||||
if account.uri is None:
|
||||
# Account does exist
|
||||
module.exit_json(changed=False, exists=False, account_uri=None)
|
||||
else:
|
||||
# Account exists: retrieve account information
|
||||
data = account.get_account_data()
|
||||
if created:
|
||||
raise AssertionError('Unwanted account creation')
|
||||
result = {
|
||||
'changed': False,
|
||||
'exists': account.uri is not None,
|
||||
'account_uri': account.uri,
|
||||
}
|
||||
if account.uri is not None:
|
||||
# Make sure promised data is there
|
||||
if 'contact' not in data:
|
||||
data['contact'] = []
|
||||
module.exit_json(changed=False, exists=True, account_uri=account.uri, account=data)
|
||||
if 'contact' not in account_data:
|
||||
account_data['contact'] = []
|
||||
account_data['public_account_key'] = account.key_data['jwk']
|
||||
result['account'] = account_data
|
||||
module.exit_json(**result)
|
||||
except ModuleFailException as e:
|
||||
e.do_fail(module)
|
||||
|
||||
|
|
|
@ -406,16 +406,21 @@ class ACMEClient(object):
|
|||
contact = []
|
||||
if module.params['account_email']:
|
||||
contact.append('mailto:' + module.params['account_email'])
|
||||
self.changed = self.account.init_account(
|
||||
created, account_data = self.account.setup_account(
|
||||
contact,
|
||||
agreement=module.params.get('agreement'),
|
||||
terms_agreed=module.params.get('terms_agreed'),
|
||||
allow_creation=modify_account,
|
||||
update_contact=modify_account
|
||||
)
|
||||
if account_data is None:
|
||||
raise ModuleFailException(msg='Account does not exist or is deactivated.')
|
||||
updated = False
|
||||
if not created and account_data and modify_account:
|
||||
updated, account_data = self.account.update_account(account_data, contact)
|
||||
self.changed = created or updated
|
||||
else:
|
||||
# This happens if modify_account is False and the ACME v1
|
||||
# protocol is used. In this case, we do not call init_account()
|
||||
# protocol is used. In this case, we do not call setup_account()
|
||||
# to avoid accidental creation of an account. This is OK
|
||||
# since for ACME v1, the account URI is not needed to send a
|
||||
# signed ACME request.
|
||||
|
|
|
@ -177,13 +177,11 @@ def main():
|
|||
result, info = account.send_signed_request(endpoint, payload, key_data=private_key_data, jws_header=jws_header)
|
||||
else:
|
||||
# Step 1: get hold of account URI
|
||||
changed = account.init_account(
|
||||
[],
|
||||
allow_creation=False,
|
||||
update_contact=False,
|
||||
)
|
||||
if changed:
|
||||
raise AssertionError('Unwanted account change')
|
||||
created, account_data = account.setup_account(allow_creation=False)
|
||||
if created:
|
||||
raise AssertionError('Unwanted account creation')
|
||||
if account_data is None:
|
||||
raise ModuleFailException(msg='Account does not exist or is deactivated.')
|
||||
# Step 2: sign revokation request with account key
|
||||
result, info = account.send_signed_request(endpoint, payload)
|
||||
if info['status'] != 200:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue