-
Notifications
You must be signed in to change notification settings - Fork 20
/
get-credentials
executable file
·135 lines (106 loc) · 6.18 KB
/
get-credentials
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3
# By Michael Ludvig <[email protected]> (c) 2017
# Webpage: https://aws.nz/aws-utils/get-credentials
# License: GPLv3
# Simple script that retrieves AWS credentials (access key,
# secret key and possibly security token) from any avaiable
# source:
# - Environment variables
# - ~/.aws/config or ~/.aws/credentials (including cross-account)
# - EC2 IAM Role
# - ...
# See http://boto3.readthedocs.io/en/latest/guide/configuration.html
import os
import sys
import argparse
import botocore
import boto3
from collections import OrderedDict
# Boto3 1.4.x or newer required
(ver_major, ver_minor, ver_patch) = boto3.__version__.split('.')
if int(ver_major)*100 + int(ver_minor) < 104:
sys.exit("ERROR: Boto3 1.4.x or newer is required")
def parse_args(argv):
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, add_help=False)
group_general = parser.add_argument_group('General Options')
group_general.add_argument('-p', '--profile', dest='profile', type=str, help='Configuration profile from ~/.aws/{credentials,config}')
group_general.add_argument('-r', '--region', dest='region', type=str, help='Set / override AWS region.')
group_general.add_argument('-v', '--verbose', action='count', dest='verbose', help='Increate verbosity level')
group_general.add_argument('-h', '--help', action="help", help='Print this help and exit')
group_outputs = parser.add_argument_group('Output Options')
group_outputs.add_argument('--access-key-var', dest='access_key_var', metavar='AWS_ACCESS_KEY_ID', default='AWS_ACCESS_KEY_ID', help='Access Key variable name. Default is $AWS_ACCESS_KEY_ID')
group_outputs.add_argument('--secret-key-var', dest='secret_key_var', metavar='AWS_SECRET_ACCESS_KEY', default='AWS_SECRET_ACCESS_KEY', help='Secret Key variable name. Default is $AWS_SECRET_ACCESS_KEY')
group_outputs.add_argument('--token-var', dest='session_token_var', metavar='AWS_SESSION_TOKEN', default='AWS_SESSION_TOKEN,AWS_SECURITY_TOKEN', help='Session/Security Token variable name. Default is $AWS_SESSION_TOKEN and $AWS_SECURITY_TOKEN (both will be set).')
group_outputs.add_argument('--region-var', dest='region_var', metavar='AWS_DEFAULT_REGION', default='', nargs='?', const='AWS_DEFAULT_REGION', help='Default Region variable name, if available. Usually $AWS_DEFAULT_REGION. Not exported by default.')
group_outputs.add_argument('--profile-var', dest='profile_var', metavar='AWS_PROFILE', default='', nargs='?', const='AWS_PROFILE', help='Default Profile variable name, if available. Usually $AWS_PROFILE. Not exported by default.')
group_outputs.add_argument('--method-var', dest='method_var', metavar='GET_CREDENTIALS_METHOD_USED', default='', nargs='?', const='GET_CREDENTIALS_METHOD_USED', help='Method used to obtain the credentials, e.g. "iam-role", "assume-role", "env" or "shared-credentials-file". Not exported by default.')
parser.usage = "{} [OPTIONS] [-- COMMAND [ARG ...]]".format(parser.prog)
parser.description='Retrieve AWS credentials from any available source'
parser.epilog='''
Examples:
1) Print AWS credentials from EC2 IAM Role and the method used
~ $ {prog} --method-var
export AWS_ACCESS_KEY_ID=ASIAZXCVBNMASDFGHJKL
export AWS_SECRET_ACCESS_KEY=lLvl4lTFLRERTuHi5Mrf4uuJ++8T7MlLvl4lT
export AWS_SESSION_TOKEN=OnlOwq5fxy[...]2qJ1ZgqDDxp68romfqJh1x3yVy
export AWS_SECRET_TOKEN=OnlOwq5fxy[...]2qJ1ZgqDDxp68romfqJh1x3yVy
export GET_CREDENTIALS_METHOD_USED=iam-role
2) Run a program with the AWS credentials environment variables set
~ $ {prog} --profile cross-account -- aws sts get-caller-identity
{{
"Account": "123456789012",
"UserId": "AROAQWERTYUIOP1234556:AWS-CLI-session",
"Arn": "arn:aws:sts::123456789012:assumed-role/CrossRole/AWS-CLI-session"
}}
This is equivalent to 'aws --profile cross-account sts get-caller-identity'
and is intended for programs that do not support obtaining credentials
from ~/.aws/credentials or from EC2 instance IAM Role.
Visit https://aws.nz/aws-utils/get-credentials for more info
and more usage examples.
'''.format(prog=parser.prog)
# Parse supplied arguments
args = parser.parse_args(argv)
# If the user specified --region he probably wants to have it exported
if args.region and args.region_var == '':
# Figure out the default '--region-var' variable
args.region_var = parser.parse_args(['--region-var']).region_var
return args
def update_env(env, var_names, var_value):
if var_names and var_value:
for var_name in var_names.split(','):
env[var_name] = var_value
if __name__ == "__main__":
## Split command line to main args and optional command to run
argv = sys.argv[1:]
cmd = ''
if argv.count('--') > 0:
cmd = argv[argv.index('--')+1:]
argv = argv[:argv.index('--')]
args = parse_args(argv)
# Create command if we've got some "unknown_args" left
if cmd and cmd[0] == '--':
cmd.pop(0)
# aws-cli compatible MFA cache
cli_cache = os.path.join(os.path.expanduser('~'),'.aws/cli/cache')
# Construct boto3 session with MFA cache
session = boto3.session.Session(profile_name=args.profile, region_name=args.region)
session._session.get_component('credential_provider').get_provider('assume-role').cache = botocore.credentials.JSONFileCache(cli_cache)
credentials = session.get_credentials()
if not credentials:
sys.exit("ERROR: Unable to locate credentials from any source.")
env = OrderedDict()
update_env(env, args.access_key_var, credentials.access_key)
update_env(env, args.secret_key_var, credentials.secret_key)
update_env(env, args.session_token_var, credentials.token)
update_env(env, args.profile_var, args.profile)
update_env(env, args.region_var, session.region_name)
update_env(env, args.method_var, credentials.method)
if args.verbose or not cmd:
for var in env.keys():
print('export {}="{}"'.format(var, env[var]))
if cmd:
import subprocess
os.environ.update(env)
cmd_line = ' '.join(["'{}'".format(c) for c in cmd])
cmd_run = subprocess.run(cmd_line, shell=True)
sys.exit(cmd_run.returncode)