summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/crypto/acme/acme_account.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/modules/crypto/acme/acme_account.py')
-rw-r--r--lib/ansible/modules/crypto/acme/acme_account.py278
1 files changed, 0 insertions, 278 deletions
diff --git a/lib/ansible/modules/crypto/acme/acme_account.py b/lib/ansible/modules/crypto/acme/acme_account.py
deleted file mode 100644
index ec922ce693..0000000000
--- a/lib/ansible/modules/crypto/acme/acme_account.py
+++ /dev/null
@@ -1,278 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# (c) 2016 Michael Gruener <michael.gruener@chaosmoon.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: acme_account
-author: "Felix Fontein (@felixfontein)"
-version_added: "2.6"
-short_description: Create, modify or delete ACME accounts
-description:
- - "Allows to create, modify or delete accounts with a CA supporting the
- L(ACME protocol,https://tools.ietf.org/html/rfc8555),
- such as L(Let's Encrypt,https://letsencrypt.org/)."
- - "This module only works with the ACME v2 protocol."
-notes:
- - "The M(acme_certificate) module also allows to do basic account management.
- When using both modules, it is recommended to disable account management
- for M(acme_certificate). For that, use the C(modify_account) option of
- M(acme_certificate)."
-seealso:
- - name: Automatic Certificate Management Environment (ACME)
- description: The specification of the ACME protocol (RFC 8555).
- link: https://tools.ietf.org/html/rfc8555
- - module: acme_account_info
- description: Retrieves facts about an ACME account.
- - module: openssl_privatekey
- description: Can be used to create a private account key.
- - module: acme_inspect
- description: Allows to debug problems.
-extends_documentation_fragment:
- - acme
-options:
- state:
- description:
- - "The state of the account, to be identified by its account key."
- - "If the state is C(absent), the account will either not exist or be
- deactivated."
- - "If the state is C(changed_key), the account must exist. The account
- key will be changed; no other information will be touched."
- type: str
- required: true
- choices:
- - present
- - absent
- - changed_key
- allow_creation:
- description:
- - "Whether account creation is allowed (when state is C(present))."
- type: bool
- default: yes
- contact:
- description:
- - "A list of contact URLs."
- - "Email addresses must be prefixed with C(mailto:)."
- - "See U(https://tools.ietf.org/html/rfc8555#section-7.3)
- for what is allowed."
- - "Must be specified when state is C(present). Will be ignored
- if state is C(absent) or C(changed_key)."
- type: list
- elements: str
- default: []
- terms_agreed:
- description:
- - "Boolean indicating whether you agree to the terms of service document."
- - "ACME servers can require this to be true."
- type: bool
- default: no
- new_account_key_src:
- description:
- - "Path to a file containing the ACME account RSA or Elliptic Curve key to change to."
- - "Same restrictions apply as to C(account_key_src)."
- - "Mutually exclusive with C(new_account_key_content)."
- - "Required if C(new_account_key_content) is not used and state is C(changed_key)."
- type: path
- new_account_key_content:
- description:
- - "Content of the ACME account RSA or Elliptic Curve key to change to."
- - "Same restrictions apply as to C(account_key_content)."
- - "Mutually exclusive with C(new_account_key_src)."
- - "Required if C(new_account_key_src) is not used and state is C(changed_key)."
- type: str
-'''
-
-EXAMPLES = '''
-- name: Make sure account exists and has given contacts. We agree to TOS.
- acme_account:
- account_key_src: /etc/pki/cert/private/account.key
- state: present
- terms_agreed: yes
- contact:
- - mailto:me@example.com
- - mailto:myself@example.org
-
-- name: Make sure account has given email address. Don't create account if it doesn't exist
- acme_account:
- account_key_src: /etc/pki/cert/private/account.key
- state: present
- allow_creation: no
- contact:
- - mailto:me@example.com
-
-- name: Change account's key to the one stored in the variable new_account_key
- acme_account:
- account_key_src: /etc/pki/cert/private/account.key
- new_account_key_content: '{{ new_account_key }}'
- state: changed_key
-
-- name: Delete account (we have to use the new key)
- acme_account:
- account_key_content: '{{ new_account_key }}'
- state: absent
-'''
-
-RETURN = '''
-account_uri:
- description: ACME account URI, or None if account does not exist.
- returned: always
- type: str
-'''
-
-from ansible.module_utils.acme import (
- ModuleFailException,
- ACMEAccount,
- handle_standard_module_arguments,
- get_default_argspec,
-)
-
-from ansible.module_utils.basic import AnsibleModule
-
-
-def main():
- argument_spec = get_default_argspec()
- argument_spec.update(dict(
- terms_agreed=dict(type='bool', default=False),
- state=dict(type='str', required=True, choices=['absent', 'present', 'changed_key']),
- allow_creation=dict(type='bool', default=True),
- contact=dict(type='list', elements='str', default=[]),
- new_account_key_src=dict(type='path'),
- new_account_key_content=dict(type='str', no_log=True),
- ))
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_one_of=(
- ['account_key_src', 'account_key_content'],
- ),
- mutually_exclusive=(
- ['account_key_src', 'account_key_content'],
- ['new_account_key_src', 'new_account_key_content'],
- ),
- required_if=(
- # Make sure that for state == changed_key, one of
- # new_account_key_src and new_account_key_content are specified
- ['state', 'changed_key', ['new_account_key_src', 'new_account_key_content'], True],
- ),
- supports_check_mode=True,
- )
- handle_standard_module_arguments(module, needs_acme_v2=True)
-
- try:
- account = ACMEAccount(module)
- changed = False
- state = module.params.get('state')
- diff_before = {}
- diff_after = {}
- if state == 'absent':
- 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')
- created, account_data = account.setup_account(
- contact,
- terms_agreed=terms_agreed,
- allow_creation=allow_creation,
- )
- if account_data is None:
- raise ModuleFailException(msg='Account does not exist or is deactivated.')
- 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(
- module.params.get('new_account_key_src'),
- module.params.get('new_account_key_content')
- )
- if error:
- raise ModuleFailException("error while parsing account key: %s" % error)
- # Verify that the account exists and has not been deactivated
- 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
- # https://tools.ietf.org/html/rfc8555#section-7.3.5
- url = account.directory['keyChange']
- protected = {
- "alg": new_key_data['alg'],
- "jwk": new_key_data['jwk'],
- "url": url,
- }
- payload = {
- "account": account.uri,
- "newKey": new_key_data['jwk'], # specified in draft 12 and older
- "oldKey": account.jwk, # specified in draft 13 and newer
- }
- data = account.sign_request(protected, payload, new_key_data)
- # Send request and verify result
- result, info = account.send_signed_request(url, data)
- if info['status'] != 200:
- raise ModuleFailException('Error account key rollover: {0} {1}'.format(info['status'], result))
- 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)
-
-
-if __name__ == '__main__':
- main()