Skip to content

Commit 41b5ff0

Browse files
authored
Merge pull request #19 from britive/develop
Develop
2 parents da8502e + 7d29557 commit 41b5ff0

File tree

6 files changed

+100
-27
lines changed

6 files changed

+100
-27
lines changed

docs/index.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,13 @@ PyBritive is intended to be used as a CLI application for communicating with the
1414

1515
## Installation
1616

17-
`pybritive` will be installed via Python `pip`. The package is not available in PyPi at this time, so it will be
18-
installed via the published tar balls in the GitHub repo. Determine the most recent version that has been published
19-
and add the version below.
17+
`pybritive` will be installed via Python `pip`.
2018

2119
~~~bash
22-
version=x.y.z
23-
pip install https://github.com/britive/python-cli/releases/download/v$version/pybritive-$version.tar.gz
20+
pip install pybritive
2421
~~~
2522

26-
Or you can always pull the latest version using one of the following commands
23+
Or you can always pull the latest version directly from Github using one of the following commands.
2724

2825
~~~
2926
pip install $(curl -s https://api.github.com/repos/britive/python-cli/releases/latest | jq -r '.assets[] | select(.content_type == "application/x-gzip") | .browser_download_url')

requirements.txt

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

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = pybritive
3-
version = 0.2.2
3+
version = 0.3.0
44
author = Britive Inc.
55
author_email = support@britive.com
66
description = A pure Python CLI for Britive

src/pybritive/britive_cli.py

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,10 @@ def list_profiles(self, checked_out: bool = False):
153153
self.login()
154154
self._set_available_profiles()
155155
data = []
156-
checked_out = [p['papId'] for p in self.b.my_access.list_checked_out_profiles()] if checked_out else []
156+
checked_out_profiles = [p['papId'] for p in self.b.my_access.list_checked_out_profiles()] if checked_out else []
157157

158158
for profile in self.available_profiles:
159-
if not checked_out or profile['profileId'] in checked_out:
159+
if not checked_out or profile['profile_id'] in checked_out_profiles:
160160
row = {
161161
'Application': profile['app_name'],
162162
'Environment': profile['env_name'],
@@ -275,18 +275,12 @@ def __get_cloud_credential_printer(self, app_type, console, mode, profile, silen
275275

276276
def checkin(self, profile):
277277
self.login()
278-
profile = self.config.profile_aliases.get(profile, profile)
279-
parts = profile.split('/')
280-
if len(parts) != 3:
281-
raise click.ClickException('Provided profile string does not have the required 3 parts.')
282-
app_name = parts[0]
283-
env_name = parts[1]
284-
profile_name = parts[2]
278+
parts = self._split_profile_into_parts(profile)
285279

286280
self.b.my_access.checkin_by_name(
287-
profile_name=profile_name,
288-
environment_name=env_name,
289-
application_name=app_name
281+
profile_name=parts['profile'],
282+
environment_name=parts['env'],
283+
application_name=parts['app']
290284
)
291285

292286
def _checkout(self, profile_name, env_name, app_name, programmatic, blocktime, maxpolltime, justification):
@@ -311,6 +305,19 @@ def _checkout(self, profile_name, env_name, app_name, programmatic, blocktime, m
311305
def _should_check_force_renew(app, force_renew, console):
312306
return app in ['AWS', 'AWS Standalone'] and force_renew and not console
313307

308+
309+
def _split_profile_into_parts(self, profile):
310+
profile_real = self.config.profile_aliases.get(profile, profile)
311+
parts = profile_real.split('/')
312+
if len(parts) != 3:
313+
raise click.ClickException('Provided profile string does not have the required 3 parts.')
314+
parts_dict = {
315+
'app': parts[0],
316+
'env': parts[1],
317+
'profile': parts[2]
318+
}
319+
return parts_dict
320+
314321
def checkout(self, alias, blocktime, console, justification, mode, maxpolltime, profile, passphrase,
315322
force_renew, aws_credentials_file):
316323
credentials = None
@@ -335,16 +342,13 @@ def checkout(self, alias, blocktime, console, justification, mode, maxpolltime,
335342
else:
336343
credential_process_creds_found = True
337344

338-
profile_real = self.config.profile_aliases.get(profile, profile)
339-
parts = profile_real.split('/')
340-
if len(parts) != 3:
341-
raise click.ClickException('Provided profile string does not have the required 3 parts.')
345+
parts = self._split_profile_into_parts(profile)
342346

343347
# create this params once so we can use it multiple places
344348
params = {
345-
'profile_name': parts[2],
346-
'env_name': parts[1],
347-
'app_name': parts[0],
349+
'profile_name': parts['profile'],
350+
'env_name': parts['env'],
351+
'app_name': parts['app'],
348352
'programmatic': False if console else True,
349353
'blocktime': blocktime,
350354
'maxpolltime': maxpolltime,
@@ -504,6 +508,28 @@ def cache_clear():
504508
def configure_update(self, section, field, value):
505509
self.config.update(section=section, field=field, value=value)
506510

511+
def request_submit(self, profile, justification):
512+
self.login()
513+
parts = self._split_profile_into_parts(profile)
514+
515+
self.b.my_access.request_approval_by_name(
516+
profile_name=parts['profile'],
517+
environment_name=parts['env'],
518+
application_name=parts['app'],
519+
block_until_disposition=False,
520+
justification=justification
521+
)
522+
523+
def request_withdraw(self, profile):
524+
self.login()
525+
parts = self._split_profile_into_parts(profile)
526+
527+
self.b.my_access.withdraw_approval_request_by_name(
528+
profile_name=parts['profile'],
529+
environment_name=parts['env'],
530+
application_name=parts['app']
531+
)
532+
507533

508534

509535

src/pybritive/cli_interface.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from .commands.checkin import checkin as command_checkin
1010
from .commands.secret import secret as group_secret
1111
from .commands.cache import cache as group_cache
12+
from .commands.request import request as group_request
1213
import sys
1314

1415
# sys.tracebacklimit = 0
@@ -39,6 +40,7 @@ def cli(version):
3940
cli.add_command(command_checkin)
4041
cli.add_command(group_secret)
4142
cli.add_command(group_cache)
43+
cli.add_command(group_request)
4244

4345

4446
if __name__ == "__main__":

src/pybritive/commands/request.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import click
2+
from ..helpers.build_britive import build_britive
3+
from ..options.britive_options import britive_options
4+
from ..completers.profile import profile_completer
5+
6+
@click.group()
7+
def request():
8+
"""Provides functionality related to requesting approval to checkout a profile."""
9+
pass
10+
11+
12+
@request.command()
13+
@build_britive
14+
@britive_options(names='justification,tenant,token,passphrase')
15+
@click.argument('profile', shell_complete=profile_completer)
16+
def submit(ctx, justification, tenant, token, passphrase, profile):
17+
"""Submit a request to checkout a profile.
18+
19+
Only applicable for profiles which require approval. This command will NOT block/wait until the request is
20+
approved or rejected. If you want to wait for the request to be approved, run the `checkout` command which will
21+
wait until the request is approved and then checkout the profile.
22+
23+
This command takes 1 required argument `PROFILE`. This should be a string representation of the profile
24+
that should be checked out. Format is `application name/environment name/profile name`.
25+
"""
26+
27+
ctx.obj.britive.request_submit(
28+
profile=profile,
29+
justification=justification
30+
)
31+
32+
33+
@request.command()
34+
@build_britive
35+
@britive_options(names='tenant,token,passphrase')
36+
@click.argument('profile', shell_complete=profile_completer)
37+
def withdraw(ctx, tenant, token, passphrase, profile):
38+
"""Withdraw a request to checkout a profile.
39+
40+
Only applicable for profiles which require approval.
41+
42+
This command takes 1 required argument `PROFILE`. This should be a string representation of the profile
43+
that should be checked out. Format is `application name/environment name/profile name`.
44+
"""
45+
46+
ctx.obj.britive.request_withdraw(
47+
profile=profile
48+
)

0 commit comments

Comments
 (0)