summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--os_client_config/config.py32
-rw-r--r--os_client_config/tests/test_config.py31
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])