Skip to content

Commit f0aa704

Browse files
authored
Merge pull request #43 from britive/aws-optional-session-token
Aws optional session token
2 parents cc226bc + 99ad098 commit f0aa704

18 files changed

+175
-40
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@
22

33
All changes to the package starting with v0.3.1 will be logged here.
44

5+
## v0.8.0 [2023-01-05]
6+
#### What's New
7+
* Ability to store a GCP `gcloud` key file locally so `eval $(pybritive checkout "profile" -m gcloudauth)` will automatically authenticate the user with the gcloud CLI.
8+
* Ability to override the default location of the GCP `gcloud` key file with `pybritive checkout "profile" -m gcloudauth --gcloud-key-file /path/to/key.json`
9+
* New command `clear` with subcommands `cache` and `gcloud-key-files`. `cache` has same functionality as `pybritive cache clear` and `gcloud-key-files` will remove all `pybritive` generated temporary key files stored in the default location.
10+
11+
#### Enhancements
12+
* None
13+
14+
#### Bug Fixes
15+
* None
16+
17+
#### Dependencies
18+
* `britive~=2.12.4` from `britive~=2.12.3` - AWS provider optional session token
19+
20+
#### Other
21+
* None
22+
523
## v0.7.2 [2022-12-12]
624
#### What's New
725
* None

TECH_README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ Environment variables that should be set for testing include the following.
4242

4343
Create `./testing-variables.txt` and load what you need so you can easily re-create the needed variables. This file is in `.gitignore`.
4444

45+
Package the code locally with `pip install -e .` so pytest can run against the python package.
46+
Then `pytest tests/ -v` to perform the testing.
47+
4548
The identity used for testing will require access to at least one profile to test `checkout` and `checkin`.
4649
Additionally, the identity will need access to 2 secrets
4750
* one standard secret with path `/pybritive-test-standard` to test `view` - the value of the secret should be generic note with note of `test`

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
britive~=2.12.3
1+
britive~=2.12.4
22
certifi==2022.6.15
33
charset-normalizer==2.1.0
44
click==8.1.3

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = pybritive
3-
version = 0.7.2
3+
version = 0.8.0
44
author = Britive Inc.
55
author_email = support@britive.com
66
description = A pure Python CLI for Britive
@@ -26,7 +26,7 @@ install_requires =
2626
toml
2727
cryptography
2828
python-dateutil
29-
britive>=2.12.3
29+
britive>=2.12.4
3030

3131
[options.packages.find]
3232
where = src

src/pybritive/britive_cli.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def _get_app_type(self, application_id):
255255
raise click.ClickException(f'Application {application_id} not found')
256256

257257
def __get_cloud_credential_printer(self, app_type, console, mode, profile, silent, credentials,
258-
aws_credentials_file):
258+
aws_credentials_file, gcloud_key_file):
259259
if app_type in ['AWS', 'AWS Standalone']:
260260
return printer.AwsCloudCredentialPrinter(
261261
console=console,
@@ -282,7 +282,8 @@ def __get_cloud_credential_printer(self, app_type, console, mode, profile, silen
282282
profile=profile,
283283
credentials=credentials,
284284
silent=silent,
285-
cli=self
285+
cli=self,
286+
gcloud_key_file=gcloud_key_file
286287
)
287288
else:
288289
return printer.GenericCloudCredentialPrinter(
@@ -348,7 +349,7 @@ def _split_profile_into_parts(self, profile):
348349
return parts_dict
349350

350351
def checkout(self, alias, blocktime, console, justification, mode, maxpolltime, profile, passphrase,
351-
force_renew, aws_credentials_file):
352+
force_renew, aws_credentials_file, gcloud_key_file):
352353
credentials = None
353354
app_type = None
354355
credential_process_creds_found = False
@@ -418,7 +419,8 @@ def checkout(self, alias, blocktime, console, justification, mode, maxpolltime,
418419
alias or profile,
419420
self.silent,
420421
credentials,
421-
aws_credentials_file
422+
aws_credentials_file,
423+
gcloud_key_file
422424
).print()
423425

424426
def import_existing_npm_config(self):
@@ -559,6 +561,9 @@ def request_withdraw(self, profile):
559561
application_name=parts['app']
560562
)
561563

564+
def clear_gcloud_auth_key_files(self):
565+
self.config.clear_gcloud_auth_key_files()
566+
562567

563568

564569

src/pybritive/choices/mode.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
'awscredentialprocess', # aws credential process output with additional caching to make the credential process more performant
1515
'azlogin', # azure az login command with all fields populated (suitable for eval)
1616
'azps', # azure powershell script
17-
'browser' # when console access is checked out open the browser to the URL provided
17+
'browser', # when console access is checked out open the browser to the URL provided
18+
'gcloudauth' # gcloud auth activate-service-account with all fields populated (suitable for eval)
1819
],
1920
case_sensitive=False
2021
)

src/pybritive/cli_interface.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .commands.secret import secret as group_secret
1111
from .commands.cache import cache as group_cache
1212
from .commands.request import request as group_request
13+
from .commands.clear import clear as group_clear
1314
import sys
1415
import os
1516

@@ -46,6 +47,7 @@ def cli(version):
4647
cli.add_command(group_secret)
4748
cli.add_command(group_cache)
4849
cli.add_command(group_request)
50+
cli.add_command(group_clear)
4951

5052

5153
if __name__ == "__main__":

src/pybritive/commands/checkout.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
@click.command()
88
@build_britive
99
@britive_options(names='alias,blocktime,console,justification,mode,maxpolltime,silent,force_renew,aws_credentials_file,'
10-
'tenant,token,passphrase,federation_provider')
10+
'gcloud_key_file,tenant,token,passphrase,federation_provider')
1111
@click.argument('profile', shell_complete=profile_completer)
1212
def checkout(ctx, alias, blocktime, console, justification, mode, maxpolltime, silent, force_renew,
13-
aws_credentials_file, tenant, token, passphrase, federation_provider, profile):
13+
aws_credentials_file, gcloud_key_file, tenant, token, passphrase, federation_provider, profile):
1414
"""Checkout a profile.
1515
1616
This command takes 1 required argument `PROFILE`. This should be a string representation of the profile
@@ -28,5 +28,6 @@ def checkout(ctx, alias, blocktime, console, justification, mode, maxpolltime, s
2828
profile=profile,
2929
passphrase=passphrase,
3030
force_renew=force_renew,
31-
aws_credentials_file=aws_credentials_file
31+
aws_credentials_file=aws_credentials_file,
32+
gcloud_key_file=gcloud_key_file
3233
)

src/pybritive/commands/clear.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import click
2+
from ..helpers.build_britive import build_britive
3+
4+
5+
@click.group()
6+
def clear():
7+
"""Clear various local settings and configurations."""
8+
pass
9+
10+
11+
@clear.command()
12+
@build_britive
13+
def cache(ctx):
14+
"""Clears the local cache."""
15+
ctx.obj.britive.cache_clear()
16+
17+
18+
@clear.command(name='gcloud-auth-key-files')
19+
@build_britive
20+
def gcloud_auth_key_files(ctx):
21+
"""Clears the local gcloud auth key files."""
22+
ctx.obj.britive.clear_gcloud_auth_key_files()
23+
24+

src/pybritive/helpers/cloud_credential_printer.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import uuid
23
import click
34
import platform
45
import configparser
@@ -50,6 +51,8 @@ def print(self):
5051
self.print_awscredentialprocess()
5152
if mode_prefix == 'azps':
5253
self.print_azps()
54+
if mode_prefix == 'gcloudauth':
55+
self.print_gcloudauth()
5356

5457
def print_console(self):
5558
if self.mode == 'browser':
@@ -81,6 +84,9 @@ def print_azlogin(self):
8184
def print_azps(self):
8285
self._not_implemented()
8386

87+
def print_gcloudauth(self):
88+
self._not_implemented()
89+
8490
def _not_implemented(self):
8591
raise click.ClickException(f'Application type {self.app_type} does not support the specified mode.')
8692

@@ -210,10 +216,11 @@ def print_azps(self):
210216

211217

212218
class GcpCloudCredentialPrinter(CloudCredentialPrinter):
213-
def __init__(self, console, mode, profile, silent, credentials, cli):
219+
def __init__(self, console, mode, profile, silent, credentials, cli, gcloud_key_file):
214220
key = list(credentials.keys())[0]
215221
credentials = json.loads(credentials[key])
216222
super().__init__('GCP', console, mode, profile, silent, credentials, cli)
223+
self.gcloud_key_file = gcloud_key_file
217224

218225
def print_json(self):
219226
self.cli.print(json.dumps(self.credentials, indent=2), ignore_silent=True)
@@ -223,3 +230,18 @@ def print_json(self):
223230
"--key-file <path-where-above-json-is-stored>", ignore_silent=True
224231
)
225232

233+
def print_gcloudauth(self):
234+
# get path to gcloud key file
235+
if not self.gcloud_key_file: # if --gcloud-key-file not provided
236+
path = Path(self.cli.config.path).parent / 'pybritive-gcloud-key-files' / f'{uuid.uuid4().hex}.json'
237+
else: # we need to parse out/sanitize what was provided
238+
path = Path(self.gcloud_key_file).expanduser().absolute()
239+
240+
# key file does not yet exist so write to it
241+
path.parent.mkdir(exist_ok=True, parents=True)
242+
path.write_text(json.dumps(self.credentials, indent=2))
243+
244+
self.cli.print(
245+
f"gcloud auth activate-service-account {self.credentials['client_email']} --key-file {str(path)}",
246+
ignore_silent=True
247+
)

0 commit comments

Comments
 (0)