3 =\G8@sdddlmZddlZddlZddlZddlZddlmZddlm Z ddl m Z Gddde Z dS))print_functionN)Lock)sleep)TaskCatExceptionc@sleZdZdZdddddddifddZddZddd Zdd d ZdddZdddZ ddZ dddZ dS) ClientFactoryaManages creating and caching boto3 clients, helpful when creating lots of clients in different regions or functions. Example usage: from tackcat import utils class MyClass(object): def __init__(self): self._boto_client = utils.ClientFactory() def my_function(self): s3_client = self._boto_client.get('s3', region='us-west-2') return s3_client.list_buckets() Nerrorc Csdii|_i|_t|_|stt|jd}tt|jd}tj} | j|tjdj|tjdj|tjdj|tjdj|t | j dkr| j tj | |_ n||_ |jd||||x"|jD]\} } |j| f| qWd S) asSets up the cache dict, a locking mechanism and the logging object Args: logger (obj): a logging instance loglevel (str): [optional] log verbosity, defaults to 'error' botolevel (str): [optional] boto3 log verbosity, defaults to 'error' aws_access_key_id (str): [optional] IAM access key, defaults to None aws_secret_access_key (str): [optional] IAM secret key, defaults to None aws_session_token (str): [optional] IAM session token, defaults to None profile_name (str): [optional] credential profile to use, defaults to None default(boto3botocoreZnoseZ s3transferrN)_clients_credential_setsr_lockgetattrloggingupper getLoggersetLevellenhandlers addHandler StreamHandlerloggerput_credential_setitems) selfrZloglevelZ botolevelaws_access_key_idaws_secret_access_keyaws_session_token profile_nameZregional_cred_mapZ mainlogger region_nameZcredential_dictr"o/private/var/folders/pf/wv4htv3x0qs2c2mp0dnn0kchsvlck3/T/pip-install-emcbgzcf/taskcat/taskcat/client_factory.py__init__$s(  zClientFactory.__init__cCszyv|r$|r$|r$tjj|||d}n8|r>|r>tjj||d}n|rRtjj|d}n tjj}|j}|sv|jjdd}Wn:tk r}z|jjdt|d}WYdd}~XnXWd|S)zreturns the default region for the credentials provided :param aws_access_key_id: :param aws_secret_access_key: :param aws_session_token: :param profile_name: :return: )rrr)rr)r z;Region not set in credential chain, defaulting to us-east-1z us-east-1z failed to get default region: %sN) r sessionSessionr!rwarning Exceptionrstr)rrrrr r%regioner"r"r#get_default_regionIs&      z ClientFactory.get_default_regioncCsL|r | s| r|rtdn|r6|s.|s.|r6td||||g|j|<dS)aAdds or updates a credential set to be re-used when creating clients aws_access_key_id (str): [optional] IAM access key, defaults to None aws_secret_access_key (str): [optional] IAM secret key, defaults to None aws_session_token (str): [optional] IAM session token, defaults to None profile_name (str): [optional] credential profile to use, defaults to None z@"aws_access_key_id" and "aws_secret_access_key" must both be setz`"profile_name" cannot be used with aws_access_key_id, aws_secret_access_key or aws_session_tokenN) ValueErrorr)rZcredential_set_namerrrr r"r"r#rhs  z ClientFactory.put_credential_setrFc Cs| r^| r^|jjd|||jjkr6td||rL||jjkrL|}|j|\}}}}|sr|j||||}|rzdnd}yf|jjd||||f|j||||} |r|j||djj|kr|jjdtd| Stk r|jjd ||jjkri|j|<||j|jkr>i|j||<||j|jkrdi|j|||<d|j||jkr|j ||||||j||d<|j |||||j||||<|j||||SXd S) a%get a client for a given service and region, optionally with specific role, credentials and/or sig version Args: service (str): service name region (str): [optional] region name, defaults to current region credential_set (str): [optional] name used to seperate different sets of credentials, defaults to "default" which uses either the auto-discovered role, or the credentials configured when this class is instantiated aws_access_key_id (str): [optional] IAM access key, defaults to None aws_secret_access_key (str): [optional] IAM secret key, defaults to None aws_session_token (str): [optional] IAM session token, defaults to None s3v4 (bool): [optional] when True enables signature_version=s3v4 which is required for SSE protected buckets/objects profile_name (str): [optional] credential profile to use, defaults to None Returns: class: boto3 client zUno explicit keys or profile for this client, fetching the credentials from the %s setz credential set %s does not exists3v4Zdefault_sig_versionzTrying to get [%s][%s][%s][%s]r%z&credentials changed, forcing update...z|r>|r>tjj||||d} n@|rZ|rZtjj|||d} n$|rptjj||d} ntjj|d} WdQRX| Stk rYq tk r} zFdt| kr|jjdd d | d 7} | |krt || |WYdd} ~ Xq Xq WdS) azcreates a boto3 session object Args: region (str): region name access_key (str): [optional] IAM secret key, defaults to None secret_key (str): [optional] IAM secret key, defaults to None session_token (str): [optional] IAM secret key, defaults to None profile_name (str): [optional] credential profile to use, defaults to None max_retries (int): [optional] number of retries, defaults to 4 delay (int): [optional] retry delay in seconds, defaults to 5 backoff_factor (int): [optional] retry delay exponent, defaults to 2 Nr)rrrr!)rrr!)r r!)r!zcould not be foundzfailed to create session)exc_info) rr r%r&rr(r)rr/r) rr*r2Z secret_keyZ session_tokenr max_retriesdelaybackoff_factorr%retryr+r"r"r#r3s@      zClientFactory._create_sessionc Csd}d} x|sy^|jN|dkrH|j||dj|tjjddd}n|j||dj|}WdQRX|Stk rYq tk r|jjddd | d7} | |krt || |Yq Xq WdS) a'creates (or fetches from cache) a boto3 client object Args: credential_set (str): session name region (str): region name service (str): AWS service name s3v4 (str): when set to "s3v4" enables signature version 4, required for SSE protected buckets/objects max_retries (int): [optional] number of retries, defaults to 4 delay (int): [optional] retry delay in seconds, defaults to 5 backoff_factor (int): [optional] retry delay exponent, defaults to 2 Nrr.r%)Zsignature_version)configzfailed to create clientr<)r=) rr r7r ZConfigrr(rr/r) rr6r*r5r.r>r?r@r7rAr"r"r#r4s& "zClientFactory._create_clientcCsnxX|jjD]J}xD|j|jD]2}d|j||jkr |j||dj|Sq Wq Wtjj}|j|S)zfetches available regions for a service Args: service (str): AWS service name Returns: list: aws region name strings r%)r r0get_available_regionsr r%r&)rr5r6r*r%r"r"r#rCs   z#ClientFactory.get_available_regionscCs&|s|jdddd}|j||dS)aAfetches existing session for credential set in a region Args: credential_set (str): name of credential set from a previously created client region (str): region name, defaults to current region Returns: boto3.session.Session: instance of boto3 Session object Nr%)r,r )rr6r*r"r"r# get_sessions zClientFactory.get_session)NNNN)NrNNNFN)NNNNr9r:r;)r9r:r;)N) __name__ __module__ __qualname____doc__r$r,rr8r3r4rCrDr"r"r"r#rs #  8 2 "r) __future__rr r ros threadingrtimerZtaskcat.exceptionsrobjectrr"r"r"r# s