[autotest] Add an RPC to get a list of servers from server DB based on given role and status

BUG=chromium:446333
TEST=local rpc runs
DEPLOY=apache

Change-Id: I39b2c1c8c81b47b492d5eaa642ace234ff86c6a5
Reviewed-on: https://chromium-review.googlesource.com/238760
Trybot-Ready: Dan Shi <dshi@chromium.org>
Tested-by: Dan Shi <dshi@chromium.org>
Reviewed-by: Fang Deng <fdeng@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Commit-Queue: Dan Shi <dshi@chromium.org>
diff --git a/frontend/afe/site_rpc_interface.py b/frontend/afe/site_rpc_interface.py
index 71d9c21..025c087 100644
--- a/frontend/afe/site_rpc_interface.py
+++ b/frontend/afe/site_rpc_interface.py
@@ -27,6 +27,7 @@
 from autotest_lib.server.hosts import moblab_host
 from autotest_lib.site_utils import host_history
 from autotest_lib.site_utils import job_history
+from autotest_lib.site_utils import server_manager_utils
 from autotest_lib.site_utils import stable_version_utils
 
 
@@ -462,6 +463,25 @@
     shard.delete()
 
 
+def get_servers(role=None, status=None):
+    """Get a list of servers with matching role and status.
+
+    @param role: Name of the server role, e.g., drone, scheduler. Default to
+                 None to match any role.
+    @param status: Status of the server, e.g., primary, backup, repair_required.
+                   Default to None to match any server status.
+
+    @raises error.RPCException: If server database is not used.
+    @return: A list of server names for servers with matching role and status.
+    """
+    if not server_manager_utils.use_server_db():
+        raise error.RPCException('Server database is not enabled. Please try '
+                                 'retrieve servers from global config.')
+    servers = server_manager_utils.get_servers(hostname=None, role=role,
+                                               status=status)
+    return [s.get_details() for s in servers]
+
+
 def get_stable_version(board=stable_version_utils.DEFAULT):
     """Get stable version for the given board.
 
diff --git a/frontend/server/models.py b/frontend/server/models.py
index 9a49f77..10be603 100644
--- a/frontend/server/models.py
+++ b/frontend/server/models.py
@@ -66,6 +66,32 @@
         return [r.role for r in self.roles.all()]
 
 
+    def get_details(self):
+        """Get a dictionary with all server details.
+
+        For example:
+        {
+            'hostname': 'server1',
+            'status': 'backup',
+            'roles': ['drone', 'scheduler'],
+            'attributes': {'max_processes': 300}
+        }
+
+        @return: A dictionary with all server details.
+        """
+        details = {}
+        details['hostname'] = self.hostname
+        details['status'] = self.status
+        details['roles'] = self.get_role_names()
+        attributes = dict([(a.attribute, a.value)
+                           for a in self.attributes.all()])
+        details['attributes'] = attributes
+        details['date_created'] = self.date_created
+        details['date_modified'] = self.date_modified
+        details['note'] = self.note
+        return details
+
+
 class ServerRole(dbmodels.Model, model_logic.ModelExtensions):
     """Role associated with hosts."""
     # Valid roles for a server.