From 865e182970c9ce42d5be07cd3b81fb5dd1a3e656 Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Fri, 26 Jul 2019 16:41:04 -0500 Subject: [PATCH] Make configuration show not require auth The configuration show should not require auth to just display the OSC config object. Changes to make it not require auth have knock-on effects of needing to change a bunch of tests that use it assuming it _does_ require auth so change those to use 'extension list' instead. This sets up further testing of the command line options for changes in behaviour when we switch to straight SDK usage for configuration. Change-Id: I6c52485341214ba401064c0f2d1e2b95fdc225c0 Signed-off-by: Dean Troyer --- openstackclient/common/configuration.py | 20 +++- openstackclient/tests/functional/base.py | 14 ++- .../functional/common/test_configuration.py | 27 +++++ .../tests/unit/integ/cli/test_project.py | 32 +++--- .../tests/unit/integ/cli/test_shell.py | 105 +++++++++++++----- .../notes/config-show-00512dc60882e5c0.yaml | 6 + 6 files changed, 150 insertions(+), 54 deletions(-) create mode 100644 releasenotes/notes/config-show-00512dc60882e5c0.yaml diff --git a/openstackclient/common/configuration.py b/openstackclient/common/configuration.py index 57825bb056..53b30d5fdd 100644 --- a/openstackclient/common/configuration.py +++ b/openstackclient/common/configuration.py @@ -25,6 +25,8 @@ REDACTED = "" class ShowConfiguration(command.ShowOne): _description = _("Display configuration details") + auth_required = False + def get_parser(self, prog_name): parser = super(ShowConfiguration, self).get_parser(prog_name) mask_group = parser.add_mutually_exclusive_group() @@ -45,13 +47,21 @@ class ShowConfiguration(command.ShowOne): def take_action(self, parsed_args): - auth_plg_name = self.app.client_manager.auth_plugin_name - secret_opts = [o.dest for o in base.get_plugin_options(auth_plg_name) - if o.secret] - info = self.app.client_manager.get_configuration() + + # Assume a default secret list in case we do not have an auth_plugin + secret_opts = ["password", "token"] + + if getattr(self.app.client_manager, "auth_plugin_name", None): + auth_plg_name = self.app.client_manager.auth_plugin_name + secret_opts = [ + o.dest for o in base.get_plugin_options(auth_plg_name) + if o.secret + ] + for key, value in six.iteritems(info.pop('auth', {})): if parsed_args.mask and key.lower() in secret_opts: - value = REDACTED + value = REDACTED info['auth.' + key] = value + return zip(*sorted(six.iteritems(info))) diff --git a/openstackclient/tests/functional/base.py b/openstackclient/tests/functional/base.py index 1414e6bbb7..c34ca39332 100644 --- a/openstackclient/tests/functional/base.py +++ b/openstackclient/tests/functional/base.py @@ -45,9 +45,17 @@ class TestCase(testtools.TestCase): @classmethod def openstack(cls, cmd, cloud=ADMIN_CLOUD, fail_ok=False): """Executes openstackclient command for the given action.""" - return execute( - 'openstack --os-cloud={cloud} '.format(cloud=cloud) + - cmd, fail_ok=fail_ok) + if cloud is not None: + return execute( + 'openstack --os-cloud={cloud} '.format(cloud=cloud) + cmd, + fail_ok=fail_ok + ) + else: + # Execute command with no auth + return execute( + 'openstack --os-auth-type none ' + cmd, + fail_ok=fail_ok + ) @classmethod def is_service_enabled(cls, service): diff --git a/openstackclient/tests/functional/common/test_configuration.py b/openstackclient/tests/functional/common/test_configuration.py index 63a17d0e77..17e0f45d1f 100644 --- a/openstackclient/tests/functional/common/test_configuration.py +++ b/openstackclient/tests/functional/common/test_configuration.py @@ -37,6 +37,10 @@ class ConfigurationTests(base.TestCase): configuration.REDACTED, cmd_output['auth.password'] ) + self.assertIn( + 'auth.password', + cmd_output.keys(), + ) # Test show --mask cmd_output = json.loads(self.openstack( @@ -65,3 +69,26 @@ class ConfigurationTests(base.TestCase): configuration.REDACTED, cmd_output['auth.password'] ) + + +class ConfigurationTestsNoAuth(base.TestCase): + """Functional test for configuration with no auth""" + + def test_configuration_show(self): + + # Test show without option + raw_output = self.openstack( + 'configuration show', + cloud=None, + ) + items = self.parse_listing(raw_output) + self.assert_table_structure(items, BASIC_CONFIG_HEADERS) + + cmd_output = json.loads(self.openstack( + 'configuration show -f json', + cloud=None, + )) + self.assertNotIn( + 'auth.password', + cmd_output, + ) diff --git a/openstackclient/tests/unit/integ/cli/test_project.py b/openstackclient/tests/unit/integ/cli/test_project.py index 6a7c6d1bd6..4e707a3762 100644 --- a/openstackclient/tests/unit/integ/cli/test_project.py +++ b/openstackclient/tests/unit/integ/cli/test_project.py @@ -36,10 +36,10 @@ class TestIntegV2ProjectID(test_base.TestInteg): def test_project_id_env(self): _shell = shell.OpenStackShell() - _shell.run("configuration show".split()) + _shell.run("extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -57,10 +57,10 @@ class TestIntegV2ProjectID(test_base.TestInteg): def test_project_id_arg(self): _shell = shell.OpenStackShell() - _shell.run("--os-project-id wsx configuration show".split()) + _shell.run("--os-project-id wsx extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -94,10 +94,10 @@ class TestIntegV2ProjectName(test_base.TestInteg): def test_project_name_env(self): _shell = shell.OpenStackShell() - _shell.run("configuration show".split()) + _shell.run("extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -115,10 +115,10 @@ class TestIntegV2ProjectName(test_base.TestInteg): def test_project_name_arg(self): _shell = shell.OpenStackShell() - _shell.run("--os-project-name qaz configuration show".split()) + _shell.run("--os-project-name qaz extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -154,10 +154,10 @@ class TestIntegV3ProjectID(test_base.TestInteg): def test_project_id_env(self): _shell = shell.OpenStackShell() - _shell.run("configuration show".split()) + _shell.run("extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -173,10 +173,10 @@ class TestIntegV3ProjectID(test_base.TestInteg): def test_project_id_arg(self): _shell = shell.OpenStackShell() - _shell.run("--os-project-id wsx configuration show".split()) + _shell.run("--os-project-id wsx extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -210,10 +210,10 @@ class TestIntegV3ProjectName(test_base.TestInteg): def test_project_name_env(self): _shell = shell.OpenStackShell() - _shell.run("configuration show".split()) + _shell.run("extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -234,10 +234,10 @@ class TestIntegV3ProjectName(test_base.TestInteg): def test_project_name_arg(self): _shell = shell.OpenStackShell() - _shell.run("--os-project-name wsx configuration show".split()) + _shell.run("--os-project-name wsx extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( diff --git a/openstackclient/tests/unit/integ/cli/test_shell.py b/openstackclient/tests/unit/integ/cli/test_shell.py index 200f9b1869..2598517113 100644 --- a/openstackclient/tests/unit/integ/cli/test_shell.py +++ b/openstackclient/tests/unit/integ/cli/test_shell.py @@ -31,6 +31,51 @@ except ImportError: CONFIG_MOCK_BASE = "os_client_config.config" +class TestIntegShellCliNoAuth(test_base.TestInteg): + + def setUp(self): + super(TestIntegShellCliNoAuth, self).setUp() + env = {} + self.useFixture(osc_lib_utils.EnvFixture(copy.deepcopy(env))) + + # self.token = test_base.make_v2_token(self.requests_mock) + + def test_shell_args_no_options(self): + _shell = shell.OpenStackShell() + _shell.run("configuration show".split()) + + # Check general calls + self.assertEqual(len(self.requests_mock.request_history), 0) + + def test_shell_args_verify(self): + _shell = shell.OpenStackShell() + _shell.run("--verify configuration show".split()) + + # Check general calls + self.assertEqual(len(self.requests_mock.request_history), 0) + + def test_shell_args_insecure(self): + _shell = shell.OpenStackShell() + _shell.run("--insecure configuration show".split()) + + # Check general calls + self.assertEqual(len(self.requests_mock.request_history), 0) + + def test_shell_args_cacert(self): + _shell = shell.OpenStackShell() + _shell.run("--os-cacert xyzpdq configuration show".split()) + + # Check general calls + self.assertEqual(len(self.requests_mock.request_history), 0) + + def test_shell_args_cacert_insecure(self): + _shell = shell.OpenStackShell() + _shell.run("--os-cacert xyzpdq --insecure configuration show".split()) + + # Check general calls + self.assertEqual(len(self.requests_mock.request_history), 0) + + class TestIntegShellCliV2(test_base.TestInteg): def setUp(self): @@ -48,10 +93,10 @@ class TestIntegShellCliV2(test_base.TestInteg): def test_shell_args_no_options(self): _shell = shell.OpenStackShell() - _shell.run("configuration show".split()) + _shell.run("extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -77,30 +122,30 @@ class TestIntegShellCliV2(test_base.TestInteg): def test_shell_args_verify(self): _shell = shell.OpenStackShell() - _shell.run("--verify configuration show".split()) + _shell.run("--verify extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check verify self.assertTrue(self.requests_mock.request_history[0].verify) def test_shell_args_insecure(self): _shell = shell.OpenStackShell() - _shell.run("--insecure configuration show".split()) + _shell.run("--insecure extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check verify self.assertFalse(self.requests_mock.request_history[0].verify) def test_shell_args_cacert(self): _shell = shell.OpenStackShell() - _shell.run("--os-cacert xyzpdq configuration show".split()) + _shell.run("--os-cacert xyzpdq extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check verify self.assertEqual( @@ -110,10 +155,10 @@ class TestIntegShellCliV2(test_base.TestInteg): def test_shell_args_cacert_insecure(self): _shell = shell.OpenStackShell() - _shell.run("--os-cacert xyzpdq --insecure configuration show".split()) + _shell.run("--os-cacert xyzpdq --insecure extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check verify self.assertFalse(self.requests_mock.request_history[0].verify) @@ -138,10 +183,10 @@ class TestIntegShellCliV2Ignore(test_base.TestInteg): def test_shell_args_ignore_v3(self): _shell = shell.OpenStackShell() - _shell.run("configuration show".split()) + _shell.run("extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -184,10 +229,10 @@ class TestIntegShellCliV3(test_base.TestInteg): def test_shell_args_no_options(self): _shell = shell.OpenStackShell() - _shell.run("configuration show".split()) + _shell.run("extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -213,30 +258,30 @@ class TestIntegShellCliV3(test_base.TestInteg): def test_shell_args_verify(self): _shell = shell.OpenStackShell() - _shell.run("--verify configuration show".split()) + _shell.run("--verify extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check verify self.assertTrue(self.requests_mock.request_history[0].verify) def test_shell_args_insecure(self): _shell = shell.OpenStackShell() - _shell.run("--insecure configuration show".split()) + _shell.run("--insecure extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check verify self.assertFalse(self.requests_mock.request_history[0].verify) def test_shell_args_cacert(self): _shell = shell.OpenStackShell() - _shell.run("--os-cacert xyzpdq configuration show".split()) + _shell.run("--os-cacert xyzpdq extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check verify self.assertEqual( @@ -248,10 +293,10 @@ class TestIntegShellCliV3(test_base.TestInteg): # This test verifies the outcome of bug 1447784 # https://bugs.launchpad.net/python-openstackclient/+bug/1447784 _shell = shell.OpenStackShell() - _shell.run("--os-cacert xyzpdq --insecure configuration show".split()) + _shell.run("--os-cacert xyzpdq --insecure extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check verify self.assertFalse(self.requests_mock.request_history[0].verify) @@ -276,10 +321,10 @@ class TestIntegShellCliV3Prompt(test_base.TestInteg): def test_shell_callback(self, mock_prompt): mock_prompt.return_value = "qaz" _shell = shell.OpenStackShell() - _shell.run("configuration show".split()) + _shell.run("extension list".split()) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check password callback set correctly self.assertEqual( @@ -332,11 +377,11 @@ class TestIntegShellCliPrecedence(test_base.TestInteg): _shell = shell.OpenStackShell() _shell.run( "--os-username zarquon --os-password qaz " - "configuration show".split(), + "extension list".split(), ) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -431,11 +476,11 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg): print("CONFIG_MOCK_BASE=%s" % CONFIG_MOCK_BASE) _shell = shell.OpenStackShell() _shell.run( - "--os-password qaz configuration show".split(), + "--os-password qaz extension list".split(), ) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( @@ -504,11 +549,11 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg): _shell = shell.OpenStackShell() _shell.run( "--os-username zarquon --os-password qaz " - "--os-project-domain-id 5678 configuration show".split(), + "--os-project-domain-id 5678 extension list".split(), ) # Check general calls - self.assertEqual(len(self.requests_mock.request_history), 2) + self.assertNotEqual(len(self.requests_mock.request_history), 0) # Check discovery request self.assertEqual( diff --git a/releasenotes/notes/config-show-00512dc60882e5c0.yaml b/releasenotes/notes/config-show-00512dc60882e5c0.yaml new file mode 100644 index 0000000000..da57dff7f9 --- /dev/null +++ b/releasenotes/notes/config-show-00512dc60882e5c0.yaml @@ -0,0 +1,6 @@ +--- +other: + - | + The ``configuration show`` command no longer requires authentication. + This is useful in debugging cloud configurations, particularly + auth configurations.