From 4a2fd82b07ada8b5aded1f9507e7b566366127d8 Mon Sep 17 00:00:00 2001
From: Stephen Finucane <stephenfin@redhat.com>
Date: Wed, 7 Aug 2024 13:38:52 +0100
Subject: [PATCH] compute: Make 'hypervisor show' a bit faster

In the event that a user provides a hypervisor name rather than an ID to
the 'hypervisor show' command, passing 'details=True' (the default) to
'find_hypervisor' will ensure we get the detailed response we need.
However, this comes at the cost of retrieving reams of additional
irrelevant data for all the other hypervisors. Rather than doing this,
use a summary view and then a second call to fetch only the hypervisor
we care about.

Change-Id: I92b53802e41a962c6f916c3a111dc2de7c12d0fc
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
Closes-bug: #2072965
---
 openstackclient/compute/v2/hypervisor.py      |  8 +++--
 .../tests/unit/compute/v2/test_hypervisor.py  | 32 +++++++++++++++++--
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/openstackclient/compute/v2/hypervisor.py b/openstackclient/compute/v2/hypervisor.py
index fffeb35216..8a82a30d98 100644
--- a/openstackclient/compute/v2/hypervisor.py
+++ b/openstackclient/compute/v2/hypervisor.py
@@ -165,9 +165,11 @@ class ShowHypervisor(command.ShowOne):
 
     def take_action(self, parsed_args):
         compute_client = self.app.client_manager.sdk_connection.compute
-        hypervisor = compute_client.find_hypervisor(
-            parsed_args.hypervisor, ignore_missing=False
-        ).copy()
+
+        hypervisor_id = compute_client.find_hypervisor(
+            parsed_args.hypervisor, ignore_missing=False, details=False
+        ).id
+        hypervisor = compute_client.get_hypervisor(hypervisor_id).copy()
 
         # Some of the properties in the hypervisor object need to be processed
         # before they get reported to the user. We spend this section
diff --git a/openstackclient/tests/unit/compute/v2/test_hypervisor.py b/openstackclient/tests/unit/compute/v2/test_hypervisor.py
index 2c226f0046..2c83fe4c91 100644
--- a/openstackclient/tests/unit/compute/v2/test_hypervisor.py
+++ b/openstackclient/tests/unit/compute/v2/test_hypervisor.py
@@ -296,13 +296,11 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
             }
         )
 
-        # Return value of compute_client.find_hypervisor
         self.compute_sdk_client.find_hypervisor.return_value = self.hypervisor
+        self.compute_sdk_client.get_hypervisor.return_value = self.hypervisor
 
-        # Return value of compute_client.aggregates()
         self.compute_sdk_client.aggregates.return_value = []
 
-        # Return value of compute_client.get_hypervisor_uptime()
         uptime_info = {
             'status': self.hypervisor.status,
             'state': self.hypervisor.state,
@@ -429,6 +427,13 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
         self.assertEqual(self.columns_v288, columns)
         self.assertCountEqual(self.data_v288, data)
 
+        self.compute_sdk_client.find_hypervisor.assert_called_once_with(
+            self.hypervisor.name, ignore_missing=False, details=False
+        )
+        self.compute_sdk_client.get_hypervisor.assert_called_once_with(
+            self.hypervisor.id
+        )
+
     def test_hypervisor_show_pre_v288(self):
         self.set_compute_api_version('2.87')
 
@@ -448,6 +453,13 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, data)
 
+        self.compute_sdk_client.find_hypervisor.assert_called_once_with(
+            self.hypervisor.name, ignore_missing=False, details=False
+        )
+        self.compute_sdk_client.get_hypervisor.assert_called_once_with(
+            self.hypervisor.id
+        )
+
     def test_hypervisor_show_pre_v228(self):
         self.set_compute_api_version('2.27')
 
@@ -472,6 +484,13 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, data)
 
+        self.compute_sdk_client.find_hypervisor.assert_called_once_with(
+            self.hypervisor.name, ignore_missing=False, details=False
+        )
+        self.compute_sdk_client.get_hypervisor.assert_called_once_with(
+            self.hypervisor.id
+        )
+
     def test_hypervisor_show_uptime_not_implemented(self):
         self.set_compute_api_version('2.87')
 
@@ -543,3 +562,10 @@ class TestHypervisorShow(compute_fakes.TestComputev2):
 
         self.assertEqual(expected_columns, columns)
         self.assertCountEqual(expected_data, data)
+
+        self.compute_sdk_client.find_hypervisor.assert_called_once_with(
+            self.hypervisor.name, ignore_missing=False, details=False
+        )
+        self.compute_sdk_client.get_hypervisor.assert_called_once_with(
+            self.hypervisor.id
+        )