From c3a0c035dc6bd4676805d0618dfe334ed2d81228 Mon Sep 17 00:00:00 2001
From: "Chung Chih, Hung" <lyan.h@inwinstack.com>
Date: Sun, 19 Jul 2015 18:31:45 +0800
Subject: [PATCH] hypervisor command can't use cell format id to show
 hypervisor

This bug was occurred in cell mode.

In cell mode, compute node's id was not identified by integer type. It
was formatted with "path!to!cell@ID".
Therefore we can't using the id of hypervisor-list output.

For example,
> nova hypervisor-list
+----------------+--------------------------+-------+---------+
| ID | Hypervisor hostname | State | Status |
+----------------+--------------------------+-------+---------+
| region!child@1 | vagrant-ubuntu-trusty-64 | up | enabled |
+----------------+--------------------------+-------+---------+

Change-Id: Iba0cc1993f67351b11d034f372d7a5b98dc017f0
Closes-Bug: 1475973
---
 novaclient/tests/unit/v2/fakes.py      | 50 ++++++++++++++++++++++++++
 novaclient/tests/unit/v2/test_shell.py | 10 +++++-
 novaclient/utils.py                    |  3 +-
 novaclient/v2/hypervisors.py           |  1 +
 4 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/novaclient/tests/unit/v2/fakes.py b/novaclient/tests/unit/v2/fakes.py
index f3052252e..77cc93b50 100644
--- a/novaclient/tests/unit/v2/fakes.py
+++ b/novaclient/tests/unit/v2/fakes.py
@@ -74,6 +74,8 @@ class FakeHTTPClient(base_client.HTTPClient):
             munged_url = munged_url.replace('.', '_')
             munged_url = munged_url.replace('-', '_')
             munged_url = munged_url.replace(' ', '_')
+            munged_url = munged_url.replace('!', '_')
+            munged_url = munged_url.replace('@', '_')
             callback = "%s_%s" % (method.lower(), munged_url)
 
         if url is None or callback == "get_http:__nova_api:8774":
@@ -1776,6 +1778,48 @@ class FakeHTTPClient(base_client.HTTPClient):
                 'disk_available_least': 200}
         })
 
+    def get_os_hypervisors_hyper1(self, **kw):
+        return (200, {}, {
+            'hypervisor':
+            {'id': 1234,
+             'service': {'id': 1, 'host': 'compute1'},
+             'vcpus': 4,
+             'memory_mb': 10 * 1024,
+             'local_gb': 250,
+             'vcpus_used': 2,
+             'memory_mb_used': 5 * 1024,
+             'local_gb_used': 125,
+             'hypervisor_type': "xen",
+             'hypervisor_version': 3,
+             'hypervisor_hostname': "hyper1",
+             'free_ram_mb': 5 * 1024,
+             'free_disk_gb': 125,
+             'current_workload': 2,
+             'running_vms': 2,
+             'cpu_info': 'cpu_info',
+             'disk_available_least': 100}})
+
+    def get_os_hypervisors_region_child_1(self, **kw):
+        return (200, {}, {
+            'hypervisor':
+            {'id': 'region!child@1',
+             'service': {'id': 1, 'host': 'compute1'},
+             'vcpus': 4,
+             'memory_mb': 10 * 1024,
+             'local_gb': 250,
+             'vcpus_used': 2,
+             'memory_mb_used': 5 * 1024,
+             'local_gb_used': 125,
+             'hypervisor_type': "xen",
+             'hypervisor_version': 3,
+             'hypervisor_hostname': "hyper1",
+             'free_ram_mb': 5 * 1024,
+             'free_disk_gb': 125,
+             'current_workload': 2,
+             'running_vms': 2,
+             'cpu_info': 'cpu_info',
+             'disk_available_least': 100}})
+
     def get_os_hypervisors_hyper_search(self, **kw):
         return (200, {}, {
             'hypervisors': [
@@ -1828,6 +1872,12 @@ class FakeHTTPClient(base_client.HTTPClient):
                            'hypervisor_hostname': "hyper1",
                            'uptime': "fake uptime"}})
 
+    def get_os_hypervisors_region_child_1_uptime(self, **kw):
+        return (200, {}, {
+            'hypervisor': {'id': 'region!child@1',
+                           'hypervisor_hostname': "hyper1",
+                           'uptime': "fake uptime"}})
+
     def get_os_networks(self, **kw):
         return (200, {}, {'networks': [{"label": "1", "cidr": "10.0.0.0/24",
                                         'project_id':
diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py
index e5d8914a5..cc3ef7478 100644
--- a/novaclient/tests/unit/v2/test_shell.py
+++ b/novaclient/tests/unit/v2/test_shell.py
@@ -1727,14 +1727,22 @@ class ShellTest(utils.TestCase):
         self.run_command('hypervisor-show 1234')
         self.assert_called('GET', '/os-hypervisors/1234')
 
+    def test_hypervisor_list_show_by_cell_id(self):
+        self.run_command('hypervisor-show region!child@1')
+        self.assert_called('GET', '/os-hypervisors/region!child@1')
+
     def test_hypervisor_show_by_name(self):
         self.run_command('hypervisor-show hyper1')
-        self.assert_called('GET', '/os-hypervisors/detail')
+        self.assert_called('GET', '/os-hypervisors/hyper1')
 
     def test_hypervisor_uptime_by_id(self):
         self.run_command('hypervisor-uptime 1234')
         self.assert_called('GET', '/os-hypervisors/1234/uptime')
 
+    def test_hypervisor_uptime_by_cell_id(self):
+        self.run_command('hypervisor-uptime region!child@1')
+        self.assert_called('GET', '/os-hypervisors/region!child@1/uptime')
+
     def test_hypervisor_uptime_by_name(self):
         self.run_command('hypervisor-uptime hyper1')
         self.assert_called('GET', '/os-hypervisors/1234/uptime')
diff --git a/novaclient/utils.py b/novaclient/utils.py
index 1f4df7a57..5abb122e7 100644
--- a/novaclient/utils.py
+++ b/novaclient/utils.py
@@ -184,7 +184,8 @@ def print_dict(d, dict_property="Property", dict_value="Value", wrap=0):
 
 def find_resource(manager, name_or_id, **find_args):
     """Helper for the _find_* methods."""
-    # for str id which is not uuid (for Flavor and Keypair search currently)
+    # for str id which is not uuid (for Flavor, Keypair and hypervsior in cells
+    # environments search currently)
     if getattr(manager, 'is_alphanum_id_allowed', False):
         try:
             return manager.get(name_or_id)
diff --git a/novaclient/v2/hypervisors.py b/novaclient/v2/hypervisors.py
index b1bfcb4b9..684a7fb34 100644
--- a/novaclient/v2/hypervisors.py
+++ b/novaclient/v2/hypervisors.py
@@ -31,6 +31,7 @@ class Hypervisor(base.Resource):
 
 class HypervisorManager(base.ManagerWithFind):
     resource_class = Hypervisor
+    is_alphanum_id_allowed = True
 
     def list(self, detailed=True):
         """