cevoaustralia / aws-google-auth

Provides AWS STS credentials based on Google Apps SAML SSO auth (what a jumble!)
MIT License
537 stars 181 forks source link

botocore.exceptions.ProfileNotFound: The config profile (xxx-xxx) could not be found #95

Closed max-rocket-internet closed 5 years ago

max-rocket-internet commented 6 years ago

I get this sometimes:

$ aws-google-auth --idp-id qqqqqqqq --sp-id 123456879 --username user@domain.com --duration 43200 --role-arn arn:aws:iam::6666666666:role/sso/sso-administrator --profile xxx-xxx --keyring
Failed to import U2F libraries, U2F login unavailable. Other methods can still continue.
Open the Google App, and tap 'Yes' on the prompt to sign in ...
Assuming arn:aws:iam::6666666666:role/sso/sso-administrator
Traceback (most recent call last):
  File "/usr/local/bin/aws-google-auth", line 11, in <module>
    sys.exit(main())
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/__init__.py", line 226, in main
    cli(cli_args)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/__init__.py", line 65, in cli
    process_auth(args, config)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/__init__.py", line 216, in process_auth
    print("Credentials Expiration: " + format(amazon_client.expiration.astimezone(get_localzone())))
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/amazon.py", line 50, in expiration
    return self.token['Credentials']['Expiration']
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/amazon.py", line 29, in token
    self.__token = self.sts_client.assume_role_with_saml(
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/amazon.py", line 20, in sts_client
    return boto3.client('sts', region_name=self.config.region)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/__init__.py", line 91, in client
    return _get_default_session().client(*args, **kwargs)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/__init__.py", line 80, in _get_default_session
    setup_default_session()
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/__init__.py", line 34, in setup_default_session
    DEFAULT_SESSION = Session(**kwargs)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/session.py", line 80, in __init__
    self._setup_loader()
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/session.py", line 120, in _setup_loader
    self._loader = self._session.get_component('data_loader')
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 729, in get_component
    return self._components.get_component(name)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 946, in get_component
    self._components[name] = factory()
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 186, in <lambda>
    lambda:  create_loader(self.get_config_variable('data_path')))
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 281, in get_config_variable
    elif self._found_in_config_file(methods, var_config):
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 308, in _found_in_config_file
    return var_config[0] in self.get_scoped_config()
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 385, in get_scoped_config
    raise ProfileNotFound(profile=profile_name)
botocore.exceptions.ProfileNotFound: The config profile (xxx-xxxx) could not be found
max-rocket-internet commented 6 years ago

My profile env var is set like AWS_PROFILE=xxx-xxxx. So is this problem that boto is reading this but failing because aws-google-auth didn't complete yet in order to set that profile up? Kind of chicken/egg or really I should wait until aws-google-auth has run before setting the AWS_PROFILE env var?

stevemac007 commented 6 years ago

I've seen this chicken/egg problem myself, to get around this I setup bash alias' as follows:

alias aws-cevo-demo='unset AWS_PROFILE; aws-google-auth -k -p cevo-demo; export AWS_PROFILE=cevo-demo'
alias aws-cevo-dev='unset AWS_PROFILE; aws-google-auth -k -p cevo-dev; export AWS_PROFILE=cevo-dev'

This way auth is always launched from the default profile, and then once aws-google-auth has finished, it is set to the newly auth'd profile.

max-rocket-internet commented 6 years ago

That's fine but aws-google-auth should return a nice, informative error without the Traceback 🙂

stevemac007 commented 6 years ago

+1 on the nicer error..

I'd also like to see if we can get around the issue too - might be able to override the ENV for aws-google-auth during the auth stage as we manage the config profile ourselves now..

stevemac007 commented 6 years ago

Trying to capture this exception and make it fail nicer, but I can't get that error. My boto3/botocore versions don't seem to match up. What versions are you running this with?

I've developing against:

boto3==1.4.8
botocore==1.8.8

These look a little old, so behaviour might have changed in recent versions.

max-rocket-internet commented 6 years ago

Hey Steve, Here's what I got:

$ pip3 list | grep boto
boto3 (1.7.8)
botocore (1.10.8)

So yes, yours looks very old.

I can reproduce this easily:

export AWS_PROFILE=does-not-exist
aws-google-auth --role-arn arn:aws:iam::....

Failed to import U2F libraries, U2F login unavailable. Other methods can still continue.
Open the Google App, and tap 'Yes' on the prompt to sign in ...
Assuming arn:aws:iam::9999999999:role/sso/sso-xxxxx
Traceback (most recent call last):
  File "/usr/local/bin/aws-google-auth", line 11, in <module>
    sys.exit(main())
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/__init__.py", line 225, in main
    cli(cli_args)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/__init__.py", line 64, in cli
    process_auth(args, config)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/__init__.py", line 215, in process_auth
    print("Credentials Expiration: " + format(amazon_client.expiration.astimezone(get_localzone())))
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/amazon.py", line 50, in expiration
    return self.token['Credentials']['Expiration']
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/amazon.py", line 29, in token
    self.__token = self.sts_client.assume_role_with_saml(
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/aws_google_auth/amazon.py", line 20, in sts_client
    return boto3.client('sts', region_name=self.config.region)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/__init__.py", line 91, in client
    return _get_default_session().client(*args, **kwargs)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/__init__.py", line 80, in _get_default_session
    setup_default_session()
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/__init__.py", line 34, in setup_default_session
    DEFAULT_SESSION = Session(**kwargs)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/session.py", line 80, in __init__
    self._setup_loader()
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/boto3/session.py", line 120, in _setup_loader
    self._loader = self._session.get_component('data_loader')
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 729, in get_component
    return self._components.get_component(name)
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 946, in get_component
    self._components[name] = factory()
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 186, in <lambda>
    lambda:  create_loader(self.get_config_variable('data_path')))
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 281, in get_config_variable
    elif self._found_in_config_file(methods, var_config):
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 308, in _found_in_config_file
    return var_config[0] in self.get_scoped_config()
  File "/Users/max.williams/Library/Python/3.6/lib/python/site-packages/botocore/session.py", line 385, in get_scoped_config
    raise ProfileNotFound(profile=profile_name)
botocore.exceptions.ProfileNotFound: The config profile (does-not-exist) could not be found
max-rocket-internet commented 6 years ago

If it's any consolation, the AWS CLI doesn't handle it either:

$ aws s3 ls
Traceback (most recent call last):
  File "/usr/local/bin/aws", line 27, in <module>
    sys.exit(main())
  File "/usr/local/bin/aws", line 23, in main
    return awscli.clidriver.main()
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/awscli/clidriver.py", line 59, in main
    rc = driver.main()
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/awscli/clidriver.py", line 194, in main
    command_table = self._get_command_table()
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/awscli/clidriver.py", line 103, in _get_command_table
    self._command_table = self._build_command_table()
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/awscli/clidriver.py", line 123, in _build_command_table
    command_object=self)
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/botocore/session.py", line 719, in emit
    return self._events.emit(event_name, **kwargs)
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/botocore/hooks.py", line 227, in emit
    return self._emit(event_name, kwargs)
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/botocore/hooks.py", line 210, in _emit
    response = handler(**kwargs)
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/awscli/customizations/preview.py", line 69, in mark_as_preview
    service_name=original_command.service_model.service_name,
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/awscli/clidriver.py", line 315, in service_model
    return self._get_service_model()
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/awscli/clidriver.py", line 332, in _get_service_model
    api_version = self.session.get_config_variable('api_versions').get(
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/botocore/session.py", line 279, in get_config_variable
    elif self._found_in_config_file(methods, var_config):
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/botocore/session.py", line 306, in _found_in_config_file
    return var_config[0] in self.get_scoped_config()
  File "/usr/local/Cellar/awscli/1.14.50/libexec/lib/python3.6/site-packages/botocore/session.py", line 383, in get_scoped_config
    raise ProfileNotFound(profile=profile_name)
botocore.exceptions.ProfileNotFound: The config profile (does-not-exist) could not be found

😁

stevemac007 commented 5 years ago

This has been improved, shouldn't get a crazy error any more.