From 992cfdfb57c359f709a0ceb67502f5bd66b90e5a Mon Sep 17 00:00:00 2001
From: Ariel-Berkowicz <arielmb@bu.edu>
Date: Mon, 5 Dec 2022 19:30:05 -0500
Subject: [PATCH] Migrate hypervisor stats commands to SDK

Change-Id: I43b2071f5108c28f6881c8e99d4b06e87c83ddfa
---
 .../compute/v2/hypervisor_stats.py            | 38 ++++++++++--
 .../tests/unit/compute/v2/fakes.py            | 61 -------------------
 .../unit/compute/v2/test_hypervisor_stats.py  | 51 +++++++++++++---
 ...ch-hypervisor-to-sdk-f6495f070b034718.yaml |  3 +
 4 files changed, 81 insertions(+), 72 deletions(-)
 create mode 100644 releasenotes/notes/switch-hypervisor-to-sdk-f6495f070b034718.yaml

diff --git a/openstackclient/compute/v2/hypervisor_stats.py b/openstackclient/compute/v2/hypervisor_stats.py
index 4493e08018..cb63a8000c 100644
--- a/openstackclient/compute/v2/hypervisor_stats.py
+++ b/openstackclient/compute/v2/hypervisor_stats.py
@@ -11,19 +11,49 @@
 #   under the License.
 #
 
-
 """Hypervisor Stats action implementations"""
 
 from osc_lib.command import command
+from osc_lib import utils
 
 from openstackclient.i18n import _
 
 
+def _get_hypervisor_stat_columns(item):
+    column_map = {
+        # NOTE(gtema): If we decide to use SDK names - empty this
+        'disk_available': 'disk_available_least',
+        'local_disk_free': 'free_disk_gb',
+        'local_disk_size': 'local_gb',
+        'local_disk_used': 'local_gb_used',
+        'memory_free': 'free_ram_mb',
+        'memory_size': 'memory_mb',
+        'memory_used': 'memory_mb_used',
+
+    }
+    hidden_columns = ['id', 'links', 'location', 'name']
+    return utils.get_osc_show_columns_for_sdk_resource(
+        item, column_map, hidden_columns)
+
+
 class ShowHypervisorStats(command.ShowOne):
     _description = _("Display hypervisor stats details")
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.compute
-        hypervisor_stats = compute_client.hypervisors.statistics().to_dict()
+        # The command is deprecated since it is being dropped in Nova.
+        self.log.warning(
+            _("This command is deprecated.")
+        )
+        compute_client = self.app.client_manager.sdk_connection.compute
+        # We do API request directly cause this deprecated method is not and
+        # will not be supported by OpenStackSDK.
+        response = compute_client.get(
+            '/os-hypervisors/statistics',
+            microversion='2.1')
+        hypervisor_stats = response.json().get('hypervisor_statistics')
 
-        return zip(*sorted(hypervisor_stats.items()))
+        display_columns, columns = _get_hypervisor_stat_columns(
+            hypervisor_stats)
+        data = utils.get_dict_properties(
+            hypervisor_stats, columns)
+        return (display_columns, data)
diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py
index 7d8c29ad7c..6ebdfc6429 100644
--- a/openstackclient/tests/unit/compute/v2/fakes.py
+++ b/openstackclient/tests/unit/compute/v2/fakes.py
@@ -341,67 +341,6 @@ class FakeExtension(object):
         return extension
 
 
-class FakeHypervisorStats(object):
-    """Fake one or more hypervisor stats."""
-
-    @staticmethod
-    def create_one_hypervisor_stats(attrs=None):
-        """Create a fake hypervisor stats.
-
-        :param dict attrs:
-            A dictionary with all attributes
-        :return:
-            A FakeResource object, with count, current_workload, and so on
-        """
-        attrs = attrs or {}
-
-        # Set default attributes.
-        stats_info = {
-            'count': 2,
-            'current_workload': 0,
-            'disk_available_least': 50,
-            'free_disk_gb': 100,
-            'free_ram_mb': 23000,
-            'local_gb': 100,
-            'local_gb_used': 0,
-            'memory_mb': 23800,
-            'memory_mb_used': 1400,
-            'running_vms': 3,
-            'vcpus': 8,
-            'vcpus_used': 3,
-        }
-
-        # Overwrite default attributes.
-        stats_info.update(attrs)
-
-        # Set default method.
-        hypervisor_stats_method = {'to_dict': stats_info}
-
-        hypervisor_stats = fakes.FakeResource(
-            info=copy.deepcopy(stats_info),
-            methods=copy.deepcopy(hypervisor_stats_method),
-            loaded=True)
-        return hypervisor_stats
-
-    @staticmethod
-    def create_hypervisors_stats(attrs=None, count=2):
-        """Create multiple fake hypervisors stats.
-
-        :param dict attrs:
-            A dictionary with all attributes
-        :param int count:
-            The number of hypervisors to fake
-        :return:
-            A list of FakeResource objects faking the hypervisors
-        """
-        hypervisors = []
-        for i in range(0, count):
-            hypervisors.append(
-                FakeHypervisorStats.create_one_hypervisor_stats(attrs))
-
-        return hypervisors
-
-
 class FakeSecurityGroup(object):
     """Fake one or more security groups."""
 
diff --git a/openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py b/openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py
index 40086f9bf2..7bc7468ad6 100644
--- a/openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py
+++ b/openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py
@@ -12,9 +12,11 @@
 #   License for the specific language governing permissions and limitations
 #   under the License.
 #
+from unittest import mock
 
 from openstackclient.compute.v2 import hypervisor_stats
 from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
+from openstackclient.tests.unit import fakes
 
 
 class TestHypervisorStats(compute_fakes.TestComputev2):
@@ -23,20 +25,55 @@ class TestHypervisorStats(compute_fakes.TestComputev2):
         super(TestHypervisorStats, self).setUp()
 
         # Get a shortcut to the compute client hypervisors mock
-        self.hypervisors_mock = self.app.client_manager.compute.hypervisors
-        self.hypervisors_mock.reset_mock()
+        self.app.client_manager.sdk_connection = mock.Mock()
+        self.app.client_manager.sdk_connection.compute = mock.Mock()
+        self.sdk_client = self.app.client_manager.sdk_connection.compute
+        self.sdk_client.get = mock.Mock()
+
+
+# Not in fakes.py because hypervisor stats has been deprecated
+
+def create_one_hypervisor_stats(attrs=None):
+    """Create a fake hypervisor stats.
+
+    :param dict attrs:
+        A dictionary with all attributes
+    :return:
+        A dictionary that contains hypervisor stats information keys
+    """
+    attrs = attrs or {}
+
+    # Set default attributes.
+    stats_info = {
+        'count': 2,
+        'current_workload': 0,
+        'disk_available_least': 50,
+        'free_disk_gb': 100,
+        'free_ram_mb': 23000,
+        'local_gb': 100,
+        'local_gb_used': 0,
+        'memory_mb': 23800,
+        'memory_mb_used': 1400,
+        'running_vms': 3,
+        'vcpus': 8,
+        'vcpus_used': 3,
+    }
+
+    # Overwrite default attributes.
+    stats_info.update(attrs)
+
+    return stats_info
 
 
 class TestHypervisorStatsShow(TestHypervisorStats):
 
+    _stats = create_one_hypervisor_stats()
+
     def setUp(self):
         super(TestHypervisorStatsShow, self).setUp()
 
-        self.hypervisor_stats = \
-            compute_fakes.FakeHypervisorStats.create_one_hypervisor_stats()
-
-        self.hypervisors_mock.statistics.return_value =\
-            self.hypervisor_stats
+        self.sdk_client.get.return_value = fakes.FakeResponse(
+            data={'hypervisor_statistics': self._stats})
 
         self.cmd = hypervisor_stats.ShowHypervisorStats(self.app, None)
 
diff --git a/releasenotes/notes/switch-hypervisor-to-sdk-f6495f070b034718.yaml b/releasenotes/notes/switch-hypervisor-to-sdk-f6495f070b034718.yaml
new file mode 100644
index 0000000000..6f1721b1b0
--- /dev/null
+++ b/releasenotes/notes/switch-hypervisor-to-sdk-f6495f070b034718.yaml
@@ -0,0 +1,3 @@
+---
+features:
+  - Switch hypervisor operations to consume OpenStackSDK