|
1 | 1 | import io |
2 | | -import os |
3 | | - |
4 | 2 | from britive.britive import Britive |
5 | 3 | from .helpers.config import ConfigManager |
6 | 4 | from .helpers.credentials import FileCredentialManager, EncryptedFileCredentialManager |
|
13 | 11 | from .helpers.cache import Cache |
14 | 12 | from britive import exceptions |
15 | 13 | from pathlib import Path |
| 14 | +from datetime import datetime |
16 | 15 |
|
17 | 16 |
|
18 | 17 | default_table_format = 'fancy_grid' |
@@ -286,46 +285,71 @@ def checkin(self, profile): |
286 | 285 | application_name=app_name |
287 | 286 | ) |
288 | 287 |
|
289 | | - def checkout(self, alias, blocktime, console, justification, mode, maxpolltime, profile): |
290 | | - self.login() |
| 288 | + def checkout(self, alias, blocktime, console, justification, mode, maxpolltime, profile, passphrase): |
291 | 289 | # first check if this is a profile alias |
292 | 290 | profile_or_alias = alias or profile |
293 | | - profile = self.config.profile_aliases.get(profile, profile) |
294 | | - parts = profile.split('/') |
295 | | - if len(parts) != 3: |
296 | | - raise click.ClickException('Provided profile string does not have the required 3 parts.') |
297 | | - app_name = parts[0] |
298 | | - env_name = parts[1] |
299 | | - profile_name = parts[2] |
300 | 291 |
|
301 | | - try: |
302 | | - response = self.b.my_access.checkout_by_name( |
303 | | - profile_name=profile_name, |
304 | | - environment_name=env_name, |
305 | | - application_name=app_name, |
306 | | - programmatic=False if console else True, |
307 | | - include_credentials=True, |
308 | | - wait_time=blocktime, |
309 | | - max_wait_time=maxpolltime, |
310 | | - justification=justification |
311 | | - ) |
312 | | - except exceptions.ApprovalRequiredButNoJustificationProvided: |
313 | | - raise click.ClickException('approval required and no justification provided.') |
314 | | - except ValueError as e: |
315 | | - raise click.BadParameter(str(e)) |
| 292 | + credentials = None |
| 293 | + app_type = None |
| 294 | + |
| 295 | + if mode == 'awscredentialprocess': |
| 296 | + self.silent = True # the aws credential process CANNOT output anything other than the expected JSON |
| 297 | + # we need to check the credential process cache for the credentials first |
| 298 | + # then check to see if they are expired |
| 299 | + # if not simply return those credentials |
| 300 | + # if they are expired |
| 301 | + app_type = 'AWS' # just hardcode as we know for sure this is for AWS |
| 302 | + credentials = Cache(passphrase=passphrase).get_awscredentialprocess(profile_name=profile_or_alias) |
| 303 | + if credentials: |
| 304 | + expiration_timestamp_str = credentials['expirationTime'].replace('Z', '') |
| 305 | + expires = datetime.fromisoformat(expiration_timestamp_str) |
| 306 | + now = datetime.utcnow() |
| 307 | + if now >= expires: # check to ensure the credentials are still valid, if not, set to None and get new |
| 308 | + credentials = None |
| 309 | + |
| 310 | + if not credentials: # nothing found via aws credential process or not aws credential process mode |
| 311 | + self.login() |
| 312 | + profile = self.config.profile_aliases.get(profile, profile) |
| 313 | + parts = profile.split('/') |
| 314 | + if len(parts) != 3: |
| 315 | + raise click.ClickException('Provided profile string does not have the required 3 parts.') |
| 316 | + app_name = parts[0] |
| 317 | + env_name = parts[1] |
| 318 | + profile_name = parts[2] |
316 | 319 |
|
317 | | - if alias: # do this down here so we know that the profile is valid and a checkout was successful |
318 | | - self.config.save_profile_alias(alias=alias, profile=profile) |
| 320 | + try: |
| 321 | + response = self.b.my_access.checkout_by_name( |
| 322 | + profile_name=profile_name, |
| 323 | + environment_name=env_name, |
| 324 | + application_name=app_name, |
| 325 | + programmatic=False if console else True, |
| 326 | + include_credentials=True, |
| 327 | + wait_time=blocktime, |
| 328 | + max_wait_time=maxpolltime, |
| 329 | + justification=justification |
| 330 | + ) |
| 331 | + credentials = response['credentials'] |
| 332 | + app_type = self._get_app_type(response['appContainerId']) |
| 333 | + except exceptions.ApprovalRequiredButNoJustificationProvided: |
| 334 | + raise click.ClickException('approval required and no justification provided.') |
| 335 | + except ValueError as e: |
| 336 | + raise click.BadParameter(str(e)) |
| 337 | + |
| 338 | + if alias: # do this down here so we know that the profile is valid and a checkout was successful |
| 339 | + self.config.save_profile_alias(alias=alias, profile=profile) |
| 340 | + if mode == 'awscredentialprocess': |
| 341 | + Cache(passphrase=passphrase).save_awscredentialprocess( |
| 342 | + profile_name=profile_or_alias, |
| 343 | + credentials=credentials |
| 344 | + ) |
319 | 345 |
|
320 | | - app_container_id = response['appContainerId'] |
321 | | - app_type = self._get_app_type(app_container_id) |
322 | 346 | cc_printer = self.__get_cloud_credential_printer( |
323 | 347 | app_type, |
324 | 348 | console, |
325 | 349 | mode, |
326 | 350 | profile_or_alias, |
327 | 351 | self.silent, |
328 | | - response['credentials'] |
| 352 | + credentials |
329 | 353 | ) |
330 | 354 | cc_printer.print() |
331 | 355 |
|
|
0 commit comments