From 4d9da2c40ae02086258cfde852b297754d8085fa Mon Sep 17 00:00:00 2001
From: Rui Chen <chenrui.momo@gmail.com>
Date: Tue, 10 Jan 2017 15:13:47 +0800
Subject: [PATCH] Fix OSC networking commands help errors

OSC networking commands need to authenticate to get
service catalog, then decide to show nova-network or
neutron command help message. Fake token and fake
auth_type in prepare_to_run_command() casue os-cloud-config
use AdminToken auth plugin, but pass all the auth information
(include: username, password and so on) to it, that casue the
class initialization error. Pop the fake token and url, then
try to load auth plugin again to fix the issue.

Change-Id: I8b140f0b0a60681fc2a35a013bb0c84ff8cb9589
Closes-Bug: #1650026
---
 openstackclient/common/clientmanager.py       | 27 +++++++++++++++++--
 .../tests/functional/common/test_help.py      |  7 +++++
 .../notes/bug-1650026-0ce6a77e69d24424.yaml   |  6 +++++
 3 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml

diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index 23c35a3b28..3e1a50e3e6 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -59,6 +59,8 @@ class ClientManager(clientmanager.ClientManager):
         self._interface = self.interface
         self._cacert = self.cacert
         self._insecure = not self.verify
+        # store original auth_type
+        self._original_auth_type = cli_options.auth_type
 
     def setup_auth(self):
         """Set up authentication"""
@@ -73,12 +75,33 @@ class ClientManager(clientmanager.ClientManager):
         if self._cli_options._openstack_config is not None:
             self._cli_options._openstack_config._pw_callback = \
                 shell.prompt_for_password
+            try:
+                self._cli_options._auth = \
+                    self._cli_options._openstack_config.load_auth_plugin(
+                        self._cli_options.config,
+                    )
+            except TypeError as e:
+                self._fallback_load_auth_plugin(e)
+
+        return super(ClientManager, self).setup_auth()
+
+    def _fallback_load_auth_plugin(self, e):
+        # NOTES(RuiChen): Hack to avoid auth plugins choking on data they don't
+        #                 expect, delete fake token and endpoint, then try to
+        #                 load auth plugin again with user specified options.
+        #                 We know it looks ugly, but it's necessary.
+        if self._cli_options.config['auth']['token'] == 'x':
+            # restore original auth_type
+            self._cli_options.config['auth_type'] = \
+                self._original_auth_type
+            del self._cli_options.config['auth']['token']
+            del self._cli_options.config['auth']['endpoint']
             self._cli_options._auth = \
                 self._cli_options._openstack_config.load_auth_plugin(
                     self._cli_options.config,
                 )
-
-        return super(ClientManager, self).setup_auth()
+        else:
+            raise e
 
     def is_network_endpoint_enabled(self):
         """Check if the network endpoint is enabled"""
diff --git a/openstackclient/tests/functional/common/test_help.py b/openstackclient/tests/functional/common/test_help.py
index bbc521970e..211c52b1de 100644
--- a/openstackclient/tests/functional/common/test_help.py
+++ b/openstackclient/tests/functional/common/test_help.py
@@ -64,3 +64,10 @@ class HelpTests(base.TestCase):
         raw_output = self.openstack('help server')
         for command in [row[0] for row in self.SERVER_COMMANDS]:
             self.assertIn(command, raw_output)
+
+    def test_networking_commands_help(self):
+        """Check networking related commands in help message."""
+        raw_output = self.openstack('help network list')
+        self.assertIn('List networks', raw_output)
+        raw_output = self.openstack('network create --help')
+        self.assertIn('Create new network', raw_output)
diff --git a/releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml b/releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml
new file mode 100644
index 0000000000..bb92c873a5
--- /dev/null
+++ b/releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Fixed a ``__init__() got an unexpected keyword argument 'project_name'``
+    error in various networking commands when ``help`` or ``--help`` was used.
+    [Bug `1650026 <https://bugs.launchpad.net/bugs/1650026>`_]