aws / aws-elastic-beanstalk-cli

The EB CLI is a command line interface for Elastic Beanstalk that provides interactive commands that simplify creating, updating and monitoring environments from a local repository.
Apache License 2.0
161 stars 79 forks source link

Support SSO Credentials For Assume Role #14

Open jsicotte opened 4 years ago

jsicotte commented 4 years ago

Description

Briefly describe the bug you are facing.

Steps to reproduce

  1. Get the latest credentials: aws2 sso login
  2. Have a profile that that tries to assume a role (role_arn), using the role specified for sso (source_profile).
  3. Try to use the eb command: eb health --profile [profile that is trying to do the assume]

Observed result

The command fails because:

The source profile [name of sso profile] must have credentials. Installing the eb cli in a fresh virtual env does not resolve the issue.

2020-02-18 21:51:33,827 (DEBUG) cement.core.foundation : laying cement for the 'eb' application
2020-02-18 21:51:33,827 (DEBUG) cement.core.hook : defining hook 'pre_setup'
2020-02-18 21:51:33,827 (DEBUG) cement.core.hook : defining hook 'post_setup'
2020-02-18 21:51:33,827 (DEBUG) cement.core.hook : defining hook 'pre_run'
2020-02-18 21:51:33,827 (DEBUG) cement.core.hook : defining hook 'post_run'
2020-02-18 21:51:33,827 (DEBUG) cement.core.hook : defining hook 'pre_argument_parsing'
2020-02-18 21:51:33,827 (DEBUG) cement.core.hook : defining hook 'post_argument_parsing'
2020-02-18 21:51:33,827 (DEBUG) cement.core.hook : defining hook 'pre_close'
2020-02-18 21:51:33,827 (DEBUG) cement.core.hook : defining hook 'post_close'
2020-02-18 21:51:33,828 (DEBUG) cement.core.hook : defining hook 'signal'
2020-02-18 21:51:33,828 (DEBUG) cement.core.hook : defining hook 'pre_render'
2020-02-18 21:51:33,828 (DEBUG) cement.core.hook : defining hook 'post_render'
2020-02-18 21:51:33,828 (DEBUG) cement.core.hook : registering hook 'add_handler_override_options' from cement.core.foundation into hooks['post_setup']
2020-02-18 21:51:33,828 (DEBUG) cement.core.hook : registering hook 'handler_override' from cement.core.foundation into hooks['post_argument_parsing']
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'extension' (IExtension)
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'log' (ILog)
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'config' (IConfig)
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'mail' (IMail)
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'plugin' (IPlugin)
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'output' (IOutput)
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'argument' (IArgument)
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'controller' (IController)
2020-02-18 21:51:33,828 (DEBUG) cement.core.handler : defining handler type 'cache' (ICache)
2020-02-18 21:51:33,829 (DEBUG) cement.core.handler : registering handler '<class 'cement.core.extension.CementExtensionHandler'>' into handlers['extension']['cement']
2020-02-18 21:51:33,844 (DEBUG) cement.ext.ext_plugin : plugin config dir /etc/eb/plugins.d does not exist.
2020-02-18 21:51:33,844 (DEBUG) cement.ext.ext_plugin : plugin config dir /Users/jjsicot/.eb/plugins.d does not exist.
2020-02-18 21:51:33,855 (DEBUG) ebcli.core.hooks : -- EBCLI Version: 3.17.0
2020-02-18 21:51:33,855 (DEBUG) ebcli.core.hooks : -- Python Version: 3.8.1 (default, Dec 27 2019, 18:05:45)
[Clang 11.0.0 (clang-1100.0.33.16)]
2020-02-18 21:51:33,855 (DEBUG) ebcli.core.fileoperations : Project root found at: /Users/jjsicot/Documents/workspaces/data-science-python/demo/search/es_api
2020-02-18 21:51:33,860 (DEBUG) ebcli.core.fileoperations : Project root found at: /Users/jjsicot/Documents/workspaces/data-science-python/demo/search/es_api
2020-02-18 21:51:33,864 (DEBUG) ebcli.core.fileoperations : Project root found at: /Users/jjsicot/Documents/workspaces/data-science-python/demo/search/es_api
2020-02-18 21:51:33,866 (DEBUG) ebcli.core.fileoperations : Project root found at: /Users/jjsicot/Documents/workspaces/data-science-python/demo/search/es_api
2020-02-18 21:51:33,868 (DEBUG) ebcli.core.fileoperations : Project root found at: /Users/jjsicot/Documents/workspaces/data-science-python/demo/search/es_api
2020-02-18 21:51:33,871 (DEBUG) ebcli.core.fileoperations : Project root found at: /Users/jjsicot/Documents/workspaces/data-science-python/demo/search/es_api
2020-02-18 21:51:33,874 (DEBUG) ebcli.core.fileoperations : Project root found at: /Users/jjsicot/Documents/workspaces/data-science-python/demo/search/es_api
2020-02-18 21:51:33,876 (DEBUG) ebcli.lib.elasticbeanstalk : Inside describe_configuration_settings api wrapper
2020-02-18 21:51:33,876 (DEBUG) ebcli.lib.aws : Creating new Botocore Session
2020-02-18 21:51:33,876 (DEBUG) ebcli.lib.aws : Botocore version: 1.13.34
2020-02-18 21:51:33,889 (DEBUG) ebcli.lib.aws : Creating new Botocore Client for elasticbeanstalk
2020-02-18 21:51:33,936 (INFO) eb : Traceback (most recent call last):
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/core/ebrun.py", line 62, in run_app
app.run()
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/cement/core/foundation.py", line 797, in run
return_val = self.controller._dispatch()
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/cement/core/controller.py", line 472, in _dispatch
return func()
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/cement/core/controller.py", line 478, in _dispatch
return func()
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/core/abstractcontroller.py", line 91, in default
self.do_command()
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/controllers/health.py", line 41, in do_command
healthops.display_interactive_health(app_name, env_name, refresh,
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/operations/healthops.py", line 39, in display_interactive_health
env = elasticbeanstalk.describe_configuration_settings(app_name, env_name)
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/lib/elasticbeanstalk.py", line 341, in describe_configuration_settings
result = _make_api_call('describe_configuration_settings',
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/lib/elasticbeanstalk.py", line 37, in _make_api_call
return aws.make_api_call('elasticbeanstalk',
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/lib/aws.py", line 194, in make_api_call
operation = _set_operation(service_name, operation_name)
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/lib/aws.py", line 311, in _set_operation
client = _get_client(service_name)
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/ebcli/lib/aws.py", line 147, in _get_client
client = session.create_client(service_name,
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/botocore/session.py", line 823, in create_client
credentials = self.get_credentials()
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/botocore/session.py", line 427, in get_credentials
self._credentials = self._components.get_component(
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/botocore/credentials.py", line 1948, in load_credentials
creds = provider.load()
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/botocore/credentials.py", line 1381, in load
return self._load_creds_via_assume_role(self._profile_name)
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/botocore/credentials.py", line 1395, in _load_creds_via_assume_role
source_credentials = self._resolve_source_credentials(
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/botocore/credentials.py", line 1557, in _resolve_source_credentials
return self._resolve_credentials_from_profile(source_profile)
File "/usr/local/Cellar/aws-elasticbeanstalk/3.17.0/libexec/lib/python3.8/site-packages/botocore/credentials.py", line 1582, in _resolve_credentials_from_profile
raise InvalidConfigError(
botocore.exceptions.InvalidConfigError: The source profile "datasci" must have credentials.

Expected result

The health status to be returned. If the same profile is provided to the aws2 command it seems to resolve the credentials properly and commands such as "s3 ls" work just fine.

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: OS X 10.14
ChaseAllbee commented 4 years ago

Hey Jason,

First, thanks for reaching out about this. This would be a valuable addition to the ebcli.

It appears that currently aws2 is storing the cache of sso tokens in ~/.aws/sso/cache, which is a place the ebcli currently is not checking for any sort of credentials. So, as an expanded feature we could check this location as well so we're at parity with v2 of the awscli. This would likely be part of a larger push to support more features that the awscli will support in v2 anyway.

Thanks again!

tehnrd commented 4 years ago

Open to a PR on this?

This sounds like it would be an easy fix (famous last words). Does anyone know where in the code it looks up the credentials to save some time tracking that down?

urz9999 commented 3 years ago

In case like this one or other similar cases where AWS SSO result in incompatibilities with your library and you don't want to play with workarounds or complicated fixes, maybe you can give a try to our open-source project: https://github.com/Noovolari/leapp. It deals with AWS SSO authentication and accounts/roles retrieval then it creates short-lived temporary credentials in .aws/credentials to maximize compatibility with third party tools / sdks.