Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ "3.7", "3.8", "3.9", "3.10" ]
python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ A configuration wizard will prompt you to enter the necessary configuration para
- 'internal' for direct interaction with the Okta APIs (`OKTA_API_KEY` environment variable required)
- 'appurl' to set an aws application link url. This setting removes the need of an OKTA API key.
- write_aws_creds - True or False - If True, the AWS credentials will be written to `~/.aws/credentials` otherwise it will be written to stdout.
- cred_profile - If writing to the AWS cred file, this sets the name of the AWS credential profile.
- cred_profile - If writing to the AWS cred file, this sets the name of the AWS credential profile. Can be overridden with the --aws-cred-profile CLI option or the GIMME_AWS_CREDS_CRED_PROFILE environment variable.
- The reserved word `role` will use the name component of the role arn as the profile name. i.e. arn:aws:iam::123456789012:role/okta-1234-role becomes section [okta-1234-role] in the aws credentials file
- The reserved word `acc` will use the account number (or alias if `resolve_aws_alias` is set to y) as the profile name. i.e. arn:aws:iam::123456789012:role/okta-1234-role becomes section [arn:aws:iam::123456789012] or if `resolve_aws_alias` [okta-1234-role] in the aws credentials file.
- The reserved word `acc-role` will use the name component of the role arn prepended with account number (or alias if `resolve_aws_alias` is set to y) to avoid collisions, i.e. arn:aws:iam::123456789012:role/okta-1234-role becomes section [123456789012-okta-1234-role], or if `resolve_aws_alias` [okta-1234-role] in the aws credentials file
Expand Down Expand Up @@ -320,7 +320,7 @@ A list of values of to change with environment variables are:
- `AWS_DEFAULT_DURATION` - corresponds to `aws_default_duration` configuration
- `AWS_SHARED_CREDENTIALS_FILE` - file to write credentials to, points to `~/.aws/credentials` by default
- `GIMME_AWS_CREDS_CLIENT_ID` - corresponds to `client_id` configuration
- `GIMME_AWS_CREDS_CRED_PROFILE` - corresponds to `cred_profile` configuration
- `GIMME_AWS_CREDS_CRED_PROFILE` - corresponds to `cred_profile` configuration and `--aws-cred-profile` CLI option
- `GIMME_AWS_CREDS_OUTPUT_FORMAT` - corresponds to `output_format` configuration and `--output-format` CLI option
- `OKTA_AUTH_SERVER` - corresponds to `okta_auth_server` configuration
- `OKTA_DEVICE_TOKEN` - corresponds to `device_token` configuration, can be used in CI
Expand Down
6 changes: 6 additions & 0 deletions gimme_aws_creds/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ def get_args(self):
'--force-classic', action='store_true',
help='Force the use of the Okta Classic login process (Okta Identity Engine only)'
)
parser.add_argument(
'--aws-cred-profile',
help="If set, overrides the cred_profile setting from the config file and the "
"GIMME_AWS_CREDS_CRED_PROFILE environment variable."
)
args = parser.parse_args(self.ui.args)

self.action_configure = args.action_configure
Expand Down Expand Up @@ -192,6 +197,7 @@ def get_args(self):
self.output_format = args.output_format
if args.roles is not None:
self.roles = [role.strip() for role in args.roles.split(',') if role.strip()]
self.cred_profile = args.aws_cred_profile
self.conf_profile = args.profile or 'DEFAULT'

def _handle_config(self, config, profile_config, include_inherits = True):
Expand Down
3 changes: 3 additions & 0 deletions gimme_aws_creds/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,9 @@ def generate_config(self):
key = self.envvar_conf_map.get(value, value).lower()
self.conf_dict[key] = self.ui.environ.get(value)

if config.cred_profile is not None:
self.conf_dict['cred_profile'] = config.cred_profile

# AWS Default session duration ....
if self.conf_dict.get('aws_default_duration'):
self.config.aws_default_duration = int(self.conf_dict['aws_default_duration'])
Expand Down
17 changes: 17 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def tearDown(self):
remember_device=False,
output_format=None,
roles=None,
aws_cred_profile=None,
action_register_device=False,
action_configure=False,
action_list_profiles=False,
Expand All @@ -47,6 +48,22 @@ def test_get_args_username(self, mock_arg):
self.config.get_args()
self.assertEqual(self.config.username, "ann")

def test_get_args_aws_cred_profile_set(self):
"""Test that --aws-cred-profile is stored on Config when provided"""
test_ui = MockUserInterface(argv=[
'gimme-aws-creds', '--aws-cred-profile', 'my-custom-profile',
])
config = Config(gac_ui=test_ui, create_config=False)
config.get_args()
self.assertEqual(config.cred_profile, "my-custom-profile")

def test_get_args_aws_cred_profile_not_set(self):
"""Test that cred_profile is None on Config when --aws-cred-profile is not provided"""
test_ui = MockUserInterface(argv=['gimme-aws-creds'])
config = Config(gac_ui=test_ui, create_config=False)
config.get_args()
self.assertIsNone(config.cred_profile)

def test_read_config(self):
"""Test to make sure getting config works"""
test_ui = MockUserInterface(argv=[
Expand Down
69 changes: 69 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import shutil
import unittest
from unittest.mock import patch

from gimme_aws_creds import errors
from gimme_aws_creds.common import RoleSet
from gimme_aws_creds.main import GimmeAWSCreds
from tests.user_interface_mock import MockUserInterface


class TestMain(unittest.TestCase):
Expand Down Expand Up @@ -312,3 +314,70 @@ def test_get_profile_name_else(self):
include_path = True
self.assertEqual(creds.get_profile_name(cred_profile, include_path, naming_data, resolve_alias, role),
'foo')


class TestCredProfilePrecedence(unittest.TestCase):
"""Tests for --aws-cred-profile CLI flag precedence over env var and config file.

Expected precedence: CLI flag > env var > config file
"""

CONFIG_TEMPLATE = """[DEFAULT]
client_id = test-client
okta_org_url = https://test.okta.com
cred_profile = {cred_profile}
"""

def setUp(self):
self._temp_dirs = []

def tearDown(self):
for d in self._temp_dirs:
shutil.rmtree(d, ignore_errors=True)

def _build_and_generate(self, argv=None, environ=None, config_cred_profile='file-profile'):
test_ui = MockUserInterface(
argv=argv or [],
environ=environ or {},
)
self._temp_dirs.append(test_ui.HOME)
with open(test_ui.HOME + "/.okta_aws_login_config", "w") as f:
f.write(self.CONFIG_TEMPLATE.format(cred_profile=config_cred_profile))

creds = GimmeAWSCreds(ui=test_ui)
creds.generate_config()
return creds

def test_cli_flag_overrides_config_file(self):
"""--aws-cred-profile should override the cred_profile from config file"""
creds = self._build_and_generate(
argv=['gimme-aws-creds', '--aws-cred-profile', 'cli-profile'],
config_cred_profile='file-profile',
)
self.assertEqual(creds.conf_dict['cred_profile'], 'cli-profile')

def test_cli_flag_overrides_env_var(self):
"""--aws-cred-profile should override GIMME_AWS_CREDS_CRED_PROFILE env var"""
creds = self._build_and_generate(
argv=['gimme-aws-creds', '--aws-cred-profile', 'cli-profile'],
environ={'GIMME_AWS_CREDS_CRED_PROFILE': 'env-profile'},
config_cred_profile='file-profile',
)
self.assertEqual(creds.conf_dict['cred_profile'], 'cli-profile')

def test_env_var_overrides_config_file_when_no_cli_flag(self):
"""Without --aws-cred-profile, GIMME_AWS_CREDS_CRED_PROFILE should override config file"""
creds = self._build_and_generate(
argv=['gimme-aws-creds'],
environ={'GIMME_AWS_CREDS_CRED_PROFILE': 'env-profile'},
config_cred_profile='file-profile',
)
self.assertEqual(creds.conf_dict['cred_profile'], 'env-profile')

def test_config_file_used_when_no_cli_flag_or_env_var(self):
"""Without --aws-cred-profile or env var, config file value should be used"""
creds = self._build_and_generate(
argv=['gimme-aws-creds'],
config_cred_profile='file-profile',
)
self.assertEqual(creds.conf_dict['cred_profile'], 'file-profile')
Loading