示例#1
0
文件: clidriver.py 项目: aws/aws-cli
def create_clidriver():
    session = botocore.session.Session(EnvironmentVariables)
    _set_user_agent_for_session(session)
    load_plugins(session.full_config.get('plugins', {}),
                 event_hooks=session.get_component('event_emitter'))
    driver = CLIDriver(session=session)
    return driver
def get_session():
    """# Boto3 MFA session magic"""
    working_dir = os.path.join(os.path.expanduser('~'), '.aws/cli/cache')

    session = botocore.session.get_session()
    provider = session.get_component('credential_provider').get_provider('assume-role')
    provider.cache = credentials.JSONFileCache(working_dir)
    return session
示例#3
0
def build_aws_client(*args, **kwargs):
    """Build an AWS client using the awscli credential cache."""

    # Create a session with the credential cache
    session = botocore.session.get_session()
    provider = session.get_component("credential_provider").get_provider(
        "assume-role"
    )
    provider.cache = credentials.JSONFileCache(AWS_CREDENTIAL_CACHE_DIR)

    # Create boto3 client from session
    return boto3.Session(botocore_session=session).client(*args, **kwargs)
示例#4
0
def _shared_example_configs():
    session = botocore.session.Session()
    loader = session.get_component('data_loader')
    services = loader.list_available_services('examples-1')
    for service in services:
        service_model = session.get_service_model(service)
        example_config = loader.load_service_model(service, 'examples-1',
                                                   service_model.api_version)
        examples = example_config.get("examples", {})
        for operation, operation_examples in examples.items():
            for example in operation_examples:
                yield operation, example, service_model
示例#5
0
文件: storage.py 项目: zfil/ssm-diff
 def ssm(self):
     """Lazy loaded to simplify testing"""
     if self._ssm is None:
         cli_cache = os.path.join(os.path.expanduser('~'), '.aws/cli/cache')
         if self.profile:
             session = botocore.session.Session(profile=self.profile)
         else:
             session = botocore.session.get_session()
         session.get_component('credential_provider').get_provider(
             'assume-role').cache = credentials.JSONFileCache(cli_cache)
         self._ssm = boto3.Session(botocore_session=session).client('ssm')
     return self._ssm
    def _create_server_side_completer(self, session=None):
        from awsshell.resource import index
        if session is None:
            session = botocore.session.Session()
        loader = session.get_component('data_loader')
        completions_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'data')
        loader.search_paths.insert(0, completions_path)

        client_creator = index.CachedClientCreator(session)
        describer = index.CompleterDescriberCreator(loader)
        completer = index.ServerSideCompleter(client_creator, describer)
        return completer
def test_lint_shared_example_configs():
    session = botocore.session.Session()
    loader = session.get_component('data_loader')
    services = loader.list_available_services('examples-1')
    for service in services:
        service_model = session.get_service_model(service)
        example_config = loader.load_service_model(
            service, 'examples-1', service_model.api_version
        )
        examples = example_config.get("examples", {})
        for operation, operation_examples in examples.items():
            for example in operation_examples:
                yield _lint_single_example, operation, example, service_model
示例#8
0
    def _create_server_side_completer(self, session=None):
        from awsshell.resource import index
        if session is None:
            session = botocore.session.Session()
        loader = session.get_component('data_loader')
        completions_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            'data')
        loader.search_paths.insert(0, completions_path)

        client_creator = index.CachedClientCreator(session)
        describer = index.CompleterDescriberCreator(loader)
        completer = index.ServerSideCompleter(client_creator, describer)
        return completer
示例#9
0
def _pagination_configs():
    session = botocore.session.get_session()
    loader = session.get_component('data_loader')
    services = loader.list_available_services('paginators-1')
    for service_name in services:
        service_model = session.get_service_model(service_name)
        page_config = loader.load_service_model(service_name,
                                                'paginators-1',
                                                service_model.api_version)
        for op_name, single_config in page_config['pagination'].items():
            yield (
                op_name,
                single_config,
                service_model
            )
示例#10
0
def _waiter_configs():
    session = botocore.session.get_session()
    validator = Draft4Validator(WAITER_SCHEMA)
    for service_name in session.get_available_services():
        client = session.create_client(service_name, 'us-east-1')
        try:
            # We use the loader directly here because we need the entire
            # json document, not just the portions exposed (either
            # internally or externally) by the WaiterModel class.
            loader = session.get_component('data_loader')
            waiter_model = loader.load_service_model(service_name, 'waiters-2')
        except UnknownServiceError:
            # The service doesn't have waiters
            continue
        yield validator, waiter_model, client
def test_lint_pagination_configs():
    session = botocore.session.get_session()
    loader = session.get_component('data_loader')
    services = loader.list_available_services('paginators-1')
    for service_name in services:
        service_model = session.get_service_model(service_name)
        page_config = loader.load_service_model(service_name,
                                                'paginators-1',
                                                service_model.api_version)
        for op_name, single_config in page_config['pagination'].items():
            yield (
                _lint_single_paginator,
                op_name,
                single_config,
                service_model
            )
示例#12
0
def test_lint_waiter_configs():
    session = botocore.session.get_session()
    validator = Draft4Validator(WAITER_SCHEMA)
    for service_name in session.get_available_services():
        client = session.create_client(service_name, 'us-east-1')
        service_model = client.meta.service_model
        try:
            # We use the loader directly here because we need the entire
            # json document, not just the portions exposed (either
            # internally or externally) by the WaiterModel class.
            loader = session.get_component('data_loader')
            waiter_model = loader.load_service_model(
                service_name, 'waiters-2')
        except UnknownServiceError:
            # The service doesn't have waiters
            continue
        yield _validate_schema, validator, waiter_model
        for waiter_name in client.waiter_names:
            yield _lint_single_waiter, client, waiter_name, service_model
示例#13
0
    def _get_session(self, profile=None, region=None):
        if self._sessions.get((profile, region)):
            return self._sessions[(profile, region)]

        # Construct botocore session with cache
        # Setup boto to cache STS tokens for MFA
        # Change the cache path from the default of ~/.aws/boto/cache to the one used by awscli
        session_vars = {}
        if profile:
            session_vars['profile'] = (None, None, profile, None)
        if region and region != 'global':
            session_vars['region'] = (None, None, region, None)

        session = botocore.session.Session(session_vars=session_vars)
        cli_cache = os.path.join(os.path.expanduser('~'), '.aws/cli/cache')
        session.get_component('credential_provider').get_provider(
            'assume-role').cache = credentials.JSONFileCache(cli_cache)

        self._sessions[(profile, region)] = session

        return session
示例#14
0
    def initialize(region='', profile=''):
        from botocore import credentials
        import botocore.session
        import os

        cli_cache = os.path.join(os.path.expanduser('~'), '.aws/cli/cache')

        params = {}
        if profile:
            params['profile'] = profile

        session = botocore.session.Session(**params)
        session.get_component('credential_provider').get_provider('assume-role').cache = credentials.JSONFileCache(
            cli_cache)

        from boto3.session import Session
        params = {}
        if region:
            params['region_name'] = region

        AWS.__session = Session(botocore_session=session, **params)
示例#15
0
文件: get_token.py 项目: aws/aws-cli
    def _get_presigned_url(self, cluster_name, role_arn):
        session = self._session_handler.get_session(
            self._region_name,
            role_arn
        )

        if self._region_name is None:
            self._region_name = session.get_config_variable('region')

        loader = botocore.loaders.create_loader()
        data = loader.load_data("endpoints")
        endpoint_resolver = botocore.regions.EndpointResolver(data)
        endpoint = endpoint_resolver.construct_endpoint(
            AUTH_SERVICE,
            self._region_name
        )
        signer = RequestSigner(
            ServiceId(AUTH_SERVICE),
            self._region_name,
            AUTH_SERVICE,
            AUTH_SIGNING_VERSION,
            session.get_credentials(),
            session.get_component('event_emitter')
        )
        action_params='Action=' + AUTH_COMMAND + '&Version=' + AUTH_API_VERSION
        params = {
            'method': 'GET',
            'url': 'https://' + endpoint["hostname"] + '/?' + action_params,
            'body': {},
            'headers': {CLUSTER_NAME_HEADER: cluster_name},
            'context': {}
        }

        url=signer.generate_presigned_url(
            params,
            region_name=endpoint["credentialScope"]["region"],
            operation_name='',
            expires_in=URL_TIMEOUT
        )
        return url
示例#16
0
# Objective: Wrapper function for boto3 client
#            Allows shared caching between CLI and boto3
#            Enables use of MFA-enforced roles

import os

import boto3
import botocore.session
from botocore import credentials

# By default the cache path is ~/.aws/boto/cache
cli_cache = os.path.join(os.path.expanduser('~'), '.aws/cli/cache')

# Construct botocore session with cache
session = botocore.session.get_session()
session.get_component('credential_provider').get_provider(
    'assume-role').cache = credentials.JSONFileCache(cli_cache)


# Create boto3 client from session
def boto3_client(service_name):
    """
    Set up a boto3 session with custom botocore credential provider.
    Boto3 will read from AWS CLI cache and use any cached STS sessions.
    Enables the use of IAM roles that have been authenticated with MFA via CLI

    :type service_name: string
    :param service_name: A valid boto3 service name (eg. ec2, ssm, sqs)
    :return: Returns an initialized boto3 client for the given service
    """
    return boto3.Session(botocore_session=session).client(service_name)
示例#17
0
def get_aws_credentials(profile_name, duration=None):
    """
    Get AWS Credentials for a given profile

    Why do we get credentials like this and not just create a boto3 session or something? Glad you asked!

    In the real world, people use AWS profiles because they have _lots_ of AWS accounts, so first and foremost,
    aws profiles _must_ be handled easily. But that's not the primary concern here.

    In the real real world, people also use MFA. Why? Well for starters AWS TELLS YOU it's a best practice, and you
    know what, it really is. Why however don't a lot of people use MFA? Well it's because the people building tools
    never treat it seriously and do no testing with MFA. Every AWS tools developer should work with MFA
    set to ON for everything they do, trust me, once you do this, the MFA experience will get fixed real fast.

    So, with all that in mind, what this approach to getting AWS credentials enables is:
    1. Get the MFA process out of the way upfront as the _first_ thing the app prompts you for so you don't have to sit
       around waiting for a prompt
    2. Use the built in ability of Boto3 to cache the MFA credentials so you don't have to go find your token
       every time you run the tool
    3. Support shelling out to AWS aware tools (like the SAM CLI)
    4. Also support using the cached credentials when creating Botocore/Boto3 sessions (you have to pass in the keys vs.
       using a profile_name but that's a small price to pay for awesomeness)

    Args:
        profile_name (str): A AWS profile name, as defined in the users .aws/aws_credentials file
        duration (int): Session duration in seconds, the duration configured in the role policy takes precedence

    Returns:
        (dict):
    """
    if not duration:
        duration = 3600

    # Construct low level botocore session with cache, which allows MFA session reuse
    if profile_name:
        session = botocore.session.Session(profile=profile_name)
        mfa_serial = session.full_config['profiles'][profile_name].get(
            'mfa_serial')
    else:
        session = botocore.session.Session()
        mfa_serial = None

    session.get_component('credential_provider').get_provider('assume-role').cache = \
        botocore.credentials.JSONFileCache()

    # this mfa_serial code is _only_ here to deal with boto profiles that _do not_ assume a role
    # which is required because this PR is still open: https://github.com/boto/botocore/pull/1399
    # otherwise MFA is nicely handled automatically by boto. Sadly, these credentials are not cached
    if mfa_serial and not session.full_config['profiles'][profile_name].get(
            'role_arn'):
        sts = session.create_client('sts')
        mfa_code = input("Enter MFA code for {}: ".format(mfa_serial))
        response = sts.get_session_token(DurationSeconds=duration,
                                         SerialNumber=mfa_serial,
                                         TokenCode=mfa_code)
        credentials = response['Credentials']
        identity = sts.get_caller_identity()
        env_vars = {
            'AWS_ACCESS_KEY_ID': credentials['AccessKeyId'],
            'AWS_SECRET_ACCESS_KEY': credentials['SecretAccessKey'],
            'AWS_SESSION_TOKEN': credentials['SessionToken'],
            'AWS_ACCOUNT_ID': identity.get('Account')
        }
        print('.')
    else:
        credentials = session.get_credentials()
        sts = session.create_client('sts')
        identity = sts.get_caller_identity()
        env_vars = {
            'AWS_ACCESS_KEY_ID': credentials.access_key,
            'AWS_SECRET_ACCESS_KEY': credentials.secret_key,
            'AWS_SESSION_TOKEN': credentials.token,
            'AWS_ACCOUNT_ID': identity.get('Account')
        }
    return env_vars
def session():
    session = botocore.session.get_session()
    cred_chain = session.get_component('credential_provider')
    provider = cred_chain.get_provider('assume-role')
    provider.cache = JSONFileCache()
    return session
示例#19
0
import os
import sys
import json
import botocore.session
import botocore.credentials

session = botocore.session.get_session()

if hasattr(botocore.credentials, 'JSONFileCache'):
    cli_cache = os.path.join(os.path.expanduser('~'), '.aws/cli/cache')
    try:
        session.get_component('credential_provider').get_provider('assume-role').cache = botocore.credentials.JSONFileCache(cli_cache)
    except botocore.exceptions.ProfileNotFound as e:
        sys.exit(e)
else:
    # workaround old awscli without https://github.com/boto/botocore/pull/1157
    from awscli.customizations.assumerole import inject_assume_role_provider_cache
    from awscli.customizations.scalarparse import add_scalar_parsers
    inject_assume_role_provider_cache(session)
    add_scalar_parsers(session)

try:
    credentials = session.get_credentials()
    if credentials is None:
        sys.exit('Unable to locate AWS credentials.')
    frozen_credentials = credentials.get_frozen_credentials()
except KeyboardInterrupt as e:
    sys.exit(e)
except botocore.exceptions.ParamValidationError as e:
    sys.exit(e)
except botocore.exceptions.ProfileNotFound as e:
示例#20
0
def configure_cache(session):
    """ Injects caching to the session's credential provider """
    cred_chain = session.get_component('credential_provider')
    provider = cred_chain.get_provider('assume-role')
    provider.cache = FixedJSONFileCache()
示例#21
0
  def from_url(remote_url):
    """
    Parses repository information from a git url, filling in additional
    attributes we need from our AWS profile.

    Our remote helper accepts two distinct types of urls...

    * codecommit://<profile>@<repository>
    * codecommit::<region>://<profile>@<repository>

    If provided the former we get the whole url, but if the later git will
    truncate the proceeding 'codecommit::' prefix for us.

    The '<profile>@' url is optional, using the aws sessions present profile
    if not provided.

    :param str remote_url: git remote url to parse

    :returns: **Context** with our CodeCommit repository information

    :raises:
      * **FormatError** if the url is malformed
      * **ProfileNotFound** if the url references a profile that doesn't exist
      * **RegionNotFound** if the url references a region that doesn't exist
      * **RegionNotAvailable** if the url references a region that is not available
    """

    url = urlparse(remote_url)
    event_handler = botocore.hooks.HierarchicalEmitter()
    profile = 'default'
    repository = url.netloc
    if not url.scheme or not url.netloc:
      raise FormatError('The following URL is malformed: {}. A URL must be in one of the two following formats: codecommit://<profile>@<repository> or codecommit::<region>://<profile>@<repository>'.format(remote_url))

    if '@' in url.netloc:
      profile, repository = url.netloc.split('@', 1)
      session = botocore.session.Session(profile = profile, event_hooks = event_handler)

      if profile not in session.available_profiles:
        raise ProfileNotFound('The following profile was not found: {}. Available profiles are: {}. Either use one of the available profiles, or create an AWS CLI profile to use and then try again. For more information, see Configure an AWS CLI Profile in the AWS CLI User Guide.'.format(profile, ', '.join(session.available_profiles)))
    else:
      session = botocore.session.Session(event_hooks = event_handler)

    session.get_component('credential_provider').get_provider('assume-role').cache = JSONFileCache()

    try:
      # when the aws cli is available support plugin authentication

      import awscli.plugin

      awscli.plugin.load_plugins(
          session.full_config.get('plugins', {}),
          event_hooks = event_handler,
          include_builtins = False,
      )

      session.emit_first_non_none_response('session-initialized', session = session)
    except ImportError:
      pass

    available_regions = [region for partition in session.get_available_partitions() for region in session.get_available_regions('codecommit', partition)]

    if url.scheme == 'codecommit':
      region = session.get_config_variable('region')

      if not region:
        raise RegionNotFound('The following profile does not have an AWS Region: {}. You must set an AWS Region for this profile. For more information, see Configure An AWS CLI Profile in the AWS CLI User Guide.'.format(profile))

      if region not in available_regions:
        raise RegionNotAvailable('The following AWS Region is not available for use with AWS CodeCommit: {}. For more information about CodeCommit\'s availability in AWS Regions, see the AWS CodeCommit User Guide. If an AWS Region is listed as supported but you receive this error, try updating your version of the AWS CLI or the AWS SDKs.'.format(region))

    elif re.match(r"^[a-z]{2}-\w*.*-\d{1}", url.scheme):
      if url.scheme in available_regions:
        region = url.scheme

      else:
        raise RegionNotAvailable('The following AWS Region is not available for use with AWS CodeCommit: {}. For more information about CodeCommit\'s availability in AWS Regions, see the AWS CodeCommit User Guide. If an AWS Region is listed as supported but you receive this error, try updating your version of the AWS CLI or the AWS SDKs.'.format(url.scheme))

    else:
      raise FormatError('The following URL is malformed: {}. A URL must be in one of the two following formats: codecommit://<profile>@<repository> or codecommit::<region>://<profile>@<repository>'.format(remote_url))
    credentials = session.get_credentials()

    if not credentials:
      raise CredentialsNotFound('The following profile does not have credentials configured: {}. You must configure the access key and secret key for the profile. For more information, see Configure an AWS CLI Profile in the AWS CLI User Guide.'.format(profile))

    return Context(session, repository, 'v1', region, credentials)
示例#22
0
    def __init__(self,
                 session=None,
                 region_name=None,
                 api_version=None,
                 use_ssl=None,
                 verify=None,
                 endpoint_url=None,
                 aws_access_key_id=None,
                 aws_secret_access_key=None,
                 aws_session_token=None,
                 config=None,
                 endpoints=None):
        if session is None:
            session = botocore.session.get_session()
        else:
            if not isinstance(session, botocore.session.Session):
                try:
                    # Check for a boto3 session-ish object and get the internal botocore session
                    _session = session._session
                except AttributeError:
                    raise ValueError(
                        'session must be a botocore or boto3 session')
                else:
                    session = _session

        if use_ssl:
            raise ValueError('SSL/TLS is not supported. Set use_ssl=False.')

        self._session = session
        default_client_config = self._session.get_default_client_config()
        if config is not None and default_client_config is not None:
            # If a config is provided and a default config is set, then
            # use the config resulting from merging the two.
            config = default_client_config.merge(config)
        elif default_client_config is not None:
            # If a config was not provided then use the default
            # client config from the session
            config = default_client_config
        self._client_config = config if config is not None else Config(
            region_name=region_name)

        # resolve the region name
        if region_name is None:
            if config and config.region_name:
                region_name = config.region_name
            else:
                region_name = self._session.get_config_variable('region')
        self._region_name = region_name

        # Figure out the verify value base on the various
        # configuration options.
        if verify is None:
            verify = self._session.get_config_variable('ca_bundle')
        self._verify = verify

        # Gather endpoints
        self._endpoints = endpoints or []
        if endpoint_url and endpoint_url not in self._endpoints:
            # If endpoint_url is provided, include it
            self._endpoints.insert(0, endpoint_url)

        if not self._endpoints:
            raise ValueError('No endpoints provided')

        # Resolve credentials
        if aws_access_key_id is not None and aws_secret_access_key is not None:
            self._credentials = Credentials(aws_access_key_id,
                                            aws_secret_access_key,
                                            aws_session_token)
        elif self._session._missing_cred_vars(aws_access_key_id,
                                              aws_secret_access_key):
            raise PartialCredentialsError(
                provider='explicit',
                cred_var=self._session._missing_cred_vars(
                    aws_access_key_id, aws_secret_access_key))
        else:
            self._credentials = self._session.get_credentials()

        # Fake out the meta information as much as possible
        loader = session.get_component('data_loader')
        json_model = loader.load_service_model('dynamodb',
                                               'service-2',
                                               api_version=api_version)
        service_model = ServiceModel(json_model, service_name='dynamodb')
        event_emitter = session.get_component('event_emitter')
        partition = None
        self.meta = ClientMeta(event_emitter, self._client_config,
                               self._endpoints[0], service_model,
                               self._PY_TO_OP_NAME, partition)

        # Check signing version
        if self._client_config.signature_version and self._client_config.signature_version != 'v4':
            logger.warning(
                'DAX only supports SigV4 signing; given signature_version "%s" ignored.',
                self._client_config.signature_version)

        # Start cluster connection & background tasks
        self._cluster = Cluster(self._region_name, self._endpoints,
                                self._credentials,
                                self._client_config.user_agent,
                                self._client_config.user_agent_extra,
                                self._client_config.connect_timeout,
                                self._client_config.read_timeout)
        self._cluster.start()
示例#23
0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os

from botocore import session
from dateutil import parser

session = session.get_session()

# Provide our own botocore json to override (and increase) various timeouts
session.get_component('data_loader')._search_paths[1:1] = [os.path.join(os.path.dirname(__file__), "data")]

# Force botocore to initialise - this avoids race conditions around
# get_component
session.create_client("ec2", "eu-west-1")


class Session(object):

    def __init__(self, access_key_id, secret_access_key, session_token, expiration, region):
        self.access_key_id = access_key_id
        self.secret_access_key = secret_access_key
        self.session_token = session_token
        self.expiration = expiration
        self.region = region