diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4a1434a2061f..a1de4f7e2a2f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,14 +5,14 @@ CHANGELOG Next Release (TBD) ================== -* feature:Page Size: Add a ``--page-size`` option, that +* feature:Page Size: Add a ``--page-size`` option, that controls page size when perfoming an operation that uses pagination. (`issue 889 `__) * bugfix:``aws s3``: Added support for ignoring and warning about files that do not exist, user does not have read permissions, or are special files (i.e. sockets, FIFOs, - character special devices, and block special devices) + character special devices, and block special devices) (`issue 881 `__) * feature:Parameter Shorthand: Added support for ``structure(list-scalar, scalar)`` parameter shorthand. @@ -20,6 +20,9 @@ Next Release (TBD) * bugfix:``aws s3``: Fix bug when unknown options were passed to ``aws s3`` commands (`issue 886 `__) +* bugfix:Endpoint URL: Provide a better error message when + an invalid ``--endpoint-url`` is provided + (`issue 899 `__) 1.4.2 diff --git a/awscli/compat.py b/awscli/compat.py index a664d8ea7891..5951a75e4aa2 100644 --- a/awscli/compat.py +++ b/awscli/compat.py @@ -15,6 +15,7 @@ if six.PY3: import locale + import urllib.parse as urlparse def get_stdout_text_writer(): return sys.stdout @@ -38,6 +39,7 @@ def compat_open(filename, mode='r', encoding=None): import codecs import locale import io + import urlparse def get_stdout_text_writer(): # In python3, all the sys.stdout/sys.stderr streams are in text diff --git a/awscli/customizations/globalargs.py b/awscli/customizations/globalargs.py index fc01f066c0e0..0acd0b80a659 100644 --- a/awscli/customizations/globalargs.py +++ b/awscli/customizations/globalargs.py @@ -15,6 +15,8 @@ import jmespath +from awscli.compat import urlparse + def register_parse_global_args(cli): cli.register('top-level-args-parsed', resolve_types) @@ -26,6 +28,7 @@ def resolve_types(parsed_args, **kwargs): # that plugins can also hook into this process. _resolve_arg(parsed_args, 'query') _resolve_arg(parsed_args, 'verify_ssl') + _resolve_arg(parsed_args, 'endpoint_url') def _resolve_arg(parsed_args, name): @@ -51,6 +54,17 @@ def _resolve_verify_ssl(value): return verify +def _resolve_endpoint_url(value): + parsed = urlparse.urlparse(value) + # Our http library requires you specify an endpoint url + # that contains a scheme, so we'll verify that up front. + if not parsed.scheme: + raise ValueError('Bad value for --endpoint-url "%s": scheme is ' + 'missing. Must be of the form ' + 'http:/// or https:///' % value) + return value + + def no_sign_request(parsed_args, session, **kwargs): if not parsed_args.sign_request: # In order to make signing disabled for all requests diff --git a/tests/unit/customizations/test_globalargs.py b/tests/unit/customizations/test_globalargs.py index 8b4c6fd6c9d9..f31bafc174e9 100644 --- a/tests/unit/customizations/test_globalargs.py +++ b/tests/unit/customizations/test_globalargs.py @@ -82,3 +82,15 @@ def test_disable_signing(self): service.signature_version = 'v4' globalargs.disable_signing(service) service.signature_version = None + + def test_invalid_endpoint_url(self): + # Invalid jmespath expression. + parsed_args = FakeParsedArgs(endpoint_url='missing-scheme.com') + with self.assertRaises(ValueError): + globalargs.resolve_types(parsed_args) + + def test_valid_endpoint_url(self): + parsed_args = FakeParsedArgs(endpoint_url='http://custom-endpoint.com') + globalargs.resolve_types(parsed_args) + self.assertEqual(parsed_args.endpoint_url, + 'http://custom-endpoint.com')