From d3f13f4c20eba725fa8228a25cdfd77d47b7569d Mon Sep 17 00:00:00 2001
From: Henry Gessau <gessau@gmail.com>
Date: Wed, 24 Feb 2016 12:46:58 -0500
Subject: [PATCH] Support dry-run option for auto-allocated-topology

Add the ability to pass fields with the
auto-allocated-topology-show command to support the
dry-run validation option of the API.

With dry-run the CLI result is "Pass" or the error message
from the response.

Rename the client binding from show_ to get_. Also provide a
client binding for validating the auto-allocation requirements.

Partially-Implements: blueprint get-me-a-network

DocImpact: Add info about dry-run to the auto-allocate section
           in the networking guide.

Change-Id: Ieba6f3cde23a8a93067b8239b096d5103f6a3128
---
 .../neutron/v2_0/auto_allocated_topology.py    | 18 +++++++++++++++++-
 .../tests/unit/test_auto_allocated_topology.py | 14 ++++++++++++++
 neutronclient/v2_0/client.py                   |  6 +++++-
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/neutronclient/neutron/v2_0/auto_allocated_topology.py b/neutronclient/neutron/v2_0/auto_allocated_topology.py
index ad96fd988..3f0f58baf 100755
--- a/neutronclient/neutron/v2_0/auto_allocated_topology.py
+++ b/neutronclient/neutron/v2_0/auto_allocated_topology.py
@@ -19,6 +19,7 @@ from cliff import show
 from oslo_serialization import jsonutils
 
 from neutronclient._i18n import _
+from neutronclient.common import exceptions
 from neutronclient.neutron import v2_0
 
 
@@ -29,6 +30,11 @@ class ShowAutoAllocatedTopology(v2_0.NeutronCommand, show.ShowOne):
 
     def get_parser(self, prog_name):
         parser = super(ShowAutoAllocatedTopology, self).get_parser(prog_name)
+        parser.add_argument(
+            '--dry-run',
+            help=_('Validate the requirements for auto-allocated-topology. '
+                   '(Does not return a topology.)'),
+            action='store_true')
         parser.add_argument(
             '--tenant-id', metavar='tenant-id',
             help=_('The owner tenant ID.'))
@@ -44,8 +50,16 @@ class ShowAutoAllocatedTopology(v2_0.NeutronCommand, show.ShowOne):
 
     def take_action(self, parsed_args):
         client = self.get_client()
+        extra_values = v2_0.parse_args_to_dict(self.values_specs)
+        if extra_values:
+            raise exceptions.CommandError(
+                _("Invalid argument(s): --%s") % ', --'.join(extra_values))
         tenant_id = parsed_args.tenant_id or parsed_args.pos_tenant_id
-        data = client.show_auto_allocated_topology(tenant_id)
+        if parsed_args.dry_run:
+            data = client.validate_auto_allocated_topology_requirements(
+                tenant_id)
+        else:
+            data = client.get_auto_allocated_topology(tenant_id)
         if self.resource in data:
             for k, v in data[self.resource].items():
                 if isinstance(v, list):
@@ -58,6 +72,8 @@ class ShowAutoAllocatedTopology(v2_0.NeutronCommand, show.ShowOne):
                         else:
                             value += str(_item)
                     data[self.resource][k] = value
+                elif v == "dry-run=pass":
+                    return ("dry-run",), ("pass",)
                 elif v is None:
                     data[self.resource][k] = ''
             return zip(*sorted(data[self.resource].items()))
diff --git a/neutronclient/tests/unit/test_auto_allocated_topology.py b/neutronclient/tests/unit/test_auto_allocated_topology.py
index b0f8cf0e7..af2742b0e 100755
--- a/neutronclient/tests/unit/test_auto_allocated_topology.py
+++ b/neutronclient/tests/unit/test_auto_allocated_topology.py
@@ -39,3 +39,17 @@ class TestAutoAllocatedTopologyJSON(test_cli20.CLITestV20Base):
         cmd = aat.ShowAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None)
         args = []
         self._test_show_resource(resource, cmd, "None", args)
+
+    def test_show_auto_allocated_topology_dry_run_as_tenant(self):
+        resource = 'auto_allocated_topology'
+        cmd = aat.ShowAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None)
+        args = ['--dry-run']
+        self._test_show_resource(resource, cmd, "None", args,
+                                 fields=('dry-run',))
+
+    def test_show_auto_allocated_topology_dry_run_as_admin(self):
+        resource = 'auto_allocated_topology'
+        cmd = aat.ShowAutoAllocatedTopology(test_cli20.MyApp(sys.stdout), None)
+        args = ['--dry-run', 'some-tenant']
+        self._test_show_resource(resource, cmd, "some-tenant", args,
+                                 fields=('dry-run',))
diff --git a/neutronclient/v2_0/client.py b/neutronclient/v2_0/client.py
index f25b007e5..71bd50317 100644
--- a/neutronclient/v2_0/client.py
+++ b/neutronclient/v2_0/client.py
@@ -1902,12 +1902,16 @@ class Client(ClientBase):
                          retrieve_all, **_params)
 
     @APIParamsCall
-    def show_auto_allocated_topology(self, tenant_id, **_params):
+    def get_auto_allocated_topology(self, tenant_id, **_params):
         """Fetch information about a tenant's auto-allocated topology."""
         return self.get(
             self.auto_allocated_topology_path % tenant_id,
             params=_params)
 
+    def validate_auto_allocated_topology_requirements(self, tenant_id):
+        """Validate requirements for getting an auto-allocated topology."""
+        return self.get_auto_allocated_topology(tenant_id, fields=['dry-run'])
+
     @APIParamsCall
     def list_bgp_speakers(self, retrieve_all=True, **_params):
         """Fetches a list of all BGP speakers for a tenant."""