Ë
    ÇVh¸.  ã                   ó€   — d dl mZmZmZ eZdZdZdZd dl	m
Z
mZmZ d dlmZmZmZ d dlmZmZ d„ Zed	k(  r e«        y
y
)é    )Úabsolute_importÚdivisionÚprint_functiona  
module: acme_inspect
author: "Felix Fontein (@felixfontein)"
short_description: Send direct requests to an ACME server
description:
  - Allows to send direct requests to an ACME server with the L(ACME protocol,https://tools.ietf.org/html/rfc8555), which
    is supported by CAs such as L(Let's Encrypt,https://letsencrypt.org/).
  - This module can be used to debug failed certificate request attempts, for example when M(community.crypto.acme_certificate)
    fails or encounters a problem which you wish to investigate.
  - The module can also be used to directly access features of an ACME servers which are not yet supported by the Ansible
    ACME modules.
notes:
  - The O(account_uri) option must be specified for properly authenticated ACME v2 requests (except a C(new-account) request).
  - "Using the C(ansible) tool, M(community.crypto.acme_inspect) can be used to directly execute ACME requests without the
    need of writing a playbook. For example, the following command retrieves the ACME account with ID 1 from Let's Encrypt
    (assuming C(/path/to/key) is the correct private account key): C(ansible localhost -m acme_inspect -a \"account_key_src=/path/to/key
    acme_directory=https://acme-v02.api.letsencrypt.org/directory acme_version=2 account_uri=https://acme-v02.api.letsencrypt.org/acme/acct/1
    method=get url=https://acme-v02.api.letsencrypt.org/acme/acct/1\")."
seealso:
  - name: Automatic Certificate Management Environment (ACME)
    description: The specification of the ACME protocol (RFC 8555).
    link: https://tools.ietf.org/html/rfc8555
  - name: ACME TLS ALPN Challenge Extension
    description: The specification of the C(tls-alpn-01) challenge (RFC 8737).
    link: https://www.rfc-editor.org/rfc/rfc8737.html
extends_documentation_fragment:
  - community.crypto.acme.basic
  - community.crypto.acme.account
  - community.crypto.attributes
  - community.crypto.attributes.actiongroup_acme
attributes:
  check_mode:
    support: none
  diff_mode:
    support: none
  idempotent:
    support: none
options:
  url:
    description:
      - The URL to send the request to.
      - Must be specified if O(method) is not V(directory-only).
    type: str
  method:
    description:
      - The method to use to access the given URL on the ACME server.
      - The value V(post) executes an authenticated POST request. The content must be specified in the O(content) option.
      - The value V(get) executes an authenticated POST-as-GET request for ACME v2, and a regular GET request for ACME v1.
      - The value V(directory-only) only retrieves the directory, without doing a request.
    type: str
    default: get
    choices:
      - get
      - post
      - directory-only
  content:
    description:
      - An encoded JSON object which will be sent as the content if O(method) is V(post).
      - Required when O(method) is V(post), and not allowed otherwise.
    type: str
  fail_on_acme_error:
    description:
      - If O(method) is V(post) or V(get), make the module fail in case an ACME error is returned.
    type: bool
    default: true
aÖ  
---
- name: Get directory
  community.crypto.acme_inspect:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    method: directory-only
  register: directory

- name: Create an account
  community.crypto.acme_inspect:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    account_key_src: /etc/pki/cert/private/account.key
    url: "{{ directory.newAccount}}"
    method: post
    content: '{"termsOfServiceAgreed":true}'
  register: account_creation
  # account_creation.headers.location contains the account URI
  # if creation was successful

- name: Get account information
  community.crypto.acme_inspect:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    account_key_src: /etc/pki/cert/private/account.key
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ account_creation.headers.location }}"
    method: get

- name: Update account contacts
  community.crypto.acme_inspect:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    account_key_src: /etc/pki/cert/private/account.key
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ account_creation.headers.location }}"
    method: post
    content: '{{ account_info | to_json }}'
  vars:
    account_info:
      # For valid values, see
      # https://tools.ietf.org/html/rfc8555#section-7.3
      contact:
        - mailto:me@example.com

- name: Create certificate order
  community.crypto.acme_certificate:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    account_key_src: /etc/pki/cert/private/account.key
    account_uri: "{{ account_creation.headers.location }}"
    csr: /etc/pki/cert/csr/sample.com.csr
    fullchain_dest: /etc/httpd/ssl/sample.com-fullchain.crt
    challenge: http-01
  register: certificate_request

# Assume something went wrong. certificate_request.order_uri contains
# the order URI.

- name: Get order information
  community.crypto.acme_inspect:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    account_key_src: /etc/pki/cert/private/account.key
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ certificate_request.order_uri }}"
    method: get
  register: order

- name: Get first authz for order
  community.crypto.acme_inspect:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    account_key_src: /etc/pki/cert/private/account.key
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ order.output_json.authorizations[0] }}"
    method: get
  register: authz

- name: Get HTTP-01 challenge for authz
  community.crypto.acme_inspect:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    account_key_src: /etc/pki/cert/private/account.key
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ authz.output_json.challenges | selectattr('type', 'equalto', 'http-01') }}"
    method: get
  register: http01challenge

- name: Activate HTTP-01 challenge manually
  community.crypto.acme_inspect:
    acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
    acme_version: 2
    account_key_src: /etc/pki/cert/private/account.key
    account_uri: "{{ account_creation.headers.location }}"
    url: "{{ http01challenge.url }}"
    method: post
    content: '{}'
aË  
directory:
  description: The ACME directory's content.
  returned: always
  type: dict
  sample: {
    "a85k3x9f91A4": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417",
    "keyChange": "https://acme-v02.api.letsencrypt.org/acme/key-change",
    "meta": {
      "caaIdentities": ["letsencrypt.org"],
      "termsOfService": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf",
      "website": "https://letsencrypt.org",
    },
    "newAccount": "https://acme-v02.api.letsencrypt.org/acme/new-acct",
    "newNonce": "https://acme-v02.api.letsencrypt.org/acme/new-nonce",
    "newOrder": "https://acme-v02.api.letsencrypt.org/acme/new-order",
    "revokeCert": "https://acme-v02.api.letsencrypt.org/acme/revoke-cert"
  }
headers:
  description: The request's HTTP headers (with lowercase keys).
  returned: always
  type: dict
  sample: {
    "boulder-requester": "12345",
    "cache-control": "max-age=0, no-cache, no-store",
    "connection": "close",
    "content-length": "904",
    "content-type": "application/json",
    "cookies": {},
    "cookies_string": "",
    "date": "Wed, 07 Nov 2018 12:34:56 GMT",
    "expires": "Wed, 07 Nov 2018 12:44:56 GMT",
    "link": '<https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf>;rel="terms-of-service"',
    "msg": "OK (904 bytes)",
    "pragma": "no-cache",
    "replay-nonce": "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGH",
    "server": "nginx",
    "status": 200,
    "strict-transport-security": "max-age=604800",
    "url": "https://acme-v02.api.letsencrypt.org/acme/acct/46161",
    "x-frame-options": "DENY",
  }
output_text:
  description: The raw text output.
  returned: always
  type: str
  sample: "{\\n  \\\"id\\\": 12345,\\n  \\\"key\\\": {\\n    \\\"kty\\\": \\\"RSA\\\",\\n ..."
output_json:
  description: The output parsed as JSON.
  returned: if output can be parsed as JSON
  type: dict
  sample:
    - id: 12345
    - key:
        - kty: RSA
        - '...'
)Úto_bytesÚ	to_nativeÚto_text)Ú
ACMEClientÚcreate_backendÚcreate_default_argspec)ÚACMEProtocolExceptionÚModuleFailExceptionc            	      óê  — t        d¬«      } | j                  t        d¬«      t        dg d¢d¬«      t        d¬«      t        dd	¬
«      ¬«       | j                  dddggddddggddddgd	gddddgd	gf¬«       | j	                  «       }t        |d«      }t        «       }d}	 t        ||«      }|j                  d   }|j                  j                  |d<   |dk7  rÌ|j                  d   }|j                  d   }|dk(  r|j                  |dd¬«      \  }	}
n6|dk(  r1d	}|j                  |t        |j                  d   «      ddd¬«      \  }	}
|j                  t        
t        	«      ¬«      «       	 |j                  t        |	«      «      |d<   |r|
d   dk\  rt!        ||
|	¬«      ‚ |j"                  dd|i|¤Ž y # t        $ r Y Œ8w xY w# t$        $ r} |j&                  |fi |¤Ž Y d }~y d }~ww xY w)NF)Úrequire_account_keyÚstr)Útype)ÚgetÚpostúdirectory-onlyr   )r   ÚchoicesÚdefaultÚboolT)r   r   )ÚurlÚmethodÚcontentÚfail_on_acme_errorr   r   r   r   Úaccount_key_srcÚaccount_key_content)Úrequired_ifÚ	directoryr   r   )Úparse_json_resultÚfail_on_error)r    Úencode_payloadr!   )ÚheadersÚoutput_textÚoutput_jsonÚstatusi  )Úinfor   Úchanged© )r   Úupdate_argspecÚdictÚupdateÚcreate_ansible_moduler
   r	   Úparamsr   Úget_requestÚsend_signed_requestr   r   Ú	from_jsonr   Ú	Exceptionr   Ú	exit_jsonr   Údo_fail)Úargument_specÚmoduleÚbackendÚresultr(   Úclientr   r   r   Údatar'   Úes               úq/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/crypto/plugins/modules/acme_inspect.pyÚmainr=   ü   sC  € Ü*¸uÔE€MØ× Ñ ÜeÔÜØÒ AÈ5ô
ô ˜%Ô Ü V°TÔ:ð !ô ð ×Ñàu˜u˜gÐ&Øv  yÐ1Ð2ØuÐ0Ð2GÐHÈ$ÐOØvÐ 1Ð3HÐIÈ4ÐPð	
ð ô ð ×0Ñ0Ó2€FÜ˜V UÓ+€Gä‹V€FØ€Gð)$ä˜F GÓ,ˆØ—‘˜xÑ(ˆØ$×.Ñ.×8Ñ8ˆˆ{ÑàÐ%Ò%Ø—-‘- Ñ&ˆCØ!'§¡Ð/CÑ!DÐà˜ŠØ#×/Ñ/Ø¨5Àð 0ó ‘
‘dð ˜6Ò!ØØ#×7Ñ7ØÜ˜VŸ]™]¨9Ñ5Ó6Ø&+Ø#(Ø"'ð 8ó ‘
dð M‰MÜØ Ü )¨$£ôôðØ(.×(8Ñ(8¼À»Ó(G}Ñ%ñ " d¨8¡n¸Ò&;Ü+¨F¸ÀtÔLÐLàˆ×ÑÑ3 Ð3¨FÓ3øô ò Ùðûô ò $Øˆ	‰	&Ñ#˜F×#ûð$ús=   Â#CG Å3F= Æ,G Æ=	G	ÇG ÇG	Ç	G Ç	G2ÇG-Ç-G2Ú__main__N)Ú
__future__r   r   r   r   Ú__metaclass__ÚDOCUMENTATIONÚEXAMPLESÚRETURNÚ+ansible.module_utils.common.text.convertersr   r   r   ÚCansible_collections.community.crypto.plugins.module_utils.acme.acmer	   r
   r   ÚEansible_collections.community.crypto.plugins.module_utils.acme.errorsr   r   r=   Ú__name__r)   ó    r<   ú<module>rI      sb   ð÷ AÑ @ð €ðA€ðFc€ðJ8
€÷t UÑ T÷ñ ÷
ò@$ðF ˆzÒÙ…Fð rH   