From 1d8e9db4a9ea153b607ba4510b99a71ef440460d Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 18 Feb 2019 11:24:17 +0100 Subject: [PATCH] crypto modules: add missing option types (#52421) * Add missing crypto option types. * Reorder argument_spec. * Reorder option docs. --- .../modules/crypto/acme/acme_account.py | 26 +++++---- .../modules/crypto/acme/acme_account_facts.py | 10 ++-- .../modules/crypto/acme/acme_certificate.py | 57 +++++++++++-------- .../crypto/acme/acme_certificate_revoke.py | 20 ++++--- .../crypto/acme/acme_challenge_cert_helper.py | 8 ++- .../modules/crypto/acme/acme_inspect.py | 21 +++---- .../crypto/certificate_complete_chain.py | 18 +++--- lib/ansible/modules/crypto/get_certificate.py | 18 +++--- lib/ansible/modules/crypto/luks_device.py | 17 +++--- lib/ansible/modules/crypto/openssh_cert.py | 49 +++++++--------- lib/ansible/modules/crypto/openssh_keypair.py | 32 +++++------ .../modules/crypto/openssl_certificate.py | 13 ++--- lib/ansible/modules/crypto/openssl_csr.py | 15 +++-- lib/ansible/modules/crypto/openssl_dhparam.py | 2 +- lib/ansible/modules/crypto/openssl_pkcs12.py | 6 +- .../modules/crypto/openssl_privatekey.py | 24 ++++---- .../modules/crypto/openssl_publickey.py | 4 +- lib/ansible/plugins/doc_fragments/acme.py | 7 ++- 18 files changed, 185 insertions(+), 162 deletions(-) diff --git a/lib/ansible/modules/crypto/acme/acme_account.py b/lib/ansible/modules/crypto/acme/acme_account.py index 5e0585d38b9..6ebee52f4e1 100644 --- a/lib/ansible/modules/crypto/acme/acme_account.py +++ b/lib/ansible/modules/crypto/acme/acme_account.py @@ -49,6 +49,7 @@ options: 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 @@ -57,8 +58,8 @@ options: allow_creation: description: - "Whether account creation is allowed (when state is C(present))." - default: yes type: bool + default: yes contact: description: - "A list of contact URLs." @@ -67,25 +68,28 @@ options: 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 default: [] terms_agreed: description: - "Boolean indicating whether you agree to the terms of service document." - "ACME servers can require this to be true." - default: no 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 = ''' @@ -137,17 +141,17 @@ def main(): argument_spec=dict( account_key_src=dict(type='path', aliases=['account_key']), account_key_content=dict(type='str', no_log=True), - account_uri=dict(required=False, type='str'), - acme_directory=dict(required=False, default='https://acme-staging.api.letsencrypt.org/directory', type='str'), - acme_version=dict(required=False, default=1, choices=[1, 2], type='int'), - validate_certs=dict(required=False, default=True, type='bool'), - terms_agreed=dict(required=False, default=False, type='bool'), - state=dict(required=True, choices=['absent', 'present', 'changed_key'], type='str'), - allow_creation=dict(required=False, default=True, type='bool'), - contact=dict(required=False, type='list', elements='str', default=[]), + account_uri=dict(type='str'), + acme_directory=dict(type='str', default='https://acme-staging.api.letsencrypt.org/directory'), + acme_version=dict(type='int', default=1, choices=[1, 2]), + validate_certs=dict(type='bool', default=True), + 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), - select_crypto_backend=dict(required=False, choices=['auto', 'openssl', 'cryptography'], default='auto', type='str'), + select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'openssl', 'cryptography']), ), required_one_of=( ['account_key_src', 'account_key_content'], diff --git a/lib/ansible/modules/crypto/acme/acme_account_facts.py b/lib/ansible/modules/crypto/acme/acme_account_facts.py index a92e71b8bbb..8b6c0a859cb 100644 --- a/lib/ansible/modules/crypto/acme/acme_account_facts.py +++ b/lib/ansible/modules/crypto/acme/acme_account_facts.py @@ -111,11 +111,11 @@ def main(): argument_spec=dict( account_key_src=dict(type='path', aliases=['account_key']), account_key_content=dict(type='str', no_log=True), - account_uri=dict(required=False, type='str'), - acme_directory=dict(required=False, default='https://acme-staging.api.letsencrypt.org/directory', type='str'), - acme_version=dict(required=False, default=1, choices=[1, 2], type='int'), - validate_certs=dict(required=False, default=True, type='bool'), - select_crypto_backend=dict(required=False, choices=['auto', 'openssl', 'cryptography'], default='auto', type='str'), + account_uri=dict(type='str'), + acme_directory=dict(type='str', default='https://acme-staging.api.letsencrypt.org/directory'), + acme_version=dict(type='int', default=1, choices=[1, 2]), + validate_certs=dict(type='bool', default=True), + select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'openssl', 'cryptography']), ), required_one_of=( ['account_key_src', 'account_key_content'], diff --git a/lib/ansible/modules/crypto/acme/acme_certificate.py b/lib/ansible/modules/crypto/acme/acme_certificate.py index 4e392d5f560..aeb6dd7414b 100644 --- a/lib/ansible/modules/crypto/acme/acme_certificate.py +++ b/lib/ansible/modules/crypto/acme/acme_certificate.py @@ -83,19 +83,21 @@ options: used the M(acme_account) module to specify more than one contact for your account, this module will update your account and restrict it to the (at most one) contact email address specified here." + type: str agreement: description: - "URI to a terms of service document you agree to when using the ACME v1 service at C(acme_directory)." - Default is latest gathered from C(acme_directory) URL. - This option will only be used when C(acme_version) is 1. + type: str terms_agreed: description: - "Boolean indicating whether you agree to the terms of service document." - "ACME servers can require this to be true." - This option will only be used when C(acme_version) is not 1. type: bool - default: 'no' + default: no version_added: "2.5" modify_account: description: @@ -106,12 +108,13 @@ options: using an old key if you changed the account key with M(acme_account)." - "If set to C(no), C(terms_agreed) and C(account_email) are ignored." type: bool - default: 'yes' + default: yes version_added: "2.6" challenge: description: The challenge to be performed. - choices: [ 'http-01', 'dns-01', 'tls-alpn-01' ] + type: str default: 'http-01' + choices: [ 'http-01', 'dns-01', 'tls-alpn-01' ] csr: description: - "File containing the CSR for the new certificate." @@ -123,6 +126,7 @@ options: account key. This is a bad idea from a security point of view, and the CA should not accept the CSR. The ACME server should return an error in this case." + type: path required: true aliases: ['src'] data: @@ -140,23 +144,27 @@ options: as it causes error messages to be come unusable, and C(data) does not contain any information which can be used without having access to the account key or which are not public anyway." + type: dict dest: description: - "The destination file for the certificate." - "Required if C(fullchain_dest) is not specified." + type: path aliases: ['cert'] fullchain_dest: description: - "The destination file for the full chain (i.e. certificate followed by chain of intermediate certificates)." - "Required if C(dest) is not specified." + type: path version_added: 2.5 aliases: ['fullchain'] chain_dest: description: - If specified, the intermediate certificate will be written to this file. - aliases: ['chain'] + type: path version_added: 2.5 + aliases: ['chain'] remaining_days: description: - "The number of days the certificate must have left being valid. @@ -165,6 +173,7 @@ options: include C(challenge_data)." - "To make sure that the certificate is renewed in any case, you can use the C(force) option." + type: int default: 10 deactivate_authzs: description: @@ -175,7 +184,7 @@ options: without having to re-authenticate the domain. This can be a security concern." type: bool - default: 'no' + default: no version_added: 2.6 force: description: @@ -184,7 +193,7 @@ options: - This is especially helpful when having an updated CSR e.g. with additional domains for which a new certificate is desired. type: bool - default: 'no' + default: no version_added: 2.6 ''' @@ -890,24 +899,24 @@ def main(): argument_spec=dict( account_key_src=dict(type='path', aliases=['account_key']), account_key_content=dict(type='str', no_log=True), - account_uri=dict(required=False, type='str'), - modify_account=dict(required=False, type='bool', default=True), - acme_directory=dict(required=False, default='https://acme-staging.api.letsencrypt.org/directory', type='str'), - acme_version=dict(required=False, default=1, choices=[1, 2], type='int'), - validate_certs=dict(required=False, default=True, type='bool'), - account_email=dict(required=False, default=None, type='str'), - agreement=dict(required=False, type='str'), - terms_agreed=dict(required=False, default=False, type='bool'), - challenge=dict(required=False, default='http-01', choices=['http-01', 'dns-01', 'tls-alpn-01'], type='str'), - csr=dict(required=True, aliases=['src'], type='path'), - data=dict(required=False, default=None, type='dict'), - dest=dict(aliases=['cert'], type='path'), - fullchain_dest=dict(aliases=['fullchain'], type='path'), - chain_dest=dict(required=False, default=None, aliases=['chain'], type='path'), - remaining_days=dict(required=False, default=10, type='int'), - deactivate_authzs=dict(required=False, default=False, type='bool'), - force=dict(required=False, default=False, type='bool'), - select_crypto_backend=dict(required=False, choices=['auto', 'openssl', 'cryptography'], default='auto', type='str'), + account_uri=dict(type='str'), + modify_account=dict(type='bool', default=True), + acme_directory=dict(type='str', default='https://acme-staging.api.letsencrypt.org/directory'), + acme_version=dict(type='int', default=1, choices=[1, 2]), + validate_certs=dict(default=True, type='bool'), + account_email=dict(type='str'), + agreement=dict(type='str'), + terms_agreed=dict(type='bool', default=False), + challenge=dict(type='str', default='http-01', choices=['http-01', 'dns-01', 'tls-alpn-01']), + csr=dict(type='path', required=True, aliases=['src']), + data=dict(type='dict'), + dest=dict(type='path', aliases=['cert']), + fullchain_dest=dict(type='path', aliases=['fullchain']), + chain_dest=dict(type='path', aliases=['chain']), + remaining_days=dict(type='int', default=10), + deactivate_authzs=dict(type='bool', default=False), + force=dict(type='bool', default=False), + select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'openssl', 'cryptography']), ), required_one_of=( ['account_key_src', 'account_key_content'], diff --git a/lib/ansible/modules/crypto/acme/acme_certificate_revoke.py b/lib/ansible/modules/crypto/acme/acme_certificate_revoke.py index d13f8d90e5e..0a3a26b9225 100644 --- a/lib/ansible/modules/crypto/acme/acme_certificate_revoke.py +++ b/lib/ansible/modules/crypto/acme/acme_certificate_revoke.py @@ -47,6 +47,7 @@ options: certificate: description: - "Path to the certificate to revoke." + type: path required: yes account_key_src: description: @@ -57,6 +58,7 @@ options: private keys in PEM format can be used as well." - "Mutually exclusive with C(account_key_content)." - "Required if C(account_key_content) is not used." + type: path account_key_content: description: - "Content of the ACME account RSA or Elliptic Curve key." @@ -71,11 +73,13 @@ options: temporary file. It can still happen that it is written to disk by Ansible in the process of moving the module with its argument to the node where it is executed." + type: str private_key_src: description: - "Path to the certificate's private key." - "Note that exactly one of C(account_key_src), C(account_key_content), C(private_key_src) or C(private_key_content) must be specified." + type: path private_key_content: description: - "Content of the certificate's private key." @@ -90,6 +94,7 @@ options: temporary file. It can still happen that it is written to disk by Ansible in the process of moving the module with its argument to the node where it is executed." + type: str revoke_reason: description: - "One of the revocation reasonCodes defined in @@ -99,6 +104,7 @@ options: C(5) (cessationOfOperation), C(6) (certificateHold), C(8) (removeFromCRL), C(9) (privilegeWithdrawn), C(10) (aACompromise)" + type: int ''' EXAMPLES = ''' @@ -128,15 +134,15 @@ def main(): argument_spec=dict( account_key_src=dict(type='path', aliases=['account_key']), account_key_content=dict(type='str', no_log=True), - account_uri=dict(required=False, type='str'), - acme_directory=dict(required=False, default='https://acme-staging.api.letsencrypt.org/directory', type='str'), - acme_version=dict(required=False, default=1, choices=[1, 2], type='int'), - validate_certs=dict(required=False, default=True, type='bool'), + account_uri=dict(type='str'), + acme_directory=dict(type='str', default='https://acme-staging.api.letsencrypt.org/directory'), + acme_version=dict(type='int', default=1, choices=[1, 2]), + validate_certs=dict(type='bool', default=True), private_key_src=dict(type='path'), private_key_content=dict(type='str', no_log=True), - certificate=dict(required=True, type='path'), - revoke_reason=dict(required=False, type='int'), - select_crypto_backend=dict(required=False, choices=['auto', 'openssl', 'cryptography'], default='auto', type='str'), + certificate=dict(type='path', required=True), + revoke_reason=dict(type='int'), + select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'openssl', 'cryptography']), ), required_one_of=( ['account_key_src', 'account_key_content', 'private_key_src', 'private_key_content'], diff --git a/lib/ansible/modules/crypto/acme/acme_challenge_cert_helper.py b/lib/ansible/modules/crypto/acme/acme_challenge_cert_helper.py index 6bdce424efd..ca10a01fb3e 100644 --- a/lib/ansible/modules/crypto/acme/acme_challenge_cert_helper.py +++ b/lib/ansible/modules/crypto/acme/acme_challenge_cert_helper.py @@ -39,22 +39,26 @@ options: challenge: description: - "The challenge type." + type: str required: yes choices: - tls-alpn-01 challenge_data: description: - "The C(challenge_data) entry provided by M(acme_certificate) for the challenge." + type: dict required: yes private_key_src: description: - "Path to a file containing the private key file to use for this challenge certificate." - "Mutually exclusive with C(private_key_content)." + type: path private_key_content: description: - "Content of the private key to use for this challenge certificate." - "Mutually exclusive with C(private_key_src)." + type: str ''' EXAMPLES = ''' @@ -169,8 +173,8 @@ else: def main(): module = AnsibleModule( argument_spec=dict( - challenge=dict(required=True, choices=['tls-alpn-01'], type='str'), - challenge_data=dict(required=True, type='dict'), + challenge=dict(type='str', required=True, choices=['tls-alpn-01']), + challenge_data=dict(type='dict', required=True), private_key_src=dict(type='path'), private_key_content=dict(type='str', no_log=True), ), diff --git a/lib/ansible/modules/crypto/acme/acme_inspect.py b/lib/ansible/modules/crypto/acme/acme_inspect.py index 0de8db09dea..59ccaf87e58 100644 --- a/lib/ansible/modules/crypto/acme/acme_inspect.py +++ b/lib/ansible/modules/crypto/acme/acme_inspect.py @@ -63,11 +63,12 @@ options: and a regular GET request for ACME v1." - "The value C(directory-only) only retrieves the directory, without doing a request." + type: str + default: get choices: - get - post - directory-only - default: get content: description: - "An encoded JSON object which will be sent as the content if I(method) @@ -259,15 +260,15 @@ def main(): argument_spec=dict( account_key_src=dict(type='path', aliases=['account_key']), account_key_content=dict(type='str', no_log=True), - account_uri=dict(required=False, type='str'), - acme_directory=dict(required=False, default='https://acme-staging.api.letsencrypt.org/directory', type='str'), - acme_version=dict(required=False, default=1, choices=[1, 2], type='int'), - validate_certs=dict(required=False, default=True, type='bool'), - url=dict(required=False, type='str'), - method=dict(required=False, type='str', choices=['get', 'post', 'directory-only'], default='get'), - content=dict(required=False, type='str'), - fail_on_acme_error=dict(required=False, type='bool', default=True), - select_crypto_backend=dict(required=False, choices=['auto', 'openssl', 'cryptography'], default='auto', type='str'), + account_uri=dict(type='str'), + acme_directory=dict(type='str', default='https://acme-staging.api.letsencrypt.org/directory'), + acme_version=dict(type='int', default=1, choices=[1, 2]), + validate_certs=dict(type='bool', default=True), + url=dict(type='str'), + method=dict(type='str', choices=['get', 'post', 'directory-only'], default='get'), + content=dict(type='str'), + fail_on_acme_error=dict(type='bool', default=True), + select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'openssl', 'cryptography']), ), mutually_exclusive=( ['account_key_src', 'account_key_content'], diff --git a/lib/ansible/modules/crypto/certificate_complete_chain.py b/lib/ansible/modules/crypto/certificate_complete_chain.py index 7759d767f03..5449b37bb0f 100644 --- a/lib/ansible/modules/crypto/certificate_complete_chain.py +++ b/lib/ansible/modules/crypto/certificate_complete_chain.py @@ -33,13 +33,12 @@ requirements: - "cryptography >= 1.5" options: input_chain: - required: yes description: - A concatenated set of certificates in PEM format forming a chain. - The module will try to complete this chain. - root_certificates: + type: str required: yes - type: list + root_certificates: description: - "A list of filenames or directories." - "A filename is assumed to point to a file containing one or more certificates @@ -49,10 +48,9 @@ options: subdirectories will be scanned and tried to be parsed as concatenated certificates in PEM format." - "Symbolic links will be followed." - intermediate_certificates: - required: no type: list - default: [] + required: yes + intermediate_certificates: description: - "A list of filenames or directories." - "A filename is assumed to point to a file containing one or more certificates @@ -62,6 +60,8 @@ options: subdirectories will be scanned and tried to be parsed as concatenated certificates in PEM format." - "Symbolic links will be followed." + type: list + default: [] ''' @@ -284,9 +284,9 @@ def format_cert(cert): def main(): module = AnsibleModule( argument_spec=dict( - input_chain=dict(required=True, type='str'), - root_certificates=dict(required=True, type='list', elements='path'), - intermediate_certificates=dict(required=False, type='list', elements='path', default=[]), + input_chain=dict(type='str', required=True), + root_certificates=dict(type='list', required=True, elements='path'), + intermediate_certificates=dict(type='list', default=[], elements='path'), ), supports_check_mode=True, ) diff --git a/lib/ansible/modules/crypto/get_certificate.py b/lib/ansible/modules/crypto/get_certificate.py index c59a3d40ff4..b2f5d7e7762 100644 --- a/lib/ansible/modules/crypto/get_certificate.py +++ b/lib/ansible/modules/crypto/get_certificate.py @@ -22,20 +22,22 @@ options: host: description: - The host to get the cert for (IP is fine) - required: True + type: str + required: true ca_certs: description: - A PEM file containing a list of root certificates; if present, the cert will be validated against these root certs. - Note that this only validates the certificate is signed by the chain; not that the cert is valid for the host presenting it. - required: False + type: path port: description: - The port to connect to - required: True + type: int + required: true timeout: description: - The timeout in seconds - required: False + type: int default: 10 notes: @@ -128,10 +130,10 @@ else: def main(): module = AnsibleModule( argument_spec=dict( - ca_certs=dict(required=False, type='path', default=None), - host=dict(required=True), - port=dict(required=True, type='int'), - timeout=dict(required=False, type='int', default=10), + ca_certs=dict(type='path'), + host=dict(type='str', required=True), + port=dict(type='int', required=True), + timeout=dict(type='int', default=10), ), ) diff --git a/lib/ansible/modules/crypto/luks_device.py b/lib/ansible/modules/crypto/luks_device.py index f8959c96f91..128e0876146 100644 --- a/lib/ansible/modules/crypto/luks_device.py +++ b/lib/ansible/modules/crypto/luks_device.py @@ -47,9 +47,9 @@ options: does not exist it will be created. Requires I(device) and I(keyfile) options to be provided. If container does already exist I(device) or I(name) will suffice." + type: str default: present choices: [present, absent, opened, closed] - type: str name: description: - "Sets container name when I(state=opened). Can be used @@ -407,15 +407,12 @@ class ConditionsHandler(Handler): def run_module(): # available arguments/parameters that a user can pass module_args = dict( - state=dict(type='str', - choices=['present', 'absent', 'opened', 'closed'], - required=False, - default='present'), - device=dict(type='str', required=False), - name=dict(type='str', required=False), - keyfile=dict(type='path', required=False), - new_keyfile=dict(type='path', required=False), - remove_keyfile=dict(type='path', required=False) + state=dict(type='str', default='present', choices=['present', 'absent', 'opened', 'closed']), + device=dict(type='str'), + name=dict(type='str'), + keyfile=dict(type='path'), + new_keyfile=dict(type='path'), + remove_keyfile=dict(type='path') ) # seed the result dict in the object diff --git a/lib/ansible/modules/crypto/openssh_cert.py b/lib/ansible/modules/crypto/openssh_cert.py index 33322d7b8b4..00e6d61f75c 100644 --- a/lib/ansible/modules/crypto/openssh_cert.py +++ b/lib/ansible/modules/crypto/openssh_cert.py @@ -26,69 +26,65 @@ requirements: - "ssh-keygen" options: state: - required: false - default: "present" - choices: [ 'present', 'absent' ] description: - Whether the host or user certificate should exist or not, taking action if the state is different from what is stated. + type: str + default: "present" + choices: [ 'present', 'absent' ] type: - required: true - choices: ['host', 'user'] description: - Whether the module should generate a host or a user certificate. + type: str + required: true + choices: ['host', 'user'] force: - required: false - default: false - type: bool description: - Should the certificate be regenerated even if it already exists and is valid. + type: bool + default: false path: - required: true - type: path description: - Path of the file containing the certificate. - signing_key: - required: true type: path + required: true + signing_key: description: - The path to the private openssh key that is used for signing the public key in order to generate the certificate. - public_key: - required: true type: path + required: true + public_key: description: - The path to the public key that will be signed with the signing key in order to generate the certificate. - valid_from: + type: path required: true - type: str + valid_from: description: - "The point in time the certificate is valid from. Time can be specified either as relative time or as absolute timestamp. Time will always be interpreted as UTC. Valid formats are: C([+-]timespec | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS | YYYY-MM-DD HH:MM:SS | always) where timespec can be an integer + C([w | d | h | m | s]) (e.g. C(+32w1d2h). Note that if using relative time this module is NOT idempotent." - valid_to: - required: true type: str + required: true + valid_to: description: - "The point in time the certificate is valid to. Time can be specified either as relative time or as absolute timestamp. Time will always be interpreted as UTC. Valid formats are: C([+-]timespec | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS | YYYY-MM-DD HH:MM:SS | forever) where timespec can be an integer + C([w | d | h | m | s]) (e.g. C(+32w1d2h). Note that if using relative time this module is NOT idempotent." - valid_at: - required: false type: str + required: true + valid_at: description: - "Check if the certificate is valid at a certain point in time. If it is not the certificate will be regenerated. Time will always be interpreted as UTC. Mainly to be used with relative timespec for I(valid_from) and / or I(valid_to). Note that if using relative time this module is NOT idempotent." + type: str principals: - required: false - type: list description: - "Certificates may be limited to be valid for a set of principal (user/host) names. By default, generated certificates are valid for all users or hosts." - options: - required: false type: list + options: description: - "Specify certificate options when signing a key. The option that are valid for user certificates are:" - "C(clear): Clear all enabled permissions. This is useful for clearing the default set of permissions so permissions may be added individually." @@ -107,12 +103,11 @@ options: - "C(source-address=address_list): Restrict the source addresses from which the certificate is considered valid. The C(address_list) is a comma-separated list of one or more address/netmask pairs in CIDR format." - "At present, no options are valid for host keys." - + type: list identifier: - required: false - type: str description: - Specify the key identity when signing a public key. The identifier that is logged by the server when the certificate is used for authentication. + type: str extends_documentation_fragment: files ''' diff --git a/lib/ansible/modules/crypto/openssh_keypair.py b/lib/ansible/modules/crypto/openssh_keypair.py index ad0e2f3eac4..ad8318d2248 100644 --- a/lib/ansible/modules/crypto/openssh_keypair.py +++ b/lib/ansible/modules/crypto/openssh_keypair.py @@ -28,40 +28,40 @@ requirements: - "ssh-keygen" options: state: - required: false - default: present - choices: [ present, absent ] description: - Whether the private and public keys should exist or not, taking action if the state is different from what is stated. + type: str + default: present + choices: [ present, absent ] size: - required: false description: - "Specifies the number of bits in the private key to create. For RSA keys, the minimum size is 1024 bits and the default is 4096 bits. Generally, 2048 bits is considered sufficient. DSA keys must be exactly 1024 bits as specified by FIPS 186-2. For ECDSA keys, size determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will cause this module to fail. Ed25519 keys have a fixed length and the size will be ignored." + type: int type: - required: false - default: rsa - choices: ['rsa', 'dsa', 'rsa1', 'ecdsa', 'ed25519'] description: - "The algorithm used to generate the SSH private key. C(rsa1) is for protocol version 1. C(rsa1) is deprecated and may not be supported by every version of ssh-keygen." + type: str + default: rsa + choices: ['rsa', 'dsa', 'rsa1', 'ecdsa', 'ed25519'] force: - required: false - default: false - type: bool description: - Should the key be regenerated even if it already exists + type: bool + default: false path: - required: true description: - Name of the files containing the public and private key. The file containing the public key will have the extension C(.pub). + type: path + required: true comment: - required: false description: - Provides a new comment to the public key. When checking if the key is in the correct state this will be ignored. + type: str extends_documentation_fragment: files ''' @@ -260,11 +260,11 @@ def main(): # Define Ansible Module module = AnsibleModule( argument_spec=dict( - state=dict(default='present', choices=['present', 'absent'], type='str'), + state=dict(type='str', default='present', choices=['present', 'absent']), size=dict(type='int'), - type=dict(default='rsa', choices=['rsa', 'dsa', 'rsa1', 'ecdsa', 'ed25519'], type='str'), - force=dict(default=False, type='bool'), - path=dict(required=True, type='path'), + type=dict(type='str', default='rsa', choices=['rsa', 'dsa', 'rsa1', 'ecdsa', 'ed25519']), + force=dict(type='bool', default=False), + path=dict(type='path', required=True), comment=dict(type='str'), ), supports_check_mode=True, diff --git a/lib/ansible/modules/crypto/openssl_certificate.py b/lib/ansible/modules/crypto/openssl_certificate.py index b5a8bb717f5..cae9dc517d3 100644 --- a/lib/ansible/modules/crypto/openssl_certificate.py +++ b/lib/ansible/modules/crypto/openssl_certificate.py @@ -40,8 +40,8 @@ options: description: - Whether the certificate should exist or not, taking action if the state is different from what is stated. type: str - choices: [ absent, present ] default: present + choices: [ absent, present ] path: description: @@ -53,8 +53,8 @@ options: description: - Name of the provider to use to generate/retrieve the OpenSSL certificate. - The C(assertonly) provider will not generate files and fail if the certificate file is missing. - required: true type: str + required: true choices: [ acme, assertonly, ownca, selfsigned ] force: @@ -312,6 +312,7 @@ options: type: bool default: no aliases: [ subjectAltName_strict ] + extends_documentation_fragment: files notes: - All ASN.1 TIME values should be specified following the YYYYMMDDHHMMSSZ pattern. @@ -1051,7 +1052,7 @@ class AcmeCertificate(Certificate): def main(): module = AnsibleModule( argument_spec=dict( - state=dict(type='str', choices=['present', 'absent'], default='present'), + state=dict(type='str', default='present', choices=['present', 'absent']), path=dict(type='path', required=True), provider=dict(type='str', choices=['acme', 'assertonly', 'ownca', 'selfsigned']), force=dict(type='bool', default=False,), @@ -1082,10 +1083,8 @@ def main(): # provider: selfsigned selfsigned_version=dict(type='int', default=3), selfsigned_digest=dict(type='str', default='sha256'), - selfsigned_not_before=dict( - type='str', default='+0s', aliases=['selfsigned_notBefore']), - selfsigned_not_after=dict( - type='str', default='+3650d', aliases=['selfsigned_notAfter']), + selfsigned_not_before=dict(type='str', default='+0s', aliases=['selfsigned_notBefore']), + selfsigned_not_after=dict(type='str', default='+3650d', aliases=['selfsigned_notAfter']), # provider: ownca ownca_path=dict(type='path'), diff --git a/lib/ansible/modules/crypto/openssl_csr.py b/lib/ansible/modules/crypto/openssl_csr.py index cd1a8b7bf44..147cdc88563 100644 --- a/lib/ansible/modules/crypto/openssl_csr.py +++ b/lib/ansible/modules/crypto/openssl_csr.py @@ -31,9 +31,8 @@ options: description: - Whether the certificate signing request should exist or not, taking action if the state is different from what is stated. type: str - required: false - choices: [ absent, present ] default: present + choices: [ absent, present ] digest: description: - The digest used when signing the certificate signing request with the private key. @@ -127,8 +126,8 @@ options: C(subject_alt_name) with C(DNS:) prefix if no SAN is specified. type: bool default: yes - aliases: [ useCommonNameForSAN ] version_added: '2.8' + aliases: [ useCommonNameForSAN ] key_usage: description: - This defines the purpose (e.g. encipherment, signature, certificate signing) @@ -155,21 +154,21 @@ options: description: - Indicates basic constraints, such as if the certificate is a CA. type: list - aliases: [ basicConstraints ] version_added: '2.5' + aliases: [ basicConstraints ] basic_constraints_critical: description: - Should the basicConstraints extension be considered as critical. type: bool - aliases: [ basicConstraints_critical ] version_added: '2.5' + aliases: [ basicConstraints_critical ] ocsp_must_staple: description: - Indicates that the certificate should contain the OCSP Must Staple extension (U(https://tools.ietf.org/html/rfc7633)). type: bool - aliases: [ ocspMustStaple ] version_added: '2.5' + aliases: [ ocspMustStaple ] ocsp_must_staple_critical: description: - Should the OCSP Must Staple extension be considered as critical @@ -178,8 +177,8 @@ options: are required to reject such certificates (see U(https://tools.ietf.org/html/rfc7633#section-4)). type: bool - aliases: [ ocspMustStaple_critical ] version_added: '2.5' + aliases: [ ocspMustStaple_critical ] select_crypto_backend: description: - Determines which crypto backend to use. @@ -187,8 +186,8 @@ options: - If set to C(pyopenssl), will try to use the L(pyOpenSSL,https://pypi.org/project/pyOpenSSL/) library. - If set to C(cryptography), will try to use the L(cryptography,https://cryptography.io/) library. type: str - choices: [ auto, cryptography, pyopenssl ] default: auto + choices: [ auto, cryptography, pyopenssl ] version_added: '2.8' extends_documentation_fragment: - files diff --git a/lib/ansible/modules/crypto/openssl_dhparam.py b/lib/ansible/modules/crypto/openssl_dhparam.py index 82b7a513d25..a7e3d935361 100644 --- a/lib/ansible/modules/crypto/openssl_dhparam.py +++ b/lib/ansible/modules/crypto/openssl_dhparam.py @@ -29,8 +29,8 @@ options: - Whether the parameters should exist or not, taking action if the state is different from what is stated. type: str - choices: [ absent, present ] default: present + choices: [ absent, present ] size: description: - Size (in bits) of the generated DH-params. diff --git a/lib/ansible/modules/crypto/openssl_pkcs12.py b/lib/ansible/modules/crypto/openssl_pkcs12.py index 3cc17fe10a8..7c69543f8bc 100644 --- a/lib/ansible/modules/crypto/openssl_pkcs12.py +++ b/lib/ansible/modules/crypto/openssl_pkcs12.py @@ -26,8 +26,9 @@ options: action: description: - C(export) or C(parse) a PKCS#12. - choices: [ export, parse ] + type: str default: export + choices: [ export, parse ] ca_certificates: description: - List of CA certificate to include. @@ -65,7 +66,7 @@ options: description: - Filename to write the PKCS#12 file to. type: path - required: True + required: true privatekey_passphrase: description: - Passphrase source to decrypt any input private keys with. @@ -80,6 +81,7 @@ options: All parameters except C(path) are ignored when state is C(absent). choices: [ absent, present ] default: present + type: str src: description: - PKCS#12 file path to parse. diff --git a/lib/ansible/modules/crypto/openssl_privatekey.py b/lib/ansible/modules/crypto/openssl_privatekey.py index 360f1d8c1ac..46e30645c75 100644 --- a/lib/ansible/modules/crypto/openssl_privatekey.py +++ b/lib/ansible/modules/crypto/openssl_privatekey.py @@ -37,8 +37,8 @@ options: description: - Whether the private key should exist or not, taking action if the state is different from what is stated. type: str - choices: [ absent, present ] default: present + choices: [ absent, present ] size: description: - Size (in bits) of the TLS/SSL key to generate. @@ -50,9 +50,9 @@ options: - Note that C(ECC) requires the C(cryptography) backend. - Depending on the curve, you need a newer version of the cryptography backend. type: str + default: RSA #choices: [ DSA, ECC, RSA, X448, X25519 ] choices: [ DSA, ECC, RSA ] - default: RSA curve: description: - Note that not all curves are supported by all versions of C(cryptography). @@ -108,8 +108,8 @@ options: - If set to C(pyopenssl), will try to use the L(pyOpenSSL,https://pypi.org/project/pyOpenSSL/) library. - If set to C(cryptography), will try to use the L(cryptography,https://cryptography.io/) library. type: str - choices: [ auto, cryptography, pyopenssl ] default: auto + choices: [ auto, cryptography, pyopenssl ] version_added: "2.8" extends_documentation_fragment: - files @@ -551,25 +551,25 @@ def main(): module = AnsibleModule( argument_spec=dict( - state=dict(default='present', choices=['present', 'absent'], type='str'), - size=dict(default=4096, type='int'), - type=dict(default='RSA', choices=[ + state=dict(type='str', default='present', choices=['present', 'absent']), + size=dict(type='int', default=4096), + type=dict(type='str', default='RSA', choices=[ 'RSA', 'DSA', 'ECC', # x25519 is missing serialization functions: https://github.com/pyca/cryptography/issues/4386 # x448 is also missing it: https://github.com/pyca/cryptography/pull/4580#issuecomment-437913340 # 'X448', 'X25519', - ], type='str'), - curve=dict(choices=[ + ]), + curve=dict(type='str', choices=[ 'secp384r1', 'secp521r1', 'secp224r1', 'secp192r1', 'secp256k1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1', 'sect571k1', 'sect409k1', 'sect283k1', 'sect233k1', 'sect163k1', 'sect571r1', 'sect409r1', 'sect283r1', 'sect233r1', 'sect163r2', - ], type='str'), - force=dict(default=False, type='bool'), - path=dict(required=True, type='path'), + ]), + force=dict(type='bool', default=False), + path=dict(type='path', required=True), passphrase=dict(type='str', no_log=True), cipher=dict(type='str'), - select_crypto_backend=dict(required=False, choices=['auto', 'pyopenssl', 'cryptography'], default='auto', type='str'), + select_crypto_backend=dict(type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'), ), supports_check_mode=True, add_file_common_args=True, diff --git a/lib/ansible/modules/crypto/openssl_publickey.py b/lib/ansible/modules/crypto/openssl_publickey.py index 0a616497aec..d1e3f78cd1b 100644 --- a/lib/ansible/modules/crypto/openssl_publickey.py +++ b/lib/ansible/modules/crypto/openssl_publickey.py @@ -30,8 +30,8 @@ options: description: - Whether the public key should exist or not, taking action if the state is different from what is stated. type: str - choices: [ absent, present ] default: present + choices: [ absent, present ] force: description: - Should the key be regenerated even it it already exists. @@ -41,8 +41,8 @@ options: description: - The format of the public key. type: str - choices: [ OpenSSH, PEM ] default: PEM + choices: [ OpenSSH, PEM ] version_added: "2.4" path: description: diff --git a/lib/ansible/plugins/doc_fragments/acme.py b/lib/ansible/plugins/doc_fragments/acme.py index c058435b576..59079758f49 100644 --- a/lib/ansible/plugins/doc_fragments/acme.py +++ b/lib/ansible/plugins/doc_fragments/acme.py @@ -33,6 +33,7 @@ options: private keys in PEM format can be used as well." - "Mutually exclusive with C(account_key_content)." - "Required if C(account_key_content) is not used." + type: path aliases: [ account_key ] account_key_content: description: @@ -48,18 +49,21 @@ options: temporary file. It can still happen that it is written to disk by Ansible in the process of moving the module with its argument to the node where it is executed." + type: str version_added: "2.5" account_uri: description: - "If specified, assumes that the account URI is as given. If the account key does not match this account, or an account with this URI does not exist, the module fails." + type: str version_added: "2.7" acme_version: description: - "The ACME version of the endpoint." - "Must be 1 for the classic Let's Encrypt ACME endpoint, or 2 for the new standardized ACME v2 endpoint." + type: int default: 1 choices: [1, 2] version_added: "2.5" @@ -78,6 +82,7 @@ options: - "I(Warning): So far, the module has only been tested against Let's Encrypt (staging and production) and against the L(Pebble testing server,https://github.com/letsencrypt/Pebble)." + type: str default: https://acme-staging.api.letsencrypt.org/directory validate_certs: description: @@ -85,7 +90,7 @@ options: - "I(Warning): Should I(only ever) be set to C(no) for testing purposes, for example when testing against a local Pebble server." type: bool - default: 'yes' + default: yes version_added: "2.5" select_crypto_backend: description: