From 2c87cc5b713af418f17d6f87a912d67f3eddc42a Mon Sep 17 00:00:00 2001 From: Murshed Jamil Ahmed Date: Sat, 19 Oct 2024 20:06:51 +0000 Subject: [PATCH 1/2] Add support for Role Session Name to EKS commands This commit adds a --session-name option to the eks get-token and eks update-kubeconfig commands. Prior to this, when creating a kubeconfig file with eks update-kubeconfig and specifying a --role-arn, there was no way to set a custom Role Session Name. This session name was hardcoded to "EKSGetTokenAuth". Role session names are included in the output of commands like `kubectl auth whoami` and can be used to distinguish users connecting to the EKS cluster that are using the same --role-arn. --- awscli/customizations/eks/get_token.py | 20 ++++++++++++---- .../customizations/eks/update_kubeconfig.py | 12 ++++++++++ tests/functional/eks/test_get_token.py | 23 +++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/awscli/customizations/eks/get_token.py b/awscli/customizations/eks/get_token.py index c85b86dd7d0e..523691ea2da1 100644 --- a/awscli/customizations/eks/get_token.py +++ b/awscli/customizations/eks/get_token.py @@ -95,6 +95,14 @@ class GetTokenCommand(BasicCommand): ), 'required': False, }, + { + 'name': 'session-name', + 'help_text': ( + "Use this parameter with --role-arn to specify a role session name. " + "When omitted, the role session name defaults to 'EKSGetTokenAuth'." + ), + 'required': False, + }, { 'name': 'cluster-id', # When EKS in-region cluster supports cluster-id, we will need to update this help text @@ -114,7 +122,7 @@ def get_expiration_time(self): def _run_main(self, parsed_args, parsed_globals): client_factory = STSClientFactory(self._session) sts_client = client_factory.get_sts_client( - region_name=parsed_globals.region, role_arn=parsed_args.role_arn + region_name=parsed_globals.region, role_arn=parsed_args.role_arn, role_session_name=parsed_args.session_name ) validate_mutually_exclusive(parsed_args, ['cluster_name'], ['cluster_id']) @@ -240,10 +248,10 @@ class STSClientFactory(object): def __init__(self, session): self._session = session - def get_sts_client(self, region_name=None, role_arn=None): + def get_sts_client(self, region_name=None, role_arn=None, role_session_name=None): client_kwargs = {'region_name': region_name} if role_arn is not None: - creds = self._get_role_credentials(region_name, role_arn) + creds = self._get_role_credentials(region_name, role_arn, role_session_name) client_kwargs['aws_access_key_id'] = creds['AccessKeyId'] client_kwargs['aws_secret_access_key'] = creds['SecretAccessKey'] client_kwargs['aws_session_token'] = creds['SessionToken'] @@ -251,10 +259,12 @@ def get_sts_client(self, region_name=None, role_arn=None): self._register_k8s_aws_id_handlers(sts) return sts - def _get_role_credentials(self, region_name, role_arn): + def _get_role_credentials(self, region_name, role_arn, role_session_name): sts = self._session.create_client('sts', region_name) + if role_session_name is None: + role_session_name = 'EKSGetTokenAuth' return sts.assume_role( - RoleArn=role_arn, RoleSessionName='EKSGetTokenAuth' + RoleArn=role_arn, RoleSessionName=role_session_name )['Credentials'] def _register_k8s_aws_id_handlers(self, sts_client): diff --git a/awscli/customizations/eks/update_kubeconfig.py b/awscli/customizations/eks/update_kubeconfig.py index 8bce83525bbb..f8fb8acb5275 100644 --- a/awscli/customizations/eks/update_kubeconfig.py +++ b/awscli/customizations/eks/update_kubeconfig.py @@ -78,6 +78,12 @@ class UpdateKubeconfigCommand(BasicCommand): "connect to the cluster the first time."), 'required': False }, + { + 'name': 'session-name', + 'help_text': ("The name of the role session to be passed down " + "to further commands."), + 'required': False + }, { 'name': 'dry-run', 'action': 'store_true', @@ -334,6 +340,12 @@ def get_user_entry(self, user_alias=None): self._parsed_args.role_arn ]) + if self._parsed_args.session_name is not None: + generated_user["user"]["exec"]["args"].extend([ + "--session-name", + self._parsed_args.session_name + ]) + if self._session.profile: generated_user["user"]["exec"]["env"] = [OrderedDict([ ("name", "AWS_PROFILE"), diff --git a/tests/functional/eks/test_get_token.py b/tests/functional/eks/test_get_token.py index 89801f9babde..69828eb35cda 100644 --- a/tests/functional/eks/test_get_token.py +++ b/tests/functional/eks/test_get_token.py @@ -25,6 +25,7 @@ def setUp(self): super(TestGetTokenCommand, self).setUp() self.cluster_name = 'MyCluster' self.role_arn = 'arn:aws:iam::012345678910:role/RoleArn' + self.session_name = 'CustomSessionName123' self.access_key = 'ABCDEFGHIJKLMNOPQRST' self.secret_key = 'TSRQPONMLKJUHGFEDCBA' self.session_token = 'TOKENTOKENTOKENTOKEN' @@ -174,6 +175,28 @@ def test_url_with_arn(self): ) self.assert_url_correct(response, has_session_token=True) + def test_url_with_arn_and_session_name(self): + cmd = 'eks get-token --cluster-name %s' % self.cluster_name + cmd += ' --role-arn %s' % self.role_arn + cmd += ' --session-name %s' % self.session_name + self.parsed_responses = [ + { + "Credentials": { + "AccessKeyId": self.access_key, + "SecretAccessKey": self.secret_key, + "SessionToken": self.session_token, + }, + } + ] + response = self.run_get_token(cmd) + assume_role_call = self.operations_called[0] + self.assertEqual(assume_role_call[0].name, 'AssumeRole') + self.assertEqual( + assume_role_call[1], + {'RoleArn': self.role_arn, 'RoleSessionName': self.session_name}, + ) + self.assert_url_correct(response, has_session_token=True) + def test_token_has_no_padding(self): cmd = 'eks get-token --cluster-name %s' % self.cluster_name num_rounds = 100 From 1a17c42f566934637bcb0da2aeb5a8b5475427e5 Mon Sep 17 00:00:00 2001 From: Murshed Jamil Ahmed Date: Wed, 23 Oct 2024 09:49:00 -0400 Subject: [PATCH 2/2] Update awscli/customizations/eks/update_kubeconfig.py Applying changes recommended by @micahhausler Co-authored-by: Micah Hausler --- awscli/customizations/eks/update_kubeconfig.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awscli/customizations/eks/update_kubeconfig.py b/awscli/customizations/eks/update_kubeconfig.py index f8fb8acb5275..ed44b3cbd8bd 100644 --- a/awscli/customizations/eks/update_kubeconfig.py +++ b/awscli/customizations/eks/update_kubeconfig.py @@ -80,8 +80,8 @@ class UpdateKubeconfigCommand(BasicCommand): }, { 'name': 'session-name', - 'help_text': ("The name of the role session to be passed down " - "to further commands."), + 'help_text': ("The name of the role session to be used when " + "role-arn is set."), 'required': False }, {