From fe59e339ae6dd6a5e9075773fb5c2a0fea9c2e53 Mon Sep 17 00:00:00 2001
From: venkata anil <anilvenkata@redhat.com>
Date: Tue, 14 Feb 2017 05:05:20 +0000
Subject: [PATCH] Allow override of distributed router flag

When router_distributed=True is set in neutron.conf,
user can't override this and create a centralized router
through openstack client. Openstack client allows modifying
routers from distributed to centralized after creation but
not supporting centralized flag during creation. We allow
centralized and distributed flags during router creation
with this change.

Closes-bug: #1664255
Change-Id: I75f72ca695338ad8c381cfa89fbb9d8e61ee7bc5
---
 doc/source/command-objects/router.rst         | 15 +++++++++-
 openstackclient/network/v2/router.py          | 13 +++++----
 .../tests/unit/network/v2/test_router.py      | 29 +++++++++++++++++++
 .../notes/bug-1664255-f82c5c13d92fed2a.yaml   |  9 ++++++
 4 files changed, 60 insertions(+), 6 deletions(-)
 create mode 100644 releasenotes/notes/bug-1664255-f82c5c13d92fed2a.yaml

diff --git a/doc/source/command-objects/router.rst b/doc/source/command-objects/router.rst
index 29131861d5..50e791ea7d 100644
--- a/doc/source/command-objects/router.rst
+++ b/doc/source/command-objects/router.rst
@@ -63,7 +63,7 @@ Create new router
     openstack router create
         [--project <project> [--project-domain <project-domain>]]
         [--enable | --disable]
-        [--distributed]
+        [--distributed | --centralized]
         [--ha | --no-ha]
         [--description <description>]
         [--availability-zone-hint <availability-zone>]
@@ -90,6 +90,19 @@ Create new router
 
     Create a distributed router
 
+    The default router type (distributed vs centralized) is determined by a
+    configuration setting in the OpenStack deployment.  Since we are unable
+    to know that default wihtout attempting to actually create a router it
+    is suggested to use either :option:`--distributed` or :option:`--centralized`
+    in situations where multiple cloud deployments may be used.
+
+.. option:: --centralized
+
+    Create a centralized router
+
+    See the note in :option:`--distributed` regarding the default used when
+    creating a new router.
+
 .. option:: --ha
 
     Create a highly available router
diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py
index f322d5d1f2..0da91baa44 100644
--- a/openstackclient/network/v2/router.py
+++ b/openstackclient/network/v2/router.py
@@ -78,8 +78,7 @@ def _get_attrs(client_manager, parsed_args):
         attrs['admin_state_up'] = True
     if parsed_args.disable:
         attrs['admin_state_up'] = False
-    # centralized is available only for SetRouter and not for CreateRouter
-    if 'centralized' in parsed_args and parsed_args.centralized:
+    if parsed_args.centralized:
         attrs['distributed'] = False
     if parsed_args.distributed:
         attrs['distributed'] = True
@@ -176,13 +175,17 @@ class CreateRouter(command.ShowOne):
             action='store_true',
             help=_("Disable router")
         )
-        parser.add_argument(
+        distribute_group = parser.add_mutually_exclusive_group()
+        distribute_group.add_argument(
             '--distributed',
-            dest='distributed',
             action='store_true',
-            default=False,
             help=_("Create a distributed router")
         )
+        distribute_group.add_argument(
+            '--centralized',
+            action='store_true',
+            help=_("Create a centralized router")
+        )
         ha_group = parser.add_mutually_exclusive_group()
         ha_group.add_argument(
             '--ha',
diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py
index a4f91997c4..02e0be9459 100644
--- a/openstackclient/tests/unit/network/v2/test_router.py
+++ b/openstackclient/tests/unit/network/v2/test_router.py
@@ -211,6 +211,35 @@ class TestCreateRouter(TestRouter):
     def test_create_with_no_ha_option(self):
         self._test_create_with_ha_options('--no-ha', False)
 
+    def _test_create_with_distributed_options(self, option, distributed):
+        arglist = [
+            option,
+            self.new_router.name,
+        ]
+        verifylist = [
+            ('name', self.new_router.name),
+            ('enable', True),
+            ('distributed', distributed),
+            ('centralized', not distributed),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = (self.cmd.take_action(parsed_args))
+
+        self.network.create_router.assert_called_once_with(**{
+            'admin_state_up': True,
+            'name': self.new_router.name,
+            'distributed': distributed,
+        })
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+
+    def test_create_with_distributed_option(self):
+        self._test_create_with_distributed_options('--distributed', True)
+
+    def test_create_with_centralized_option(self):
+        self._test_create_with_distributed_options('--centralized', False)
+
     def test_create_with_AZ_hints(self):
         arglist = [
             self.new_router.name,
diff --git a/releasenotes/notes/bug-1664255-f82c5c13d92fed2a.yaml b/releasenotes/notes/bug-1664255-f82c5c13d92fed2a.yaml
new file mode 100644
index 0000000000..ec162306b4
--- /dev/null
+++ b/releasenotes/notes/bug-1664255-f82c5c13d92fed2a.yaml
@@ -0,0 +1,9 @@
+---
+fixes:
+  - |
+    Allow users to create centralized (distributed=False)
+    routers using the ``--centralized`` option in ``router create``.
+    Without this, routers are created based on the default
+    neutron configuration of the deployment, which, for example,
+    could be 'distributed'.
+    [Bug `1664255 <https://bugs.launchpad.net/bugs/1664255>`_]