# Path: awslimitchecker/connectable.py
# class Connectable(object):
#     """
#     Mix-in helper class for connecting to AWS APIs. Centralizes logic of
#     connecting via regions and/or STS.
#     """
# 
#     @property
#     def _max_retries_config(self):
#         """
#         If a ``BOTO_MAX_RETRIES_<self.api_name>`` environment variable is set,
#         return a new ``botocore.config.Config`` instance using that number
#         as the retries max_attempts value.
# 
#         :rtype: ``botocore.config.Config`` or None
#         """
#         key = 'BOTO_MAX_RETRIES_%s' % self.api_name
#         if key not in os.environ:
#             return None
#         try:
#             max_retries = int(os.environ[key])
#         except Exception:
#             logger.error(
#                 'ERROR: Found "%s" environment variable, but unable to '
#                 'parse value "%s" to an integer.', key, os.environ[key]
#             )
#             return None
#         logger.debug(
#             'Setting explicit botocore retry config with max_attempts=%d '
#             'for "%s" API based on %s environment variable.',
#             max_retries, self.api_name, key
#         )
#         return Config(retries={'max_attempts': max_retries})
# 
#     def connect(self):
#         """
#         Connect to an AWS API via boto3 low-level client and set ``self.conn``
#         to the `boto3.client <https://boto3.readthed
#         ocs.org/en/latest/reference/core/boto3.html#boto3.client>`_ object
#         (a ``botocore.client.*`` instance). If ``self.conn`` is not None,
#         do nothing. This connects to the API name given by ``self.api_name``.
# 
#         :returns: None
#         """
#         if self.conn is not None:
#             return
# 
#         default_config = Config(retries={'mode': 'adaptive'})
#         kwargs = dict(self._boto3_connection_kwargs)
#         kwargs['config'] = default_config
# 
#         if self._max_retries_config is not None:
#             kwargs['config'] = default_config.merge(self._max_retries_config)
#         self.conn = boto3.client(self.api_name, **kwargs)
#         logger.info("Connected to %s in region %s",
#                     self.api_name, self.conn._client_config.region_name)
# 
#     def connect_resource(self):
#         """
#         Connect to an AWS API via boto3 high-level resource connection and set
#         ``self.resource_conn`` to the `boto3.resource <https://boto3.readthed
#         ocs.org/en/latest/reference/core/boto3.html#boto3.resource>`_ object
#         (a ``boto3.resources.factory.*.ServiceResource`` instance).
#         If ``self.resource_conn`` is not None,
#         do nothing. This connects to the API name given by ``self.api_name``.
# 
#         :returns: None
#         """
#         if self.resource_conn is not None:
#             return
# 
#         default_config = Config(retries={'mode': 'adaptive'})
#         kwargs = dict(self._boto3_connection_kwargs)
#         kwargs['config'] = default_config
# 
#         if self._max_retries_config is not None:
#             kwargs['config'] = default_config.merge(self._max_retries_config)
# 
#         self.resource_conn = boto3.resource(self.api_name, **kwargs)
#         logger.info("Connected to %s (resource) in region %s", self.api_name,
#                     self.resource_conn.meta.client._client_config.region_name)
# 
# class ConnectableCredentials(object):
#     """
#     boto's (2.x) :py:meth:`boto.sts.STSConnection.assume_role` returns a
#     :py:class:`boto.sts.credentials.Credentials` object, but boto3's
#     `boto3.sts.STSConnection.assume_role <https://boto3.readthedocs.org/en/
#     latest/reference/services/sts.html#STS.Client.assume_role>`_ just returns
#     a dict. This class provides a compatible interface for boto3.
# 
#     We also maintain an ``account_id`` attribute that can be set to the
#     account ID, to ensure that credentials are updated when switching accounts.
#     """
# 
#     def __init__(self, creds_dict):
#         self.access_key = creds_dict['Credentials']['AccessKeyId']
#         self.secret_key = creds_dict['Credentials']['SecretAccessKey']
#         self.session_token = creds_dict['Credentials']['SessionToken']
#         self.expiration = creds_dict['Credentials']['Expiration']
#         self.assumed_role_id = creds_dict['AssumedRoleUser']['AssumedRoleId']
#         self.assumed_role_arn = creds_dict['AssumedRoleUser']['Arn']
#         self.account_id = None


from awslimitchecker.connectable import Connectable, ConnectableCredentials
from datetime import datetime
    from mock import patch, call, Mock, PropertyMock
    from unittest.mock import patch, call, Mock, PropertyMock
import sys
import os

The Copyright and Authors attributions contained herein may not be removed or
otherwise altered, except to add the Author attribution of a contributor to
this work. (Additional Terms pursuant to Section 7b of the AGPL v3)
################################################################################
While not legally required, I sincerely request that anyone who finds
bugs please submit them at <https://github.com/jantman/awslimitchecker> or
to me via email, and that you send any contributions or improvements
either as a pull request on GitHub, or to me via email.
################################################################################

AUTHORS:
Jason Antman <jason@jasonantman.com> <http://www.jasonantman.com>
################################################################################
"""


# https://code.google.com/p/mock/issues/detail?id=249
# py>=3.4 should use unittest.mock not the mock package on pypi
if (
        sys.version_info[0] < 3 or
        sys.version_info[0] == 3 and sys.version_info[1] < 4
):
else:


pbm = 'awslimitchecker.connectable'
pb = '%s.Connectable' % pbm



# Path: awslimitchecker/connectable.py
# class Connectable(object):
#     """
#     Mix-in helper class for connecting to AWS APIs. Centralizes logic of
#     connecting via regions and/or STS.
#     """
# 
#     @property
#     def _max_retries_config(self):
#         """
#         If a ``BOTO_MAX_RETRIES_<self.api_name>`` environment variable is set,
#         return a new ``botocore.config.Config`` instance using that number
#         as the retries max_attempts value.
# 
#         :rtype: ``botocore.config.Config`` or None
#         """
#         key = 'BOTO_MAX_RETRIES_%s' % self.api_name
#         if key not in os.environ:
#             return None
#         try:
#             max_retries = int(os.environ[key])
#         except Exception:
#             logger.error(
#                 'ERROR: Found "%s" environment variable, but unable to '
#                 'parse value "%s" to an integer.', key, os.environ[key]
#             )
#             return None
#         logger.debug(
#             'Setting explicit botocore retry config with max_attempts=%d '
#             'for "%s" API based on %s environment variable.',
#             max_retries, self.api_name, key
#         )
#         return Config(retries={'max_attempts': max_retries})
# 
#     def connect(self):
#         """
#         Connect to an AWS API via boto3 low-level client and set ``self.conn``
#         to the `boto3.client <https://boto3.readthed
#         ocs.org/en/latest/reference/core/boto3.html#boto3.client>`_ object
#         (a ``botocore.client.*`` instance). If ``self.conn`` is not None,
#         do nothing. This connects to the API name given by ``self.api_name``.
# 
#         :returns: None
#         """
#         if self.conn is not None:
#             return
# 
#         default_config = Config(retries={'mode': 'adaptive'})
#         kwargs = dict(self._boto3_connection_kwargs)
#         kwargs['config'] = default_config
# 
#         if self._max_retries_config is not None:
#             kwargs['config'] = default_config.merge(self._max_retries_config)
#         self.conn = boto3.client(self.api_name, **kwargs)
#         logger.info("Connected to %s in region %s",
#                     self.api_name, self.conn._client_config.region_name)
# 
#     def connect_resource(self):
#         """
#         Connect to an AWS API via boto3 high-level resource connection and set
#         ``self.resource_conn`` to the `boto3.resource <https://boto3.readthed
#         ocs.org/en/latest/reference/core/boto3.html#boto3.resource>`_ object
#         (a ``boto3.resources.factory.*.ServiceResource`` instance).
#         If ``self.resource_conn`` is not None,
#         do nothing. This connects to the API name given by ``self.api_name``.
# 
#         :returns: None
#         """
#         if self.resource_conn is not None:
#             return
# 
#         default_config = Config(retries={'mode': 'adaptive'})
#         kwargs = dict(self._boto3_connection_kwargs)
#         kwargs['config'] = default_config
# 
#         if self._max_retries_config is not None:
#             kwargs['config'] = default_config.merge(self._max_retries_config)
# 
#         self.resource_conn = boto3.resource(self.api_name, **kwargs)
#         logger.info("Connected to %s (resource) in region %s", self.api_name,
#                     self.resource_conn.meta.client._client_config.region_name)
# 
# class ConnectableCredentials(object):
#     """
#     boto's (2.x) :py:meth:`boto.sts.STSConnection.assume_role` returns a
#     :py:class:`boto.sts.credentials.Credentials` object, but boto3's
#     `boto3.sts.STSConnection.assume_role <https://boto3.readthedocs.org/en/
#     latest/reference/services/sts.html#STS.Client.assume_role>`_ just returns
#     a dict. This class provides a compatible interface for boto3.
# 
#     We also maintain an ``account_id`` attribute that can be set to the
#     account ID, to ensure that credentials are updated when switching accounts.
#     """
# 
#     def __init__(self, creds_dict):
#         self.access_key = creds_dict['Credentials']['AccessKeyId']
#         self.secret_key = creds_dict['Credentials']['SecretAccessKey']
#         self.session_token = creds_dict['Credentials']['SessionToken']
#         self.expiration = creds_dict['Credentials']['Expiration']
#         self.assumed_role_id = creds_dict['AssumedRoleUser']['AssumedRoleId']
#         self.assumed_role_arn = creds_dict['AssumedRoleUser']['Arn']
#         self.account_id = None


# Path: awslimitchecker/tests/test_connectable.py
from awslimitchecker.connectable import Connectable, ConnectableCredentials
from datetime import datetime
    from mock import patch, call, Mock, PropertyMock
    from unittest.mock import patch, call, Mock, PropertyMock
import sys
import os


The Copyright and Authors attributions contained herein may not be removed or
otherwise altered, except to add the Author attribution of a contributor to
this work. (Additional Terms pursuant to Section 7b of the AGPL v3)
################################################################################
While not legally required, I sincerely request that anyone who finds
bugs please submit them at <https://github.com/jantman/awslimitchecker> or
to me via email, and that you send any contributions or improvements
either as a pull request on GitHub, or to me via email.
################################################################################

AUTHORS:
Jason Antman <jason@jasonantman.com> <http://www.jasonantman.com>
################################################################################
"""


# https://code.google.com/p/mock/issues/detail?id=249
# py>=3.4 should use unittest.mock not the mock package on pypi
if (
        sys.version_info[0] < 3 or
        sys.version_info[0] == 3 and sys.version_info[1] < 4
):
else:


pbm = 'awslimitchecker.connectable'
pb = '%s.Connectable' % pbm



class ConnectableTester(Connectable):