<commit_before>"""
.. module: lemur.plugins.lemur_aws.iam
    :platform: Unix
    :synopsis: Contains helper functions for interactive with AWS IAM Apis.
    :copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
    :license: Apache, see LICENSE for more details.
.. moduleauthor:: <NAME> <<EMAIL>>
"""
import botocore

from retrying import retry

from lemur.extensions import metrics
from lemur.plugins.lemur_aws.sts import sts_client


def retry_throttled(exception):
    """
    Determines if this exception is due to throttling
    :param exception:
    :return:
    """
    if isinstance(exception, botocore.exceptions.ClientError):
        if exception.response['Error']['Code'] == 'NoSuchEntity':
            return False

    metrics.send('iam_retry', 'counter', 1)
    return True


def get_name_from_arn(arn):
    """
    Extract the certificate name from an arn.

    :param arn: IAM SSL arn
    :return: name of the certificate as uploaded to AWS
    """
    return arn.split("/", 1)[1]


def create_arn_from_cert(account_number, region, certificate_name):
    """
    Create an ARN from a certificate.
    :param account_number:
    :param region:
    :param certificate_name:
    :return:
    """
    return "arn:aws:iam::{account_number}:server-certificate/{certificate_name}".format(
        account_number=account_number,
        certificate_name=certificate_name)


@sts_client('iam')
@retry(retry_on_exception=retry_throttled, stop_max_attempt_number=7, wait_exponential_multiplier=100)
def upload_cert(name, body, private_key, path, cert_chain=None, **kwargs):
    """
    Upload a certificate to AWS

    :param name:
    :param body:
    :param private_key:
    :param cert_chain:
    :param path:
    :return:
    """
    client = kwargs.pop('client')
    try:
        if cert_chain:
            return client.upload_server_certificate(
                Path=path,
                ServerCertificateName=name,
                CertificateBody=str(body),
                PrivateKey=str(private_key),
                CertificateChain=str(cert_chain)
            )
        else:
            return client.upload_server_certificate(
                Path=path,
                ServerCertificateName=name,
                CertificateBody=str(body),
                PrivateKey=str(private_key)
            )
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] != 'EntityAlreadyExists':
            raise e


@sts_client('iam')
@retry(retry_on_exception=retry_throttled, stop_max_attempt_number=7, wait_exponential_multiplier=100)
def delete_cert(cert_name, **kwargs):
    """
    Delete a certificate from AWS

    :param cert_name:<commit_msg>Fixing an issue with uploading to cloudfront. (#815)<commit_after>"""
.. module: lemur.plugins.lemur_aws.iam
    :platform: Unix
    :synopsis: Contains helper functions for interactive with AWS IAM Apis.
    :copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
    :license: Apache, see LICENSE for more details.
.. moduleauthor:: <NAME> <<EMAIL>>
"""
import botocore

from retrying import retry

from lemur.extensions import metrics
from lemur.plugins.lemur_aws.sts import sts_client


def retry_throttled(exception):
    """
    Determines if this exception is due to throttling
    :param exception:
    :return:
    """
    if isinstance(exception, botocore.exceptions.ClientError):
        if exception.response['Error']['Code'] == 'NoSuchEntity':
            return False

    metrics.send('iam_retry', 'counter', 1)
    return True


def get_name_from_arn(arn):
    """
    Extract the certificate name from an arn.

    :param arn: IAM SSL arn
    :return: name of the certificate as uploaded to AWS
    """
    return arn.split("/", 1)[1]


def create_arn_from_cert(account_number, region, certificate_name):
    """
    Create an ARN from a certificate.
    :param account_number:
    :param region:
    :param certificate_name:
    :return:
    """
    return "arn:aws:iam::{account_number}:server-certificate/{certificate_name}".format(
        account_number=account_number,
        certificate_name=certificate_name)


@sts_client('iam')
@retry(retry_on_exception=retry_throttled, stop_max_attempt_number=7, wait_exponential_multiplier=100)
def upload_cert(name, body, private_key, path, cert_chain=None, **kwargs):
    """
    Upload a certificate to AWS

    :param name:
    :param body:
    :param private_key:
    :param cert_chain:
    :param path:
    :return:
    """
    client = kwargs.pop('client')

    if not path:
        path = '/'
    else:
        name = name + '-' + path.strip('/')

    try:
        if cert_chain:
            return client.upload_server_certificate(
                Path=path,
                ServerCertificateName=name,
                CertificateBody=str(body),
                PrivateKey=str(private_key),
                CertificateChain=str(cert_chain)
            )
        else:
            return client.upload_server_certificate(
                Path=path,
                ServerCertificateName=name,
                CertificateBody=str(body),
                PrivateKey=str(private_key)
            )
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] != 'EntityAlreadyExists':
            raise e


@sts_client('iam')
@retry(retry_on_exception=retry_throttled, stop_max_attempt_number=7, wait_exponential_multiplier=100)
def delete_cert(cert_name, **kwargs):
    """
    Delete a certificate from AWS

    :param cert_name:
{'fraction_non_alphanumeric': 0.10240636873529944, 'fraction_numerical': 0.0059706893432241726, 'mean_word_length': 2.9011997177134794, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '3688274', 'n_tokens_mistral': 1691, 'n_tokens_neox': 1624, 'n_words': 396}