Rework shell and tests

* break up initialize_app() so subclasses can easily insert into the flow
* remove all handling for verify/insecure
This commit is contained in:
Dean Troyer 2016-05-13 12:28:08 -05:00
parent ec4b38faf9
commit 2f1539bdaf
2 changed files with 307 additions and 213 deletions

View File

@ -76,7 +76,17 @@ class OpenStackShell(app.App):
log = logging.getLogger(__name__)
timing_data = []
def __init__(self):
def __init__(
self,
description=None,
version=None,
command_manager=None,
stdin=None,
stdout=None,
stderr=None,
interactive_app_factory=None,
deferred_help=False,
):
# Patch command.Command to add a default auth_required = True
command.Command.auth_required = True
@ -88,21 +98,24 @@ class OpenStackShell(app.App):
self.DEFAULT_DEBUG_VALUE = None
self.DEFAULT_DEBUG_HELP = 'Set debug logging and traceback on errors.'
# Do default for positionals
if not command_manager:
cm = commandmanager.CommandManager('openstack.cli')
else:
command_manager
super(OpenStackShell, self).__init__(
description=__doc__.strip(),
version=None,
# version=openstackclient.__version__,
command_manager=commandmanager.CommandManager('openstack.cli'),
version=version,
command_manager=cm,
deferred_help=True,
)
self.api_version = {}
# Until we have command line arguments parsed, dump any stack traces
self.dump_stack_trace = True
# Assume TLS host certificate verification is enabled
self.verify = True
# Set in subclasses
self.api_version = None
self.client_manager = None
self.command_options = None
@ -200,7 +213,7 @@ class OpenStackShell(app.App):
'--os-cacert',
metavar='<ca-bundle-file>',
dest='cacert',
default=utils.env('OS_CACERT'),
default=utils.env('OS_CACERT', default=None),
help='CA certificate bundle file (Env: OS_CACERT)')
parser.add_argument(
'--os-cert',
@ -274,28 +287,26 @@ class OpenStackShell(app.App):
return clientmanager.build_plugin_option_parser(parser)
def initialize_app(self, argv):
"""Global app init bits:
"""
Break up initialize_app() so that overriding it in a subclass does not
require duplicating a lot of the method
* set up API versions
* validate authentication info
* authenticate against Identity if requested
"""
* super()
* _final_defaults()
* OpenStackConfig
* get_one_cloud
* _load_plugins()
* _load_commands()
* ClientManager
# Parent __init__ parses argv into self.options
super(OpenStackShell, self).initialize_app(argv)
self.log.info("START with options: %s",
strutils.mask_password(self.command_options))
self.log.debug("options: %s",
strutils.mask_password(self.options))
# Set the default plugin to token_endpoint if url and token are given
if (self.options.url and self.options.token):
# Use service token authentication
auth_type = 'token_endpoint'
else:
auth_type = 'password'
"""
def _final_defaults(self):
# Set the default plugin to None
# NOTE(dtroyer): This is here to set up for setting it to a default
# in the calling CLI
self._auth_type = None
# Converge project/tenant options
project_id = getattr(self.options, 'project_id', None)
project_name = getattr(self.options, 'project_name', None)
tenant_id = getattr(self.options, 'tenant_id', None)
@ -313,6 +324,41 @@ class OpenStackShell(app.App):
if tenant_name and not project_name:
self.options.project_name = tenant_name
# Save default domain
self.default_domain = self.options.default_domain
def _load_plugins(self):
"""Load plugins via stevedore
osc-lib has no opinion on what plugins should be loaded
"""
pass
def _load_commands(self):
"""Load commands via cliff/stevedore
osc-lib has no opinion on what commands should be loaded
"""
pass
def initialize_app(self, argv):
"""Global app init bits:
* set up API versions
* validate authentication info
* authenticate against Identity if requested
"""
# Parent __init__ parses argv into self.options
super(OpenStackShell, self).initialize_app(argv)
self.log.info("START with options: %s",
strutils.mask_password(self.command_options))
self.log.debug("options: %s",
strutils.mask_password(self.options))
# Callout for stuff between superclass init and o-c-c
self._final_defaults()
# Do configuration file handling
# Ignore the default value of interface. Only if it is set later
# will it be used.
@ -320,7 +366,7 @@ class OpenStackShell(app.App):
cc = cloud_config.OpenStackConfig(
override_defaults={
'interface': None,
'auth_type': auth_type,
'auth_type': self._auth_type,
},
)
except (IOError, OSError) as e:
@ -343,85 +389,18 @@ class OpenStackShell(app.App):
self.log.debug("cloud cfg: %s",
strutils.mask_password(self.cloud.config))
# Set up client TLS
# NOTE(dtroyer): --insecure is the non-default condition that
# overrides any verify setting in clouds.yaml
# so check it first, then fall back to any verify
# setting provided.
self.verify = not self.cloud.config.get(
'insecure',
not self.cloud.config.get('verify', True),
)
# Callout for stuff between o-c-c and ClientManager
# self._initialize_app_2(self.options)
# NOTE(dtroyer): Per bug https://bugs.launchpad.net/bugs/1447784
# --insecure now overrides any --os-cacert setting,
# where before --insecure was ignored if --os-cacert
# was set.
if self.verify and self.cloud.cacert:
self.verify = self.cloud.cacert
self._load_plugins()
# Save default domain
self.default_domain = self.options.default_domain
# Loop through extensions to get API versions
for mod in clientmanager.PLUGIN_MODULES:
default_version = getattr(mod, 'DEFAULT_API_VERSION', None)
option = mod.API_VERSION_OPTION.replace('os_', '')
version_opt = str(self.cloud.config.get(option, default_version))
if version_opt:
api = mod.API_NAME
self.api_version[api] = version_opt
# Add a plugin interface to let the module validate the version
# requested by the user
skip_old_check = False
mod_check_api_version = getattr(mod, 'check_api_version', None)
if mod_check_api_version:
# this throws an exception if invalid
skip_old_check = mod_check_api_version(version_opt)
mod_versions = getattr(mod, 'API_VERSIONS', None)
if not skip_old_check and mod_versions:
if version_opt not in mod_versions:
self.log.warning(
"%s version %s is not in supported versions %s"
% (api, version_opt,
', '.join(list(mod.API_VERSIONS.keys()))))
# Command groups deal only with major versions
version = '.v' + version_opt.replace('.', '_').split('_')[0]
cmd_group = 'openstack.' + api.replace('-', '_') + version
self.command_manager.add_command_group(cmd_group)
self.log.debug(
'%(name)s API version %(version)s, cmd group %(group)s',
{'name': api, 'version': version_opt, 'group': cmd_group}
)
# Commands that span multiple APIs
self.command_manager.add_command_group(
'openstack.common')
# This is the naive extension implementation referred to in
# blueprint 'client-extensions'
# Extension modules can register their commands in an
# 'openstack.extension' entry point group:
# entry_points={
# 'openstack.extension': [
# 'list_repo=qaz.github.repo:ListRepo',
# 'show_repo=qaz.github.repo:ShowRepo',
# ],
# }
self.command_manager.add_command_group(
'openstack.extension')
# call InitializeXxx() here
# set up additional clients to stuff in to client_manager??
self._load_commands()
# Handle deferred help and exit
self.print_help_if_requested()
self.client_manager = clientmanager.ClientManager(
cli_options=self.cloud,
verify=self.verify,
api_version=self.api_version,
pw_func=prompt_for_password,
)

View File

@ -62,7 +62,7 @@ CLOUD_1 = {
'project_name': DEFAULT_PROJECT_NAME,
'username': 'zaphod',
},
'region_name': 'occ-cloud',
'region_name': 'occ-cloud,krikkit',
'donut': 'glazed',
'interface': 'public',
}
@ -135,6 +135,7 @@ def make_shell():
"""Create a new command shell and mock out some bits."""
_shell = shell.OpenStackShell()
_shell.command_manager = mock.Mock()
_shell.cloud = mock.Mock()
return _shell
@ -171,49 +172,6 @@ class TestShell(utils.TestCase):
self.addCleanup(self.cmd_patch.stop)
self.app = mock.Mock("Test Shell")
def _assert_initialize_app_arg(self, cmd_options, default_args):
"""Check the args passed to initialize_app()
The argv argument to initialize_app() is the remainder from parsing
global options declared in both cliff.app and
osc_lib.OpenStackShell build_option_parser(). Any global
options passed on the commmad line should not be in argv but in
_shell.options.
"""
with mock.patch(
"osc_lib.shell.OpenStackShell.initialize_app",
self.app,
):
_shell, _cmd = make_shell(), cmd_options + " list project"
fake_execute(_shell, _cmd)
self.app.assert_called_with(["list", "project"])
for k in default_args.keys():
self.assertEqual(
default_args[k],
vars(_shell.options)[k],
"%s does not match" % k,
)
def _assert_cli(self, cmd_options, default_args):
with mock.patch("osc_lib.shell.OpenStackShell.initialize_app",
self.app):
_shell, _cmd = make_shell(), cmd_options + " list server"
fake_execute(_shell, _cmd)
self.app.assert_called_with(["list", "server"])
self.assertEqual(default_args["compute_api_version"],
_shell.options.os_compute_api_version)
self.assertEqual(default_args["identity_api_version"],
_shell.options.os_identity_api_version)
self.assertEqual(default_args["image_api_version"],
_shell.options.os_image_api_version)
self.assertEqual(default_args["volume_api_version"],
_shell.options.os_volume_api_version)
self.assertEqual(default_args["network_api_version"],
_shell.options.os_network_api_version)
class TestShellHelp(TestShell):
"""Test the deferred help flag"""
@ -228,22 +186,84 @@ class TestShellHelp(TestShell):
kwargs = {
"deferred_help": True,
}
with mock.patch("osc_lib.shell.OpenStackShell.initialize_app",
self.app):
with mock.patch(
"osc_lib.shell.OpenStackShell.initialize_app",
self.app,
):
_shell, _cmd = make_shell(), flag
fake_execute(_shell, _cmd)
self.assertEqual(kwargs["deferred_help"],
_shell.options.deferred_help)
self.assertEqual(
kwargs["deferred_help"],
_shell.options.deferred_help,
)
class TestShellOptions(TestShell):
"""Test the option handling by argparse and os_client_config
This covers getting the CLI options through the initial processing
and validates the arguments to initialize_app() and occ_get_one()
"""
def setUp(self):
super(TestShellOptions, self).setUp()
self.useFixture(EnvFixture())
def _assert_initialize_app_arg(self, cmd_options, default_args):
"""Check the args passed to initialize_app()
The argv argument to initialize_app() is the remainder from parsing
global options declared in both cliff.app and
osc_lib.OpenStackShell build_option_parser(). Any global
options passed on the command line should not be in argv but in
_shell.options.
"""
with mock.patch(
"osc_lib.shell.OpenStackShell.initialize_app",
self.app,
):
_shell, _cmd = make_shell(), cmd_options + " module list"
fake_execute(_shell, _cmd)
self.app.assert_called_with(["module", "list"])
for k in default_args.keys():
self.assertEqual(
default_args[k],
vars(_shell.options)[k],
"%s does not match" % k,
)
def _assert_cloud_config_arg(self, cmd_options, default_args):
"""Check the args passed to cloud_config.get_one_cloud()
The argparse argument to get_one_cloud() is an argparse.Namespace
object that contains all of the options processed to this point in
initialize_app().
"""
cloud = mock.Mock(name="cloudy")
cloud.config = {}
self.occ_get_one = mock.Mock(return_value=cloud)
with mock.patch(
"os_client_config.config.OpenStackConfig.get_one_cloud",
self.occ_get_one,
):
_shell, _cmd = make_shell(), cmd_options + " module list"
fake_execute(_shell, _cmd)
self.app.assert_called_with(["module", "list"])
opts = self.occ_get_one.call_args[1]['argparse']
for k in default_args.keys():
self.assertEqual(
default_args[k],
vars(opts)[k],
"%s does not match" % k,
)
def _test_options_init_app(self, test_opts):
"""Test options on the command line"""
for opt in test_opts.keys():
if not test_opts[opt][1]:
continue
@ -258,6 +278,7 @@ class TestShellOptions(TestShell):
self._assert_initialize_app_arg(cmd, kwargs)
def _test_env_init_app(self, test_opts):
"""Test options in the environment"""
for opt in test_opts.keys():
if not test_opts[opt][2]:
continue
@ -271,7 +292,23 @@ class TestShellOptions(TestShell):
os.environ = env.copy()
self._assert_initialize_app_arg("", kwargs)
def _test_options_get_one_cloud(self, test_opts):
"""Test options sent "to os_client_config"""
for opt in test_opts.keys():
if not test_opts[opt][1]:
continue
key = opt2attr(opt)
if isinstance(test_opts[opt][0], str):
cmd = opt + " " + test_opts[opt][0]
else:
cmd = opt
kwargs = {
key: test_opts[opt][0],
}
self._assert_cloud_config_arg(cmd, kwargs)
def _test_env_get_one_cloud(self, test_opts):
"""Test environment options sent "to os_client_config"""
for opt in test_opts.keys():
if not test_opts[opt][2]:
continue
@ -285,134 +322,132 @@ class TestShellOptions(TestShell):
os.environ = env.copy()
self._assert_cloud_config_arg("", kwargs)
def test_empty_auth(self):
def test_no_options(self):
os.environ = {}
self._assert_initialize_app_arg("", {})
self._assert_cloud_config_arg("", {})
def test_global_options(self):
self._test_options_init_app(global_options)
self._test_options_get_one_cloud(global_options)
def test_global_env(self):
self._test_env_init_app(global_options)
self._test_env_get_one_cloud(global_options)
class TestShellCli(TestShell):
"""Test handling of specific global options
_shell.options is the parsed command line from argparse
_shell.client_manager.* are the values actually used
"""
def setUp(self):
super(TestShellCli, self).setUp()
env = {
"OS_COMPUTE_API_VERSION": DEFAULT_COMPUTE_API_VERSION,
"OS_IDENTITY_API_VERSION": DEFAULT_IDENTITY_API_VERSION,
"OS_IMAGE_API_VERSION": DEFAULT_IMAGE_API_VERSION,
"OS_VOLUME_API_VERSION": DEFAULT_VOLUME_API_VERSION,
"OS_NETWORK_API_VERSION": DEFAULT_NETWORK_API_VERSION,
# "OS_COMPUTE_API_VERSION": DEFAULT_COMPUTE_API_VERSION,
# "OS_IDENTITY_API_VERSION": DEFAULT_IDENTITY_API_VERSION,
# "OS_IMAGE_API_VERSION": DEFAULT_IMAGE_API_VERSION,
# "OS_VOLUME_API_VERSION": DEFAULT_VOLUME_API_VERSION,
# "OS_NETWORK_API_VERSION": DEFAULT_NETWORK_API_VERSION,
}
self.useFixture(EnvFixture(env.copy()))
def test_shell_args_no_options(self):
def test_shell_args_tls_options(self):
"""Test the TLS verify and CA cert file options"""
_shell = make_shell()
with mock.patch("osc_lib.shell.OpenStackShell.initialize_app",
self.app):
fake_execute(_shell, "list user")
self.app.assert_called_with(["list", "user"])
def test_shell_args_ca_options(self):
_shell = make_shell()
# NOTE(dtroyer): The commented out asserts below are the desired
# behaviour and will be uncommented when the
# handling for --verify and --insecure is fixed.
# Default
fake_execute(_shell, "list user")
fake_execute(_shell, "module list")
self.assertIsNone(_shell.options.verify)
self.assertIsNone(_shell.options.insecure)
self.assertEqual('', _shell.options.cacert)
self.assertTrue(_shell.verify)
self.assertIsNone(_shell.options.cacert)
self.assertTrue(_shell.client_manager.verify)
self.assertIsNone(_shell.client_manager.cacert)
# --verify
fake_execute(_shell, "--verify list user")
fake_execute(_shell, "--verify module list")
self.assertTrue(_shell.options.verify)
self.assertIsNone(_shell.options.insecure)
self.assertEqual('', _shell.options.cacert)
self.assertTrue(_shell.verify)
self.assertIsNone(_shell.options.cacert)
self.assertTrue(_shell.client_manager.verify)
self.assertIsNone(_shell.client_manager.cacert)
# --insecure
fake_execute(_shell, "--insecure list user")
fake_execute(_shell, "--insecure module list")
self.assertIsNone(_shell.options.verify)
self.assertTrue(_shell.options.insecure)
self.assertEqual('', _shell.options.cacert)
self.assertFalse(_shell.verify)
self.assertIsNone(_shell.options.cacert)
self.assertFalse(_shell.client_manager.verify)
self.assertIsNone(_shell.client_manager.cacert)
# --os-cacert
fake_execute(_shell, "--os-cacert foo list user")
fake_execute(_shell, "--os-cacert foo module list")
self.assertIsNone(_shell.options.verify)
self.assertIsNone(_shell.options.insecure)
self.assertEqual('foo', _shell.options.cacert)
self.assertTrue(_shell.verify)
self.assertEqual('foo', _shell.client_manager.verify)
self.assertEqual('foo', _shell.client_manager.cacert)
# --os-cacert and --verify
fake_execute(_shell, "--os-cacert foo --verify list user")
fake_execute(_shell, "--os-cacert foo --verify module list")
self.assertTrue(_shell.options.verify)
self.assertIsNone(_shell.options.insecure)
self.assertEqual('foo', _shell.options.cacert)
self.assertTrue(_shell.verify)
self.assertEqual('foo', _shell.client_manager.verify)
self.assertEqual('foo', _shell.client_manager.cacert)
# --os-cacert and --insecure
# NOTE(dtroyer): Per bug https://bugs.launchpad.net/bugs/1447784
# in this combination --insecure now overrides any
# --os-cacert setting, where before --insecure
# was ignored if --os-cacert was set.
fake_execute(_shell, "--os-cacert foo --insecure list user")
fake_execute(_shell, "--os-cacert foo --insecure module list")
self.assertIsNone(_shell.options.verify)
self.assertTrue(_shell.options.insecure)
self.assertEqual('foo', _shell.options.cacert)
self.assertFalse(_shell.verify)
self.assertFalse(_shell.client_manager.verify)
self.assertIsNone(_shell.client_manager.cacert)
def test_shell_args_cert_options(self):
"""Test client cert options"""
_shell = make_shell()
# Default
fake_execute(_shell, "list user")
fake_execute(_shell, "module list")
self.assertEqual('', _shell.options.cert)
self.assertEqual('', _shell.options.key)
self.assertIsNone(_shell.client_manager.cert)
# --os-cert
fake_execute(_shell, "--os-cert mycert list user")
fake_execute(_shell, "--os-cert mycert module list")
self.assertEqual('mycert', _shell.options.cert)
self.assertEqual('', _shell.options.key)
self.assertEqual('mycert', _shell.client_manager.cert)
# --os-key
fake_execute(_shell, "--os-key mickey list user")
fake_execute(_shell, "--os-key mickey module list")
self.assertEqual('', _shell.options.cert)
self.assertEqual('mickey', _shell.options.key)
self.assertIsNone(_shell.client_manager.cert)
def test_default_env(self):
flag = ""
kwargs = {
"compute_api_version": DEFAULT_COMPUTE_API_VERSION,
"identity_api_version": DEFAULT_IDENTITY_API_VERSION,
"image_api_version": DEFAULT_IMAGE_API_VERSION,
"volume_api_version": DEFAULT_VOLUME_API_VERSION,
"network_api_version": DEFAULT_NETWORK_API_VERSION,
}
self._assert_cli(flag, kwargs)
def test_empty_env(self):
os.environ = {}
flag = ""
kwargs = {
"compute_api_version": LIB_COMPUTE_API_VERSION,
"identity_api_version": LIB_IDENTITY_API_VERSION,
"image_api_version": LIB_IMAGE_API_VERSION,
"volume_api_version": LIB_VOLUME_API_VERSION,
"network_api_version": LIB_NETWORK_API_VERSION
}
self._assert_cli(flag, kwargs)
# --os-cert and --os-key
fake_execute(_shell, "--os-cert mycert --os-key mickey module list")
self.assertEqual('mycert', _shell.options.cert)
self.assertEqual('mickey', _shell.options.key)
self.assertEqual(('mycert', 'mickey'), _shell.client_manager.cert)
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
def test_shell_args_cloud_no_vendor(self, config_mock):
"""Test cloud config options without the vendor file"""
config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_1))
_shell = make_shell()
fake_execute(
_shell,
"--os-cloud scc list user",
"--os-cloud scc module list",
)
self.assertEqual(
'scc',
@ -436,6 +471,10 @@ class TestShellCli(TestShell):
'occ-cloud',
_shell.cloud.config['region_name'],
)
self.assertEqual(
'occ-cloud',
_shell.client_manager.region_name,
)
self.assertEqual(
'glazed',
_shell.cloud.config['donut'],
@ -445,16 +484,21 @@ class TestShellCli(TestShell):
_shell.cloud.config['interface'],
)
self.assertIsNone(_shell.cloud.config['cert'])
self.assertIsNone(_shell.cloud.config['key'])
self.assertIsNone(_shell.client_manager.cert)
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
def test_shell_args_cloud_public(self, config_mock, public_mock):
"""Test cloud config options with the vendor file"""
config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_2))
public_mock.return_value = ('file.yaml', copy.deepcopy(PUBLIC_1))
_shell = make_shell()
fake_execute(
_shell,
"--os-cloud megacloud list user",
"--os-cloud megacloud module list",
)
self.assertEqual(
'megacloud',
@ -484,9 +528,14 @@ class TestShellCli(TestShell):
'occ-cloud',
_shell.cloud.config['region_name'],
)
self.assertEqual(
'occ-cloud',
_shell.client_manager.region_name,
)
self.assertEqual('mycert', _shell.cloud.config['cert'])
self.assertEqual('mickey', _shell.cloud.config['key'])
self.assertEqual(('mycert', 'mickey'), _shell.client_manager.cert)
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
@ -498,7 +547,7 @@ class TestShellCli(TestShell):
# Test command option overriding config file value
fake_execute(
_shell,
"--os-cloud megacloud --os-region-name krikkit list user",
"--os-cloud megacloud --os-region-name krikkit module list",
)
self.assertEqual(
'megacloud',
@ -528,13 +577,19 @@ class TestShellCli(TestShell):
'krikkit',
_shell.cloud.config['region_name'],
)
self.assertEqual(
'krikkit',
_shell.client_manager.region_name,
)
class TestShellCliEnv(TestShell):
class TestShellCliPrecedence(TestShell):
"""Test option precedencr order"""
def setUp(self):
super(TestShellCliEnv, self).setUp()
super(TestShellCliPrecedence, self).setUp()
env = {
'OS_CLOUD': 'megacloud',
'OS_REGION_NAME': 'occ-env',
}
self.useFixture(EnvFixture(env.copy()))
@ -542,6 +597,7 @@ class TestShellCliEnv(TestShell):
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
def test_shell_args_precedence_1(self, config_mock, vendor_mock):
"""Test environment overriding occ"""
config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_2))
vendor_mock.return_value = ('file.yaml', copy.deepcopy(PUBLIC_1))
_shell = make_shell()
@ -549,7 +605,7 @@ class TestShellCliEnv(TestShell):
# Test env var
fake_execute(
_shell,
"--os-cloud megacloud list user",
"module list",
)
self.assertEqual(
'megacloud',
@ -575,14 +631,21 @@ class TestShellCliEnv(TestShell):
'zaphod',
_shell.cloud.config['auth']['username'],
)
# These come from the environment
self.assertEqual(
'occ-env',
_shell.cloud.config['region_name'],
)
self.assertEqual(
'occ-env',
_shell.client_manager.region_name,
)
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
def test_shell_args_precedence_2(self, config_mock, vendor_mock):
"""Test command line overriding environment and occ"""
config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_2))
vendor_mock.return_value = ('file.yaml', copy.deepcopy(PUBLIC_1))
_shell = make_shell()
@ -590,7 +653,7 @@ class TestShellCliEnv(TestShell):
# Test command option overriding config file value
fake_execute(
_shell,
"--os-cloud megacloud --os-region-name krikkit list user",
"--os-region-name krikkit list user",
)
self.assertEqual(
'megacloud',
@ -622,3 +685,55 @@ class TestShellCliEnv(TestShell):
'krikkit',
_shell.cloud.config['region_name'],
)
self.assertEqual(
'krikkit',
_shell.client_manager.region_name,
)
@mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file")
@mock.patch("os_client_config.config.OpenStackConfig._load_config_file")
def test_shell_args_precedence_3(self, config_mock, vendor_mock):
"""Test command line overriding environment and occ"""
config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_1))
vendor_mock.return_value = ('file.yaml', copy.deepcopy(PUBLIC_1))
_shell = make_shell()
# Test command option overriding config file value
fake_execute(
_shell,
"--os-cloud scc --os-region-name krikkit list user",
)
self.assertEqual(
'scc',
_shell.cloud.name,
)
# These come from clouds-public.yaml
self.assertEqual(
DEFAULT_AUTH_URL,
_shell.cloud.config['auth']['auth_url'],
)
self.assertEqual(
'glazed',
_shell.cloud.config['donut'],
)
# These come from clouds.yaml
self.assertEqual(
DEFAULT_PROJECT_NAME,
_shell.cloud.config['auth']['project_name'],
)
self.assertEqual(
'zaphod',
_shell.cloud.config['auth']['username'],
)
# These come from the command line
self.assertEqual(
'krikkit',
_shell.cloud.config['region_name'],
)
self.assertEqual(
'krikkit',
_shell.client_manager.region_name,
)