<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

# (c) 2016 <NAME> <<EMAIL>>
# 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_certificate
author: "<NAME> (@mgruener)"
version_added: "2.2"
short_description: Create SSL certificates with an ACME protocol endpoint
description:
   - "Create and renew SSL certificates with a CA supporting the ACME protocol,
      such as Let's Encrypt (U(https://letsencrypt.org)). For details see
      U(https://letsencrypt.org). The current implementation supports the
      C(http-01) and C(dns-01) challenges."
   - "To use this module, it has to be executed twice. Either as two
      different tasks in the same run or during two runs. Note that the output
      of the first run needs to be recorded and passed to the second run as the
      module argument C(data)."
   - "Between these two tasks you have to fulfill the required steps for the
      chosen challenge by whatever means necessary. For C(http-01) that means
      creating the necessary challenge file on the destination webserver. For
      C(dns-01) the necessary dns record has to be created.
      It is I(not) the responsibility of this module to perform these steps."
   - "For details on how to fulfill these challenges, you might have to read through
      U(https://tools.ietf.org/html/draft-ietf-acme-acme-12#section-8).
      Also, consider the examples provided for this module."
   - "Although the defaults are chosen so that the module can be used with
      the Let's Encrypt CA, the module can be used with any service using the ACME
      v1 or v2 protocol."
   - "At least one of C(dest) and C(fullchain_dest) must be specified."
   - "Note: this module was called C(letsencrypt) before Ansible 2.6. The usage
      did not change."
requirements:
  - "python >= 2.6"
  - openssl
options:
  account_key_src:
    description:
      - "Path to a file containing the ACME account RSA or Elliptic Curve
         key."
      - "RSA keys can be created with C(openssl rsa ...). Elliptic curve keys can
         be created with C(openssl ecparam -genkey ...)."
      - "Mutually exclusive with C(account_key_content)."
      - "Required if C(account_key_content) is not used."
    aliases: [ account_key ]
  account_key_content:
    description:
      - "Content of the ACME account RSA or Elliptic Curve key."
      - "Mutually exclusive with C(account_key_src)."
      - "Required if C(account_key_src) is not used."
      - "Warning: the content will be written into a temporary file, which will
         be deleted by Ansible when the module completes. Since this is an
         important private key — it can be used to change the account key,
         or to revoke your certificates without knowing their private keys
         —, this might not be acceptable."
    version_added: "2.5"
  account_email:
    description:
      - "The email address associated with this account."
      - "It will be used for certificate expiration warnings."
  acme_directory:
    description:
      - "The ACME directory to use. This is the entry point URL to access
         CA server API."
      - "For safety reasons the default is set to the Let's Encrypt staging
         server (for the ACME v1 protocol). This will create technically correct,
         but untrusted certificates."
      - "For Let's Encrypt, all staging endpoints can be found here:
         U(https://letsencrypt.org/docs/staging-environment/)"
      - "For Let's Encrypt, the production directory URL for ACME v1 is
         U(https://acme-v01.api.letsencrypt.org/directory), and the production
         directory URL for ACME v2 is U(https://acme-v02.api.letsencrypt.org/directory)."
      - "I(Warning): So far, the module has only been tested against Let's Encrypt
         (staging and production) and against the Pebble testing server
         (U(https://github.com/letsencrypt/Pebble))."
    default: https://acme-staging.api.letsencrypt.org/directory
  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."
    default: 1
    choices: [1, 2]
    version_added: "2.5"
  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.
  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'
    version_added: "2.5"
  challenge:
    description: The challenge to be performed.
    choices: [ 'http-01', 'dns-01']
    default: 'http-01'
  csr:
    description:
      - "File containing the CSR for the new certificate."
      - "Can be created with C(openssl req ...)."
      - "The CSR may contain multiple Subject Alternate Names, but each one
         will lead to an individual challenge that must be fulfilled for the
         CSR to be signed."
      - "I(Note): the private key used to create the CSR I(must not) be the the
         account key. This is a bad idea from a security point of view, and
         the CA should not accept the CSR. Let's Encrypt will return an error
         in this case."
    required: true
    aliases: ['src']
  data:
    description:
      - "The data to validate ongoing challenges. This must be specified for
         the second run of the module only."
      - "The value that must be used here will be provided by a previous use
         of this module. See the examples for more details."
      - "I(Note): the C(data) option was marked as C(no_log) up to
         Ansible 2.5. From Ansible 2.6 on, it is no longer marked this way
         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."
  dest:
    description:
      - "The destination file for the certificate."
      - "Required if C(fullchain_dest) is not specified."
    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."
    version_added: 2.5
    aliases: ['fullchain']
  chain_dest:
    description:
      - If specified, the intermediate certificate will be written to this file.
    aliases: ['chain']
    version_added: 2.5
  remaining_days:
    description:
      - "The number of days the certificate must have left being valid.
         If C(cert_days < remaining_days), then it will be renewed.
         If the certificate is not renewed, module return values will not
         include C(challenge_data)."
    default: 10
  validate_certs:
    description:
      - Whether calls to the ACME directory will validate TLS certificates.
      - 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'
    version_added: 2.5
  deactivate_authzs:
    description:
      - "Deactivate authentication objects (authz) after issuing a certificate,
         or when issuing the certificate failed."
      - "Authentication objects are bound to an account key and remain valid
         for a certain amount of time, and can be used to issue certificates
         without having to re-authenticate the domain. This can be a security
         concern. "
    type: bool
    default: 'no'
    version_added: 2.6
  force:
    description:
      - Enforces the execution of the challenge and validation, even if an
        existing certificate is still valid.
      - 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'
    version_added: 2.6
'''

EXAMPLES = '''
### Example with HTTP challenge ###

- name: Create a challenge for sample.com using a account key from a variable.
  acme_certificate:
    account_key_content: "{{ account_private_key }}"
    csr: /etc/pki/cert/csr/sample.com.csr
    dest: /etc/httpd/ssl/sample.com.crt
  register: sample_com_challenge

# Alternative first step:
- name: Create a challenge for sample.com using a account key from hashi vault.
  acme_certificate:
    account_key_content: "{{ lookup('hashi_vault', 'secret=secret/account_private_key:value') }}"
    csr: /etc/pki/cert/csr/sample.com.csr
    fullchain_dest: /etc/httpd/ssl/sample.com-fullchain.crt
  register: sample_com_challenge

# Alternative first step:
- name: Create a challenge for sample.com using a account key file.
  acme_certificate:<commit_msg>Prevent Jinja2 string escaping in alternative Route53 example from getting lost in translation. (#40376)<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

# (c) 2016 <NAME> <<EMAIL>>
# 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_certificate
author: "<NAME> (@mgruener)"
version_added: "2.2"
short_description: Create SSL certificates with an ACME protocol endpoint
description:
   - "Create and renew SSL certificates with a CA supporting the ACME protocol,
      such as Let's Encrypt (U(https://letsencrypt.org)). For details see
      U(https://letsencrypt.org). The current implementation supports the
      C(http-01) and C(dns-01) challenges."
   - "To use this module, it has to be executed twice. Either as two
      different tasks in the same run or during two runs. Note that the output
      of the first run needs to be recorded and passed to the second run as the
      module argument C(data)."
   - "Between these two tasks you have to fulfill the required steps for the
      chosen challenge by whatever means necessary. For C(http-01) that means
      creating the necessary challenge file on the destination webserver. For
      C(dns-01) the necessary dns record has to be created.
      It is I(not) the responsibility of this module to perform these steps."
   - "For details on how to fulfill these challenges, you might have to read through
      U(https://tools.ietf.org/html/draft-ietf-acme-acme-12#section-8).
      Also, consider the examples provided for this module."
   - "Although the defaults are chosen so that the module can be used with
      the Let's Encrypt CA, the module can be used with any service using the ACME
      v1 or v2 protocol."
   - "At least one of C(dest) and C(fullchain_dest) must be specified."
   - "Note: this module was called C(letsencrypt) before Ansible 2.6. The usage
      did not change."
requirements:
  - "python >= 2.6"
  - openssl
options:
  account_key_src:
    description:
      - "Path to a file containing the ACME account RSA or Elliptic Curve
         key."
      - "RSA keys can be created with C(openssl rsa ...). Elliptic curve keys can
         be created with C(openssl ecparam -genkey ...)."
      - "Mutually exclusive with C(account_key_content)."
      - "Required if C(account_key_content) is not used."
    aliases: [ account_key ]
  account_key_content:
    description:
      - "Content of the ACME account RSA or Elliptic Curve key."
      - "Mutually exclusive with C(account_key_src)."
      - "Required if C(account_key_src) is not used."
      - "Warning: the content will be written into a temporary file, which will
         be deleted by Ansible when the module completes. Since this is an
         important private key — it can be used to change the account key,
         or to revoke your certificates without knowing their private keys
         —, this might not be acceptable."
    version_added: "2.5"
  account_email:
    description:
      - "The email address associated with this account."
      - "It will be used for certificate expiration warnings."
  acme_directory:
    description:
      - "The ACME directory to use. This is the entry point URL to access
         CA server API."
      - "For safety reasons the default is set to the Let's Encrypt staging
         server (for the ACME v1 protocol). This will create technically correct,
         but untrusted certificates."
      - "For Let's Encrypt, all staging endpoints can be found here:
         U(https://letsencrypt.org/docs/staging-environment/)"
      - "For Let's Encrypt, the production directory URL for ACME v1 is
         U(https://acme-v01.api.letsencrypt.org/directory), and the production
         directory URL for ACME v2 is U(https://acme-v02.api.letsencrypt.org/directory)."
      - "I(Warning): So far, the module has only been tested against Let's Encrypt
         (staging and production) and against the Pebble testing server
         (U(https://github.com/letsencrypt/Pebble))."
    default: https://acme-staging.api.letsencrypt.org/directory
  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."
    default: 1
    choices: [1, 2]
    version_added: "2.5"
  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.
  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'
    version_added: "2.5"
  challenge:
    description: The challenge to be performed.
    choices: [ 'http-01', 'dns-01']
    default: 'http-01'
  csr:
    description:
      - "File containing the CSR for the new certificate."
      - "Can be created with C(openssl req ...)."
      - "The CSR may contain multiple Subject Alternate Names, but each one
         will lead to an individual challenge that must be fulfilled for the
         CSR to be signed."
      - "I(Note): the private key used to create the CSR I(must not) be the the
         account key. This is a bad idea from a security point of view, and
         the CA should not accept the CSR. Let's Encrypt will return an error
         in this case."
    required: true
    aliases: ['src']
  data:
    description:
      - "The data to validate ongoing challenges. This must be specified for
         the second run of the module only."
      - "The value that must be used here will be provided by a previous use
         of this module. See the examples for more details."
      - "I(Note): the C(data) option was marked as C(no_log) up to
         Ansible 2.5. From Ansible 2.6 on, it is no longer marked this way
         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."
  dest:
    description:
      - "The destination file for the certificate."
      - "Required if C(fullchain_dest) is not specified."
    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."
    version_added: 2.5
    aliases: ['fullchain']
  chain_dest:
    description:
      - If specified, the intermediate certificate will be written to this file.
    aliases: ['chain']
    version_added: 2.5
  remaining_days:
    description:
      - "The number of days the certificate must have left being valid.
         If C(cert_days < remaining_days), then it will be renewed.
         If the certificate is not renewed, module return values will not
         include C(challenge_data)."
    default: 10
  validate_certs:
    description:
      - Whether calls to the ACME directory will validate TLS certificates.
      - 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'
    version_added: 2.5
  deactivate_authzs:
    description:
      - "Deactivate authentication objects (authz) after issuing a certificate,
         or when issuing the certificate failed."
      - "Authentication objects are bound to an account key and remain valid
         for a certain amount of time, and can be used to issue certificates
         without having to re-authenticate the domain. This can be a security
         concern. "
    type: bool
    default: 'no'
    version_added: 2.6
  force:
    description:
      - Enforces the execution of the challenge and validation, even if an
        existing certificate is still valid.
      - 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'
    version_added: 2.6
'''

EXAMPLES = R'''
### Example with HTTP challenge ###

- name: Create a challenge for sample.com using a account key from a variable.
  acme_certificate:
    account_key_content: "{{ account_private_key }}"
    csr: /etc/pki/cert/csr/sample.com.csr
    dest: /etc/httpd/ssl/sample.com.crt
  register: sample_com_challenge

# Alternative first step:
- name: Create a challenge for sample.com using a account key from hashi vault.
  acme_certificate:
    account_key_content: "{{ lookup('hashi_vault', 'secret=secret/account_private_key:value') }}"
    csr: /etc/pki/cert/csr/sample.com.csr
    fullchain_dest: /etc/httpd/ssl/sample.com-fullchain.crt
  register: sample_com_challenge

# Alternative first step:
- name: Create a challenge for sample.com using a account key file.
  acme_certificate:
{'fraction_non_alphanumeric': 0.07780639622236532, 'fraction_numerical': 0.008370895041854474, 'mean_word_length': 2.7612512613521694, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 18, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6343355', 'n_tokens_mistral': 5317, 'n_tokens_neox': 5131, 'n_words': 2249}