<commit_before># MIT Licensed, Copyright (c) 2015 <NAME> <<EMAIL>>

import boto3
import hashlib
import logging
import time
from botocore.exceptions import ClientError

import cfn_resource

log = logging.getLogger()
log.setLevel(logging.DEBUG)

acm = boto3.client('acm')

def check_properties(event):
    if event['RequestType'] == 'Delete':
        # don't validate on delete
        return

def check_properties(event):
    properties = event['ResourceProperties']
    for p in ('Domains', ):
        if properties.get(p) is None:
            reason = "ERROR: No property '%s' on event %s" % (p, event)
            log.error(reason)
            return {
                'Status': 'FAILED',
                'Reason': reason,
                'PhysicalResourceId': 'could-not-create',
                'Data': {},
            }

    dom = properties.get('Domains', list)
    log.info("Got domains %s" % dom)

    if not (isinstance(dom, list) and len(dom) >= 1):
        reason = "ERROR: Domains is not a list in event %s" % event
        log.error(reason)
        return {
            'Status': 'FAILED',
            'Reason': reason,
            'PhysicalResourceId': 'could-not-create',
            'Data': {},
        }


handler = cfn_resource.Resource()


@handler.create
def create_cert(event, context):
    props = event['ResourceProperties']
    prop_errors = check_properties(event)
    if prop_errors:
        return prop_errors
    domains = props['Domains']

    # take a hash of the Stack & resource ID to make a request token
    id_token = hashlib.md5('cfn-{StackId}-{LogicalResourceId}'.format(
        **event)).hexdigest()
    kwargs = {
        'DomainName': domains[0],
        # the idempotency token length limit is 31 characters
        'IdempotencyToken': id_token[:30]
    }

    if len(domains) > 1:
        # add alternative names if the user wants more names
        # wildcards are allowed
        kwargs['SubjectAlternativeNames'] = domains[1:]

    if props.get('ValidationDomain'):
        kwargs['DomainValidationOptions'] = {
            'DomainName': domains[0],
            'ValidationDomain': props['ValidationDomain'],
        }

    response = acm.request_certificate(**kwargs)

    return {
        'Status': 'SUCCESS',
        'Reason': 'Cert request created successfully',
        'PhysicalResourceId': response['CertificateArn'],
        'Data': {},
    }


@handler.update
def update_certificate(event, context):
    props = event['ResourceProperties']
    prop_errors = check_properties(event)
    if prop_errors:
        return prop_errors
    domains = props['Domains']
    arn = event['PhysicalResourceId']
    if not arn.startswith('arn:aws:acm:'):
        return create_cert(event, context)

    try:
        cert = acm.describe_certificate(CertificateArn=arn)<commit_msg>Add ability to wait for the cert to be issued before returning SUCCESS<commit_after># MIT Licensed, Copyright (c) 2015 <NAME> <<EMAIL>>

import boto3
import hashlib
import logging
import time
from botocore.exceptions import ClientError

import cfn_resource

log = logging.getLogger()
log.setLevel(logging.DEBUG)

acm = boto3.client('acm')

def await_validation(domain, context):
    # as long as we have at least 10 seconds left
    while context.get_remaining_time_in_millis() > 10000:
        time.sleep(5)
        resp = acm.list_certificates(CertificateStatuses=['ISSUED'])
        if any(cert['DomainName'] == domain for cert in resp['CertificateSummaryList']):
            cert_info = [cert for cert in resp['CertificateSummaryList']
                         if cert['DomainName'] == domain][0]
            log.info("Certificate has been issued for domain %s, ARN: %s" %
                     (domain, cert_info['CertificateArn']))
            return cert_info['CertificateArn']
        log.info("Awaiting cert for domain %s" % domain)

    log.warning("Timed out waiting for cert for domain %s" % domain)

def check_properties(event):
    properties = event['ResourceProperties']
    for p in ('Domains', ):
        if properties.get(p) is None:
            reason = "ERROR: No property '%s' on event %s" % (p, event)
            log.error(reason)
            return {
                'Status': 'FAILED',
                'Reason': reason,
                'PhysicalResourceId': 'could-not-create',
                'Data': {},
            }

    dom = properties.get('Domains', list)
    log.info("Got domains %s" % dom)

    if not (isinstance(dom, list) and len(dom) >= 1):
        reason = "ERROR: Domains is not a list in event %s" % event
        log.error(reason)
        return {
            'Status': 'FAILED',
            'Reason': reason,
            'PhysicalResourceId': 'could-not-create',
            'Data': {},
        }


handler = cfn_resource.Resource()


@handler.create
def create_cert(event, context):
    props = event['ResourceProperties']
    prop_errors = check_properties(event)
    if prop_errors:
        return prop_errors
    domains = props['Domains']

    # take a hash of the Stack & resource ID to make a request token
    id_token = hashlib.md5('cfn-{StackId}-{LogicalResourceId}'.format(
        **event)).hexdigest()
    kwargs = {
        'DomainName': domains[0],
        # the idempotency token length limit is 31 characters
        'IdempotencyToken': id_token[:30]
    }

    if len(domains) > 1:
        # add alternative names if the user wants more names
        # wildcards are allowed
        kwargs['SubjectAlternativeNames'] = domains[1:]

    if props.get('ValidationDomain'):
        kwargs['DomainValidationOptions'] = {
            'DomainName': domains[0],
            'ValidationDomain': props['ValidationDomain'],
        }

    response = acm.request_certificate(**kwargs)
    if props.get('Await', False):
        await_validation(domains[0], context)

    return {
        'Status': 'SUCCESS',
        'Reason': 'Cert request created successfully',
        'PhysicalResourceId': response['CertificateArn'],
        'Data': {},
    }


@handler.update
def update_certificate(event, context):
    props = event['ResourceProperties']
    prop_errors = check_properties(event)
    if prop_errors:
        return prop_errors
    domains = props['Domains']
    arn = event['PhysicalResourceId']
    if not arn.startswith('arn:aws:acm:'):
        return create_cert(event, context)

    try:
        cert = acm.describe_certificate(CertificateArn=arn)
{'fraction_non_alphanumeric': 0.1186994399502178, 'fraction_numerical': 0.006533914125700062, 'mean_word_length': 2.6445578231292517, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '7163651', 'n_tokens_mistral': 1882, 'n_tokens_neox': 1786, 'n_words': 487}