---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

- block:
  - name: Generate account keys
    openssl_privatekey:
      path: "{{ remote_tmp_dir }}/{{ item }}.pem"
      type: ECC
      curve: secp256r1
      force: true
    loop: "{{ account_keys }}"

  - name: Parse account keys (to ease debugging some test failures)
    openssl_privatekey_info:
      path: "{{ remote_tmp_dir }}/{{ item }}.pem"
      return_private_key_data: true
    loop: "{{ account_keys }}"

  vars:
    account_keys:
      - accountkey

- name: Get directory
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    method: directory-only
    select_crypto_backend: "{{ select_crypto_backend }}"
  register: directory
- debug: var=directory

- name: Create an account
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    url: "{{ directory.directory.newAccount}}"
    method: post
    content: '{"termsOfServiceAgreed":true}'
    select_crypto_backend: "{{ select_crypto_backend }}"
  register: account_creation
  # account_creation.headers.location contains the account URI
  # if creation was successful
- debug: var=account_creation

- name: Get account information
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ account_creation.headers.location }}"
    method: get
    select_crypto_backend: "{{ select_crypto_backend }}"
  register: account_get
- debug: var=account_get

- name: Update account contacts
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ account_creation.headers.location }}"
    method: post
    content: '{{ account_info | to_json }}'
    select_crypto_backend: "{{ select_crypto_backend }}"
  vars:
    account_info:
      # For valid values, see
      # https://www.rfc-editor.org/rfc/rfc8555.html#section-7.3
      contact:
      - mailto:me@example.com
  register: account_update
- debug: var=account_update

- name: Create certificate order
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ directory.directory.newOrder }}"
    method: post
    content: '{{ create_order | to_json }}'
    select_crypto_backend: "{{ select_crypto_backend }}"
  vars:
    create_order:
      # For valid values, see
      # https://www.rfc-editor.org/rfc/rfc8555.html#section-7.4 and
      # https://www.rfc-editor.org/rfc/rfc8738.html
      identifiers:
      - type: dns
        value: example.com
      - type: dns
        value: example.org
  register: new_order
- debug: var=new_order

- name: Get order information
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ new_order.headers.location }}"
    method: get
    select_crypto_backend: "{{ select_crypto_backend }}"
  register: order
- debug: var=order

- name: Get authzs for order
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ item }}"
    method: get
    select_crypto_backend: "{{ select_crypto_backend }}"
  loop: "{{ order.output_json.authorizations }}"
  register: authz
- debug: var=authz

- name: Get HTTP-01 challenge for authz
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ (item.challenges | selectattr('type', 'equalto', 'http-01') | list)[0].url }}"
    method: get
    select_crypto_backend: "{{ select_crypto_backend }}"
  register: http01challenge
  loop: "{{ authz.results | map(attribute='output_json') | list }}"
- debug: var=http01challenge

- name: Activate HTTP-01 challenge manually
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ item.url }}"
    method: post
    content: '{}'
    select_crypto_backend: "{{ select_crypto_backend }}"
  register: activation
  loop: "{{ http01challenge.results | map(attribute='output_json') | list }}"
- debug: var=activation

- name: Get HTTP-01 challenge results
  acme_inspect:
    acme_directory: "{{ acme_directory_url }}"
    acme_version: 2
    validate_certs: false
    account_key_src: "{{ remote_tmp_dir }}/accountkey.pem"
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ item.url }}"
    method: get
    select_crypto_backend: "{{ select_crypto_backend }}"
  register: validation_result
  loop: "{{ http01challenge.results | map(attribute='output_json') | list }}"
  until: "validation_result.output_json.status not in ['pending', 'processing']"
  retries: 20
  delay: 1
- debug: var=validation_result
