
    VhU                        d Z dZdZddlZddlZddlmZ 	 ddlZddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ d Zd Zd Z ej.                  d      Zd Zd Zd Zd Zd Zd Zedk(  r e        yy# e$ r Y fw xY w)aX  
---
module: acm_certificate
short_description: Upload and delete certificates in the AWS Certificate Manager service
version_added: 1.0.0
description:
  - >
    Import and delete certificates in Amazon Web Service's Certificate
    Manager (AWS ACM).
  - >
    This module does not currently interact with AWS-provided certificates.
    It currently only manages certificates provided to AWS by the user.
  - The ACM API allows users to upload multiple certificates for the same domain
    name, and even multiple identical certificates. This module attempts to
    restrict such freedoms, to be idempotent, as per the Ansible philosophy.
    It does this through applying AWS resource "Name" tags to ACM certificates.
  - >
    When I(state=present),
    if there is one certificate in ACM
    with a C(Name) tag equal to the I(name_tag) parameter,
    and an identical body and chain,
    this task will succeed without effect.
  - >
    When I(state=present),
    if there is one certificate in ACM
    a I(Name) tag equal to the I(name_tag) parameter,
    and a different body,
    this task will overwrite that certificate.
  - >
    When I(state=present),
    if there are multiple certificates in ACM
    with a I(Name) tag equal to the I(name_tag) parameter,
    this task will fail.
  - >
    When I(state=absent) and I(certificate_arn) is defined,
    this module will delete the ACM resource with that ARN if it exists in this
    region, and succeed without effect if it doesn't exist.
  - >
    When I(state=absent) and I(domain_name) is defined, this module will delete
    all ACM resources in this AWS region with a corresponding domain name.
    If there are none, it will succeed without effect.
  - >
    When I(state=absent) and I(certificate_arn) is not defined,
    and I(domain_name) is not defined, this module will delete all ACM resources
    in this AWS region with a corresponding I(Name) tag.
    If there are none, it will succeed without effect.
  - >
    Note that this may not work properly with keys of size 4096 bits, due to a
    limitation of the ACM API.
  - Prior to release 5.0.0 this module was called C(community.aws.aws_acm).
    The usage did not change.
options:
  certificate:
    description:
      - The body of the PEM encoded public certificate.
      - Required when I(state) is not C(absent) and the certificate does not exist.
      - >
        If your certificate is in a file,
        use C(lookup('file', 'path/to/cert.pem')).
    type: str
  certificate_arn:
    description:
      - The ARN of a certificate in ACM to modify or delete.
      - >
        If I(state=present), the certificate with the specified ARN can be updated.
        For example, this can be used to add/remove tags to an existing certificate.
      - >
        If I(state=absent), you must provide one of
        I(certificate_arn), I(domain_name) or I(name_tag).
      - >
        If I(state=absent) and no resource exists with this ARN in this region,
        the task will succeed with no effect.
      - >
        If I(state=absent) and the corresponding resource exists in a different
        region, this task may report success without deleting that resource.
    type: str
    aliases: [arn]
  certificate_chain:
    description:
      - The body of the PEM encoded chain for your certificate.
      - >
        If your certificate chain is in a file,
        use C(lookup('file', 'path/to/chain.pem')).
      - Ignored when I(state=absent)
    type: str
  domain_name:
    description:
      - The domain name of the certificate.
      - >
        If I(state=absent) and I(domain_name) is specified,
        this task will delete all ACM certificates with this domain.
      - >
        Exactly one of I(domain_name), I(name_tag) and I(certificate_arn)
        must be provided.
      - >
        If I(state=present) this must not be specified.
        (Since the domain name is encoded within the public certificate's body.)
    type: str
    aliases: [domain]
  name_tag:
    description:
      - >
        The unique identifier for tagging resources using AWS tags,
        with key I(Name).
      - This can be any set of characters accepted by AWS for tag values.
      - >
        This is to ensure Ansible can treat certificates idempotently,
        even though the ACM API allows duplicate certificates.
      - If I(state=preset), this must be specified.
      - >
        If I(state=absent) and I(name_tag) is specified,
        this task will delete all ACM certificates with this Name tag.
      - >
        If I(state=absent), you must provide exactly one of
        I(certificate_arn), I(domain_name) or I(name_tag).
      - >
        If both I(name_tag) and the 'Name' tag in I(tags) are set,
        the values must be the same.
      - >
        If the 'Name' tag in I(tags) is not set and I(name_tag) is set,
        the I(name_tag) value is copied to I(tags).
    type: str
    aliases: [name]
  private_key:
    description:
      - The body of the PEM encoded private key.
      - Required when I(state=present) and the certificate does not exist.
      - Ignored when I(state=absent).
      - >
        If your private key is in a file,
        use C(lookup('file', 'path/to/key.pem')).
    type: str
  state:
    description:
      - >
        If I(state=present), the specified public certificate and private key
        will be uploaded, with I(Name) tag equal to I(name_tag).
      - >
        If I(state=absent), any certificates in this region
        with a corresponding I(domain_name), I(name_tag) or I(certificate_arn)
        will be deleted.
    choices: [present, absent]
    default: present
    type: str

notes:
  - Support for I(tags) and I(purge_tags) was added in release 3.2.0
author:
  - Matthew Davis (@matt-telstra) on behalf of Telstra Corporation Limited
extends_documentation_fragment:
  - amazon.aws.common.modules
  - amazon.aws.region.modules
  - amazon.aws.tags
  - amazon.aws.boto3
a[  

- name: upload a self-signed certificate
  community.aws.acm_certificate:
    certificate: "{{ lookup('file', 'cert.pem' ) }}"
    privateKey: "{{ lookup('file', 'key.pem' ) }}"
    name_tag: my_cert # to be applied through an AWS tag as  "Name":"my_cert"
    region: ap-southeast-2 # AWS region

- name: create/update a certificate with a chain
  community.aws.acm_certificate:
    certificate: "{{ lookup('file', 'cert.pem' ) }}"
    private_key: "{{ lookup('file', 'key.pem' ) }}"
    name_tag: my_cert
    certificate_chain: "{{ lookup('file', 'chain.pem' ) }}"
    state: present
    region: ap-southeast-2
  register: cert_create

- name: print ARN of cert we just created
  ansible.builtin.debug:
    var: cert_create.certificate.arn

- name: delete the cert we just created
  community.aws.acm_certificate:
    name_tag: my_cert
    state: absent
    region: ap-southeast-2

- name: delete a certificate with a particular ARN
  community.aws.acm_certificate:
    certificate_arn: "arn:aws:acm:ap-southeast-2:123456789012:certificate/01234567-abcd-abcd-abcd-012345678901"
    state: absent
    region: ap-southeast-2

- name: delete all certificates with a particular domain name
  community.aws.acm_certificate:
    domain_name: acm.ansible.com
    state: absent
    region: ap-southeast-2

- name: add tags to an existing certificate with a particular ARN
  community.aws.acm_certificate:
    certificate_arn: "arn:aws:acm:ap-southeast-2:123456789012:certificate/01234567-abcd-abcd-abcd-012345678901"
    tags:
      Name: my_certificate
      Application: search
      Environment: development
    purge_tags: true
a/  
certificate:
  description: Information about the certificate which was uploaded
  type: complex
  returned: when I(state=present)
  contains:
    arn:
      description: The ARN of the certificate in ACM
      type: str
      returned: when I(state=present) and not in check mode
      sample: "arn:aws:acm:ap-southeast-2:123456789012:certificate/01234567-abcd-abcd-abcd-012345678901"
    domain_name:
      description: The domain name encoded within the public certificate
      type: str
      returned: when I(state=present)
      sample: acm.ansible.com
arns:
  description: A list of the ARNs of the certificates in ACM which were deleted
  type: list
  elements: str
  returned: when I(state=absent)
  sample:
   - "arn:aws:acm:ap-southeast-2:123456789012:certificate/01234567-abcd-abcd-abcd-012345678901"
    N)deepcopy)to_text)ACMServiceManager)ansible_dict_to_boto3_tag_list)boto3_tag_list_to_ansible_dict)compare_aws_tags)AnsibleCommunityAWSModulec                     |d|fS t        |||      \  }}t        |xs |      }|r)|j                  s	 | j                  |t	        |             |rA|j                  s5|D 
cg c]  }
|
|j                  |
      d }}
	 | j                  ||       t        |      }|j                         D ]
  \  }
}|||
<    |D ]  }
|j                  |
d         ||fS # t
        j                  j                  t
        j                  j                  f$ r}	|j                  |	d|        Y d }	~	d }	~	ww xY wc c}
w # t
        j                  j                  t
        j                  j                  f$ r}	|j                  |	d|        Y d }	~	d }	~	ww xY w)NF)CertificateArnTagsz!Couldn't add tags to certificate )KeyValuez&Couldn't remove tags from certificate )r   bool
check_modeadd_tags_to_certificater   botocore
exceptionsClientErrorBotoCoreErrorfail_json_awsgetremove_tags_from_certificater   itemspop)clientmoduleresource_arnexisting_tagstags
purge_tagstags_to_addtags_to_removechangedekey	tags_listnew_tagsvalues                 q/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/aws/plugins/modules/acm_certificate.pyensure_tagsr*     s   |}%%"2=$
"SK;0.1G6,,		X**+3K@ +  f//N\]sS=+<+<S+AB]	]		]//+ 0  &H!'') 
U  S$ X- ++--
 	X   &G~$VWW		X ^ ++--
 	]   &L\N$[\\		]s5   C #D2D7 7D/D**D/77F.FFc                     t        | |      }t        | |      }t        |      t        |      k7  ryt        ||      D ]$  \  }}t        | |      }t        | |      }||k7  s$ y y)NFT)pem_chain_splitlenzipPEM_body_to_DER)	r   abchain_a_pemchain_b_pemcacbder_ader_bs	            r)   chain_comparer8   2  sr    !&!,K!&!,K
;3{++ k;/ B++E>	     c                     	 t        j                  t        |            }|S # t        t        f$ r}| j                  |d       Y d }~S d }~ww xY w)Nz"Unable to decode certificate chainmsg)base64	b64decoder   
ValueError	TypeErrorr   )r   pemderr$   s       r)   r/   r/   E  sX    Jws|, J 	" JQ$HIIJJs   " AA

Azg------?BEGIN [A-Z0-9. ]*CERTIFICATE------?([a-zA-Z0-9\+\/=\s]+)------?END [A-Z0-9. ]*CERTIFICATE------?c                     t        j                  t        t        |            }t	        |      dk(  r| j                  d       |S )Nr   z>Unable to split certificate chain. Possibly zero-length chain?r;   )refindallpem_chain_split_regexr   r-   	fail_json)r   rA   pem_arrs      r)   r,   r,   W  s:    jj.=G
7|q]^Nr9   c           	         |j                  d       d|vsd|d   vr|j                  d|       |j                  j                  d      7|d   d   |j                  j                  d      k7  r|j                  d|       d	|vr|j                  d
|       d}d}|j                  j                  d	      p|t	        ||d	   |j                  d	         z  }|j                  d   r!|t	        ||d   |j                  d         z  }n |t	        ||d   |j                  d	         z  }|r|j                  d       |d   }d}||fS g d}t        |D 	cg c]  }	|j                  |	   du c}	      dk  r|j                  d       |j                  d       d}|j                  r	|d   }||fS |j                  | ||j                  d	   |j                  d   |j                  d   |d   |      }||fS c c}	w )zN
    Update the existing certificate that was previously imported in ACM.
    z!Existing certificate found in ACMr   Namez2Internal error, unsure which certificate to update)r<   certificatename_tagNz'Internal error, Name tag does not matchrK   z7Internal error, unsure what the existing cert in ACM isTcertificate_chainz'Existing certificate in ACM is the samecertificate_arnFrK   rL   private_key   zbWhen importing a certificate, all of 'name_tag', 'certificate' and 'private_key' must be specifiedr;   z5Existing certificate in ACM is different, overwritingrP   )rK   rP   rM   arnr   )debugrG   paramsr   r8   sumr   import_certificate)
r   r   acmold_certdesired_tagscert_arnsamer#   absent_argsr0   s
             r)   update_imported_certificater]   a  sE    LL45hF(62B$BQ_gh}}$0hv6Fv6NRXR_R_RcRcdnRo6o 	FT\]H$VdlmHD}}'3fh}&=v}}]?[\\==,- M&(3F*GWjIkllD M&(3F*GWdIeffD>?-.. X+ AD1q!-DEIx   	LM 12H X --"MM-8"MM-8"(--0C"D./! . H X) Es   G5c                    g d}d}t        |D cg c]  }|j                  |   du c}      dk  r|j                  d       |j                  d       d}|j                  r#d}|j                  t        |	      d
       ||fS |j                  | ||j                  d   |j                  d   |j                  d   |      }||fS c c}w )z&
    Import a certificate to ACM.
    rO   NrQ   zfWhen importing a new certificate, all of 'name_tag', 'certificate' and 'private_key' must be specifiedr;   z(No certificate in ACM. Creating new one.Tzexample.com)domain_namerK   r#   rK   rP   rM   )rK   rP   rM   r   )rU   rT   rG   rS   r   	exit_jsondictrV   )	r   r   rW   rY   r\   rZ   r0   r#   domains	            r)   rV   rV     s    
 =KH
K@qV]]1T)@AAEx 	 	
 LL;<GTf%=tL X ))m4m4$mm,?@ * 
 X% As   Cc                    d }d}t        |      dkD  r'd|j                  d    d}|j                  ||       n5t        |      dk(  rt        | |||d   |      \  }}nt	        | |||      \  }}	 t        | j                  |      d	         }	|j                  j                  d      }t        | ||	||      \  }}||z  }|j                  | ||      }|j                  t!        |||      |       y # t        j                  j                  t        j                  j                  f$ r}
|j                  |
d
       Y d }
~
d }
~
ww xY w)NF   z$More than one certificate with Name=rL   z exists in ACM in this region)r<   certificatesr   )r   r   z!Couldn't get tags for certificater    )r   r   rR   )r_   rR   r   r`   )r-   rT   rG   r]   rV   r   list_tags_for_certificater   r   r   r   r   r   r*   get_domain_of_certra   rb   )r   r   rW   rf   rY   filter_tagsrZ   r#   r<   r   r$   r    cr'   rc   s                  r)   ensure_certificates_presentrk     s]   HG
<14V]]:5N4OOlmS|<	\	a	9&&#|\]`lm( 1lS(E6,,H,EfM
 ""<0J-WabMQqLG##6&h#OF
&hX!V`gh ++X-@-@-N-NO EQ CDDEs   0C5 57E,EEc                     |D ]%  }|j                   r|j                  | ||d          ' |j                  |D cg c]  }|d   	 c}t        |      dkD         y c c}w )NrN   r   )arnsr#   )r   delete_certificatera   r-   )r   r   rW   rf   certs        r)   ensure_certificates_absentrp     sj     L  ""6648I3JKL |Lt4 12LWZ[gWhklWlnLs   Ac                     t        t               t        dg      t               t        dg      t        dg      t        d      t        ddg	      t        d
d      t        dddg      	      } t        | d      }t        |      }|j                  d   dk(  rlg d}t	        |D cg c]  }|j                  |   d u c}      dk  r|D ]%  }|j                  | d|j                  |           ' |j                  d       nkg d}t	        |D cg c]  }|j                  |   d u c}      dk7  r<|D ]%  }|j                  | d|j                  |           ' |j                  d       d }d }|j                  j                  d      |j                  d   }nd|j                  d<   |j                  j                  d      et        |j                  d         }|?d|v r(|d   |j                  d   k7  r1|j                  d       n|j                  d   |d<   nt        |      }|j                  d      }|j                  |||j                  d    |j                  d!   |"      }|j                  d#t        |       d$       |j                  d   dk(  rt        ||||||       y t        ||||       y c c}w c c}w )%NrR   )aliasesrc   nameT)no_logrb   resource_tags)typerr   r   )rv   defaultpresentabsent)rw   choices)	rK   rN   rM   r_   rL   rP   r   r    state)argument_specsupports_check_moder{   )rN   r_   rL   re   z is zzIf 'state' is specified as 'present' then at least one of 'name_tag', 'certificate_arn' or 'domain_name' must be specifiedr;   zxIf 'state' is specified as 'absent' then exactly one of 'name_tag', 'certificate_arn' or 'domain_name' must be specifiedr   Fr    rL   )rJ   rJ   z7Value of 'name_tag' conflicts with value of 'tags.Name'rW   r_   rN   )r   r   r_   rR   	only_tagszFound z" corresponding certificates in ACM)rb   AnsibleAWSModuler   rT   rU   rS   rG   r   r   r   get_certificatesr-   rk   rp   )	r|   r   rW   r\   r0   ri   rY   r   rf   s	            r)   mainr     s   FeW-&(,vh'%v'89VT29y(.CD
M # F F
#C }}W*DD1q!-DEI  ;s$v}}Q'7&89:; Q  
 ED1q!-DEJ  ;s$v}}Q'7&89:; O   KL}} ,}}V, ',l#}}$0
 j 9:#%'6==+DD$$)b$c'-}}Z'@V$#K0L]]5!F ''MM-0MM+, ( L LL6#l+,,NOP}}W*#FFC|U`a 	#663Em E Es   +KK	__main__) DOCUMENTATIONEXAMPLESRETURNr=   rD   copyr   r   ImportErroransible.module_utils._textr   7ansible_collections.amazon.aws.plugins.module_utils.acmr   ;ansible_collections.amazon.aws.plugins.module_utils.taggingr   r   r   >ansible_collections.community.aws.plugins.module_utils.modulesr	   r   r*   r8   r/   compilerF   r,   r]   rV   rk   rp   r   __name__ r9   r)   <module>r      s   Zx1f
4  	 	 / U f f X x#V& #

n 8v8i8oLF^ zF a	  		s   A9 9B B