diff options
-rw-r--r-- | os_client_config/config.py | 32 | ||||
-rw-r--r-- | os_client_config/tests/test_config.py | 31 |
2 files changed, 63 insertions, 0 deletions
diff --git a/os_client_config/config.py b/os_client_config/config.py index 48bcb0f..077c109 100644 --- a/os_client_config/config.py +++ b/os_client_config/config.py @@ -15,6 +15,7 @@ # alias because we already had an option named argparse import argparse as argparse_mod +import collections import copy import json import os @@ -136,6 +137,34 @@ def _auth_update(old_dict, new_dict_source): return old_dict +def _fix_argv(argv): + # Transform any _ characters in arg names to - so that we don't + # have to throw billions of compat argparse arguments around all + # over the place. + processed = collections.defaultdict(list) + for index in range(0, len(argv)): + if argv[index].startswith('--'): + split_args = argv[index].split('=') + orig = split_args[0] + new = orig.replace('_', '-') + if orig != new: + split_args[0] = new + argv[index] = "=".join(split_args) + # Save both for later so we can throw an error about dupes + processed[new].append(orig) + overlap = [] + for new, old in processed.items(): + if len(old) > 1: + overlap.extend(old) + if overlap: + raise exceptions.OpenStackConfigException( + "The following options were given: '{options}' which contain" + " duplicates except that one has _ and one has -. There is" + " no sane way for us to know what you're doing. Remove the" + " duplicate option and try again".format( + options=','.join(overlap))) + + class OpenStackConfig(object): def __init__(self, config_files=None, vendor_files=None, @@ -521,6 +550,9 @@ class OpenStackConfig(object): is requested """ + # Fix argv in place - mapping any keys with embedded _ in them to - + _fix_argv(argv) + local_parser = argparse_mod.ArgumentParser(add_help=False) for p in (parser, local_parser): diff --git a/os_client_config/tests/test_config.py b/os_client_config/tests/test_config.py index bb45693..30ed731 100644 --- a/os_client_config/tests/test_config.py +++ b/os_client_config/tests/test_config.py @@ -431,6 +431,37 @@ class TestConfigArgparse(base.TestCase): self.assertEqual(cc.config['auth_type'], 'token') self.assertEqual(cc.config['auth']['token'], 'very-bad-things') + def test_argparse_underscores(self): + c = config.OpenStackConfig(config_files=[self.no_yaml], + vendor_files=[self.no_yaml], + secure_files=[self.no_yaml]) + parser = argparse.ArgumentParser() + parser.add_argument('--os_username') + argv = [ + '--os_username', 'user', '--os_password', 'pass', + '--os-auth-url', 'auth-url', '--os-project-name', 'project'] + c.register_argparse_arguments(parser, argv=argv) + opts, _remain = parser.parse_known_args(argv) + cc = c.get_one_cloud(argparse=opts) + self.assertEqual(cc.config['auth']['username'], 'user') + self.assertEqual(cc.config['auth']['password'], 'pass') + self.assertEqual(cc.config['auth']['auth_url'], 'auth-url') + + def test_argparse_underscores_duplicate(self): + c = config.OpenStackConfig(config_files=[self.no_yaml], + vendor_files=[self.no_yaml], + secure_files=[self.no_yaml]) + parser = argparse.ArgumentParser() + parser.add_argument('--os_username') + argv = [ + '--os_username', 'user', '--os_password', 'pass', + '--os-username', 'user1', '--os-password', 'pass1', + '--os-auth-url', 'auth-url', '--os-project-name', 'project'] + self.assertRaises( + exceptions.OpenStackConfigException, + c.register_argparse_arguments, + parser=parser, argv=argv) + def test_register_argparse_bad_plugin(self): c = config.OpenStackConfig(config_files=[self.cloud_yaml], vendor_files=[self.vendor_yaml]) |