From 239b103849b96213dc9cb317006346ce311228e4 Mon Sep 17 00:00:00 2001
From: Surya Seetharaman <suryaseetharaman.9@gmail.com>
Date: Mon, 28 Jan 2019 19:30:00 +0100
Subject: [PATCH] API microversion 2.69: Handles Down Cells

This patch explicitly points out the change needed while
forming the detailed lists for servers. In those cases
where the server response for ``openstack server list``
has the flavor and image keys missing for the instances
in the down cell, the servers will be skipped from being
processed.

Depends-On: https://review.openstack.org/591657/
Related to blueprint handling-down-cell
Change-Id: Ibcfe9febdc45db1cb86c6e88f65976feceb01c02
---
 openstackclient/compute/v2/server.py          |  8 ++++
 .../tests/unit/compute/v2/test_server.py      | 44 +++++++++++++++++++
 ...p-handling-down-cell-ab8af2897f1a8c85.yaml |  9 ++++
 3 files changed, 61 insertions(+)
 create mode 100644 releasenotes/notes/bp-handling-down-cell-ab8af2897f1a8c85.yaml

diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index b608ecbd52..36a674339f 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -1314,6 +1314,14 @@ class ListServer(command.Lister):
         # Populate image_name, image_id, flavor_name and flavor_id attributes
         # of server objects so that we can display those columns.
         for s in data:
+            if compute_client.api_version >= api_versions.APIVersion('2.69'):
+                # NOTE(tssurya): From 2.69, we will have the keys 'flavor'
+                # and 'image' missing in the server response during
+                # infrastructure failure situations.
+                # For those servers with partial constructs we just skip the
+                # processing of the image and flavor informations.
+                if not hasattr(s, 'image') or not hasattr(s, 'flavor'):
+                    continue
             if 'id' in s.image:
                 image = images.get(s.image['id'])
                 if image:
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index c529d840de..c30af8fb8e 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -2272,6 +2272,50 @@ class TestServerList(TestServer):
             'Invalid time value'
         )
 
+    def test_server_list_v269_with_partial_constructs(self):
+        self.app.client_manager.compute.api_version = \
+            api_versions.APIVersion('2.69')
+        arglist = []
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        # include "partial results" from non-responsive part of
+        # infrastructure.
+        server_dict = {
+            "id": "server-id-95a56bfc4xxxxxx28d7e418bfd97813a",
+            "status": "UNKNOWN",
+            "tenant_id": "6f70656e737461636b20342065766572",
+            "created": "2018-12-03T21:06:18Z",
+            "links": [
+                {
+                    "href": "http://fake/v2.1/",
+                    "rel": "self"
+                },
+                {
+                    "href": "http://fake",
+                    "rel": "bookmark"
+                }
+            ],
+            # We need to pass networks as {} because its defined as a property
+            # of the novaclient Server class which gives {} by default. If not
+            # it will fail at formatting the networks info later on.
+            "networks": {}
+        }
+        server = compute_fakes.fakes.FakeResource(
+            info=server_dict,
+        )
+        self.servers.append(server)
+        columns, data = self.cmd.take_action(parsed_args)
+        # get the first three servers out since our interest is in the partial
+        # server.
+        next(data)
+        next(data)
+        next(data)
+        partial_server = next(data)
+        expected_row = (
+            'server-id-95a56bfc4xxxxxx28d7e418bfd97813a', '',
+            'UNKNOWN', '', '', '')
+        self.assertEqual(expected_row, partial_server)
+
 
 class TestServerLock(TestServer):
 
diff --git a/releasenotes/notes/bp-handling-down-cell-ab8af2897f1a8c85.yaml b/releasenotes/notes/bp-handling-down-cell-ab8af2897f1a8c85.yaml
new file mode 100644
index 0000000000..f9e1ad278d
--- /dev/null
+++ b/releasenotes/notes/bp-handling-down-cell-ab8af2897f1a8c85.yaml
@@ -0,0 +1,9 @@
+---
+features:
+  - |
+    From microversion 2.69 the results of ``openstack server list`` and
+    ``openstack server show`` may contain missing information in their outputs
+    when there are partial infrastructure failure periods in the deployment.
+    See `Handling Down Cells`_ for more information on the missing keys/info.
+
+    .. _Handling Down Cells: https://developer.openstack.org/api-guide/compute/down_cells.html
\ No newline at end of file