def boto3_session(profile_name=None, config_file=None, credentials_file=None, existing_creds=None): """ returns a boto3 session using cached credentials Allows for sharing credentials from cli commands with boto sessions """ # Construct botocore session with cache session = botocore.session.get_session() if profile_name is not None: session.set_config_variable("profile", profile_name) if config_file is not None: session.set_config_variable("config_file", config_file) if credentials_file is not None: session.set_config_variable("credentials_file", credentials_file) if existing_creds is not None: session.set_credentials( access_key=existing_creds["aws_access_key_id"], secret_key=existing_creds["aws_secret_access_key"], token=existing_creds["aws_session_token"], ) session.get_component("credential_provider").get_provider( "assume-role").cache = credentials.JSONFileCache(cli_cache) return boto3.Session(botocore_session=session)
def _create_aws_session(region_name=None, profile_name=None): logger.debug("Obtaining boto3 session object") kwargs = {} if region_name is not None: kwargs["region_name"] = region_name if profile_name is not None: kwargs["profile_name"] = profile_name # https://github.com/boto/boto3/issues/598 if "AWS_ACCESS_KEY_ID" in os.environ: kwargs["aws_access_key_id"] = os.environ["AWS_ACCESS_KEY_ID"] if "AWS_SECRET_ACCESS_KEY" in os.environ: kwargs["aws_secret_access_key"] = os.environ["AWS_SECRET_ACCESS_KEY"] if "AWS_SESSION_TOKEN" in os.environ: kwargs["aws_session_token"] = os.environ["AWS_SESSION_TOKEN"] # By default the cache path is ~/.aws/boto/cache cli_cache = os.path.join(os.path.expanduser("~"), ".aws/cli/cache") session = boto3.session.Session(**kwargs) # Add aws-gate version to the client user-agent # pylint: disable=protected-access session._session.user_agent_extra += " " + "aws-gate/{}".format(__version__) session._session.get_component("credential_provider").get_provider( "assume-role" ).cache = credentials.JSONFileCache(cli_cache) return session
def get_credentials(profile: str = "default", environment: Optional[Environment] = None) -> Environment: """ Use session cache so users don't need to use MFA while there are valid session tokens. This is the behavior of the AWSCLI and what we are trying to emulate. Modified with support for profiles from: https://github.com/boto/botocore/pull/1338/#issuecomment-368472031 """ # By default the cache path is ~/.aws/boto/cache cli_cache = (Path.home() / ".aws" / "cli" / "cache").absolute() # Construct botocore session with cache session = Session(profile=profile) session.get_component("credential_provider").get_provider( "assume-role").cache = credentials.JSONFileCache(cli_cache) # return credentials from session creds = boto3.Session(botocore_session=session, profile_name=profile).get_credentials() return { "AWS_ACCESS_KEY_ID": creds.access_key, "AWS_SECRET_ACCESS_KEY": creds.secret_key, "AWS_SESSION_TOKEN": creds.token, }
def initialize(region, profile): cli_cache = os.path.join(os.path.expanduser("~"), ".aws/cli/cache") session = botocore.session.Session(profile=profile) session.get_component("credential_provider").get_provider("assume-role").cache = credentials.JSONFileCache( cli_cache ) boto3.setup_default_session(botocore_session=session, region_name=region, profile_name=profile)
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)
def get_session(): """ Return a botocore session sharing awscli session caching """ # This little dance is explained here: # https://github.com/boto/botocore/pull/1157#issuecomment-387580482 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 boto3.Session(botocore_session=session)
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 setUp(self): try: self.event_loop = asyncio.get_event_loop() except RuntimeError: self.event_loop = asyncio.new_event_loop() working_dir = os.path.join(os.path.expanduser('~'), '.aws/cli/cache') session = AioSession(profile=os.environ.get('AWS_PROFILE')) provider = session.get_component('credential_provider').get_provider('assume-role') provider.cache = credentials.JSONFileCache(working_dir) aioboto3.setup_default_session(botocore_session=session)
def create(*, profile_name: str): """ Create a new session provider with MFA authentication, that you can use to create temporary assume role sessions for roles that are protected by policies requiring MFA :param profile_name: the profile to use to create the base session :return: the SessionProvider """ session = Session(profile_name=profile_name) session_cache = SessionCache(cache=credentials.JSONFileCache()) session_factory = CachedMfaSessionFactory( sts_client=session.client("sts"), session_cache=session_cache) return MFASessionProvider( session_data=session_factory.get_session_token())
def _refresh_session(self): """ Update boto3's default session by creating a new session based on values set in the context. Some properties of the Boto3's session object are read-only. Therefore when Click parses new AWS session related properties (like region & profile), it will call this method to create a new session with latest values for these properties. """ try: botocore_session = botocore.session.get_session() boto3.setup_default_session(botocore_session=botocore_session, region_name=self._aws_region, profile_name=self._aws_profile) # get botocore session and setup caching for MFA based credentials botocore_session.get_component("credential_provider").get_provider( "assume-role").cache = credentials.JSONFileCache() except botocore.exceptions.ProfileNotFound as ex: raise CredentialsError(str(ex)) from ex
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
def initiate_session(self, user_input, region): self.user_input = user_input self.region = region # Established botocore session with caching ability cli_cache = os.path.join(os.path.expanduser('~'),'.aws/cli/cache') self.session = botocore.session.Session(profile=self.user_input) self.session.get_component('credential_provider').get_provider('assume-role').cache = credentials.JSONFileCache(cli_cache) self.session_2 = boto3.Session(botocore_session=self.session, profile_name = self.user_input) self.get_all_ec2_id() self.create_tags()
def _get_session(self, profile, region=None): """ Returns a boto session in the target account. If a ``profile`` is specified in ConnectionManager's initialiser, then the profile is used to generate temporary credentials to create the Boto session. If ``profile`` is not specified then the default profile is assumed to create the boto session. :returns: The Boto3 session. :rtype: boto3.session.Session :raises: botocore.exceptions.ClientError """ with self._session_lock: self.logger.debug("Getting Boto3 session") key = (region, profile) if self._boto_sessions.get(key) is None: self.logger.debug("No Boto3 session found, creating one...") self.logger.debug("Using cli credentials...") # Create a botocore session to pass into the boto3 session. # Used to add a persistent credential cache to botocore after # the boto3 session has finished initialization. botocore_session = botocore.session.get_session() # Credentials from env take priority over profile config = { "profile_name": profile, "region_name": region, "aws_access_key_id": environ.get("AWS_ACCESS_KEY_ID"), "aws_secret_access_key": environ.get( "AWS_SECRET_ACCESS_KEY" ), "aws_session_token": environ.get("AWS_SESSION_TOKEN"), "botocore_session": botocore_session, } session = boto3.session.Session(**config) # Use a credentials cache for assumed role profiles. # Directory to store cached assume-role credentials. # This is the same directory used by aws-cli CACHE_DIR = path.expanduser( path.join('~', '.aws', 'cli', 'cache')) provider = botocore_session \ .get_component('credential_provider') \ .get_provider('assume-role') provider.cache = credentials.JSONFileCache(CACHE_DIR) self._boto_sessions[key] = session self.logger.debug( "Using credential set from %s: %s", session.get_credentials().method, { "AccessKeyId": mask_key( session.get_credentials().access_key ), "SecretAccessKey": mask_key( session.get_credentials().secret_key ), "Region": session.region_name } ) self.logger.debug("Boto3 session created") return self._boto_sessions[key]
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)
# 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)