From 3fa04e6d2d8bee36c4089620c16ce750dd115ece Mon Sep 17 00:00:00 2001
From: Michal Dulko <michal.dulko@intel.com>
Date: Tue, 19 Aug 2014 13:21:00 +0200
Subject: [PATCH] Add filtering by service to hosts list command

This commit adds --service-name option to host-list command allowing
user to filter hosts by service.

DocImpact
Closes-Bug: 1224763
Change-Id: Ic67deb3af7ddbe23c14fa38ae180d43ab484b78f
---
 novaclient/tests/fixture_data/hosts.py | 10 ++++++++--
 novaclient/tests/v3/test_hosts.py      | 15 +++++++++++++++
 novaclient/v3/hosts.py                 | 16 ++++++++++++++++
 novaclient/v3/shell.py                 |  5 ++++-
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/novaclient/tests/fixture_data/hosts.py b/novaclient/tests/fixture_data/hosts.py
index 6ac217cb0..babfbec7c 100644
--- a/novaclient/tests/fixture_data/hosts.py
+++ b/novaclient/tests/fixture_data/hosts.py
@@ -45,6 +45,7 @@ class BaseFixture(base.Fixture):
         def get_os_hosts(request, context):
             host, query = parse.splitquery(request.url)
             zone = 'nova1'
+            service = None
 
             if query:
                 qs = parse.parse_qs(query)
@@ -53,16 +54,21 @@ class BaseFixture(base.Fixture):
                 except Exception:
                     pass
 
+                try:
+                    service = qs['service'][0]
+                except Exception:
+                    pass
+
             return {
                 'hosts': [
                     {
                         'host': 'host1',
-                        'service': 'nova-compute',
+                        'service': service or 'nova-compute',
                         'zone': zone
                     },
                     {
                         'host': 'host1',
-                        'service': 'nova-cert',
+                        'service': service or 'nova-cert',
                         'zone': zone
                     }
                 ]
diff --git a/novaclient/tests/v3/test_hosts.py b/novaclient/tests/v3/test_hosts.py
index cbd47822b..485633ffe 100644
--- a/novaclient/tests/v3/test_hosts.py
+++ b/novaclient/tests/v3/test_hosts.py
@@ -43,6 +43,21 @@ class HostsTest(utils.FixturedTestCase):
             self.assertIsInstance(h, hosts.Host)
             self.assertEqual(h.zone, 'nova')
 
+    def test_list_host_with_service(self):
+        hs = self.cs.hosts.list(service='nova-compute')
+        self.assert_called('GET', '/os-hosts?service=nova-compute')
+        for h in hs:
+            self.assertIsInstance(h, hosts.Host)
+            self.assertEqual(h.service, 'nova-compute')
+
+    def test_list_host_with_zone_and_service(self):
+        hs = self.cs.hosts.list(service='nova-compute', zone='nova')
+        self.assert_called('GET', '/os-hosts?zone=nova&service=nova-compute')
+        for h in hs:
+            self.assertIsInstance(h, hosts.Host)
+            self.assertEqual(h.zone, 'nova')
+            self.assertEqual(h.service, 'nova-compute')
+
     def test_update_enable(self):
         host = self.cs.hosts.get('sample_host')[0]
         values = {"status": "enabled"}
diff --git a/novaclient/v3/hosts.py b/novaclient/v3/hosts.py
index 5327a2bf3..174b62334 100644
--- a/novaclient/v3/hosts.py
+++ b/novaclient/v3/hosts.py
@@ -33,3 +33,19 @@ class HostManager(hosts.HostManager):
         """Perform an action on a host."""
         url = '/os-hosts/{0}/{1}'.format(host, action)
         return self._get(url, response_key='host')
+
+    def list(self, zone=None, service=None):
+        """List cloud hosts."""
+
+        filters = []
+        if zone:
+            filters.append('zone=%s' % zone)
+        if service:
+            filters.append('service=%s' % service)
+
+        if filters:
+            url = '/os-hosts?%s' % '&'.join(filters)
+        else:
+            url = '/os-hosts'
+
+        return self._list(url, "hosts")
diff --git a/novaclient/v3/shell.py b/novaclient/v3/shell.py
index e88683a4d..2e87a5530 100644
--- a/novaclient/v3/shell.py
+++ b/novaclient/v3/shell.py
@@ -2494,10 +2494,13 @@ def do_host_describe(cs, args):
 @utils.arg('--zone', metavar='<zone>', default=None,
            help='Filters the list, returning only those '
                 'hosts in the availability zone <zone>.')
+@utils.arg('--service-name', metavar='<service>', default=None,
+           help='Filters the list, returning only those '
+                'hosts providing service <service>.')
 def do_host_list(cs, args):
     """List all hosts by service."""
     columns = ["host_name", "service", "zone"]
-    result = cs.hosts.list(args.zone)
+    result = cs.hosts.list(args.zone, args.service_name)
     utils.print_list(result, columns)