@@ -81,6 +81,21 @@ class Layer1(AWSAuthConnection):
81
81
def __init__ (self , aws_access_key_id = None , aws_secret_access_key = None ,
82
82
is_secure = True , port = None , proxy = None , proxy_port = None ,
83
83
debug = 0 , session_token = None , region = None ):
84
+ """
85
+ This is, for the moment at least, more complicated than other
86
+ Connection classes wrt credentials. If a session token is
87
+ passed in, it is expected to be a Credential object obtained
88
+ from a call to STS and those credentials will be used as-is.
89
+ If no session_token is passed in, we need to check to see if
90
+ we are running on an EC2 instance with an IAM Role associated
91
+ with it. If so, use those temporarty credentials. Finally, if
92
+ neither of the above scenarios were true, we must create
93
+ temporary credentials by making a call to STS ourselves.
94
+
95
+ NOTE: If this is called with an STS session token and no real
96
+ AWS credentials, there will be no way to renew the STS
97
+ session token when it expires.
98
+ """
84
99
if not region :
85
100
region_name = boto .config .get ('DynamoDB' , 'region' ,
86
101
self .DefaultRegionName )
@@ -92,32 +107,50 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
92
107
self .region = region
93
108
self ._passed_access_key = aws_access_key_id
94
109
self ._passed_secret_key = aws_secret_access_key
95
- if not session_token :
96
- session_token = self ._get_session_token ()
97
- self .creds = session_token
110
+ if session_token :
111
+ # If an STS session token was passed in, use it.
112
+ # Note, however, that if no real credentials are passed
113
+ # in it will be impossible to renew this session token
114
+ # and when it expires, things will stop working.
115
+ AWSAuthConnection .__init__ (self , self .region .endpoint ,
116
+ session_token .access_key ,
117
+ session_token .secret_key ,
118
+ is_secure , port , proxy , proxy_port ,
119
+ debug = debug ,
120
+ security_token = session_token .session_token )
121
+ else :
122
+ # Create a connection in the normal way and see if
123
+ # session credentials are found. If so, it means we are
124
+ # using IAM Roles on an EC2 instance and we are good to go.
125
+ # If not, we need to explicitly create a session token.
126
+ AWSAuthConnection .__init__ (self , self .region .endpoint ,
127
+ aws_access_key_id ,
128
+ aws_secret_access_key ,
129
+ is_secure , port , proxy , proxy_port ,
130
+ debug = debug )
131
+ if not self .provider .security_token :
132
+ self ._need_session_token = True
133
+ self ._get_session_token ()
134
+ else :
135
+ self ._need_session_token = False
98
136
self .throughput_exceeded_events = 0
99
137
self .request_id = None
100
138
self .instrumentation = {'times' : [], 'ids' : []}
101
139
self .do_instrumentation = False
102
- AWSAuthConnection .__init__ (self , self .region .endpoint ,
103
- self .creds .access_key ,
104
- self .creds .secret_key ,
105
- is_secure , port , proxy , proxy_port ,
106
- debug = debug ,
107
- security_token = self .creds .session_token )
108
-
109
- def _update_provider (self ):
110
- self .provider = Provider ('aws' ,
111
- self .creds .access_key ,
112
- self .creds .secret_key ,
113
- self .creds .session_token )
114
- self ._auth_handler .update_provider (self .provider )
115
140
116
141
def _get_session_token (self ):
117
- boto .log .debug ('Creating new Session Token' )
118
- sts = boto .connect_sts (self ._passed_access_key ,
119
- self ._passed_secret_key )
120
- return sts .get_session_token ()
142
+ if self ._need_session_token :
143
+ boto .log .debug ('Creating new Session Token' )
144
+ sts = boto .connect_sts (self ._passed_access_key ,
145
+ self ._passed_secret_key )
146
+ token = sts .get_session_token ()
147
+ self .provider = Provider (self ._provider_type ,
148
+ token .access_key ,
149
+ token .secret_key ,
150
+ token .session_token )
151
+ else :
152
+ self .provider = Provider (self ._provider_type )
153
+ self ._auth_handler .update_provider (self .provider )
121
154
122
155
def _required_auth_capability (self ):
123
156
return ['hmac-v3-http' ]
@@ -164,8 +197,7 @@ def _retry_handler(self, response, i, next_sleep):
164
197
status = (msg , i , next_sleep )
165
198
elif self .SessionExpiredError in data .get ('__type' ):
166
199
msg = 'Renewing Session Token'
167
- self .creds = self ._get_session_token ()
168
- self ._update_provider ()
200
+ self ._get_session_token ()
169
201
status = (msg , i + self .num_retries - 1 , 0 )
170
202
elif self .ConditionalCheckFailedError in data .get ('__type' ):
171
203
raise dynamodb_exceptions .DynamoDBConditionalCheckFailedError (
0 commit comments