web: add /{tenant}/nodes route

This change adds a /nodes route to return the nodes status.

Change-Id: I81b495d29659f9a130c75f4c3f32cfd0f47ef15f
This commit is contained in:
Tristan Cacqueray 2018-03-17 15:49:43 +00:00 committed by Joshua Hesketh
parent 22efec8423
commit 8436ed38b7
3 changed files with 68 additions and 0 deletions

View File

@ -372,6 +372,13 @@ class TestWeb(BaseTestWeb):
'voting': True
}], data)
def test_web_nodes_list(self):
# can we fetch the nodes list
data = self.get_url('api/tenant/tenant-one/nodes').json()
self.assertGreater(len(data), 0)
self.assertEqual("test-provider", data[0]["provider"])
self.assertEqual("label1", data[0]["type"])
def test_web_labels_list(self):
# can we fetch the labels list
data = self.get_url('api/tenant/tenant-one/labels').json()

View File

@ -356,6 +356,21 @@ class ZuulWebAPI(object):
resp.headers['Access-Control-Allow-Origin'] = '*'
return ret
@cherrypy.expose
@cherrypy.tools.save_params()
@cherrypy.tools.json_out(content_type='application/json; charset=utf-8')
def nodes(self, tenant):
ret = []
for node in self.zk.nodeIterator():
node_data = {}
for key in ("id", "type", "connection_type", "external_id",
"provider", "state", "state_time", "comment"):
node_data[key] = node.get(key)
ret.append(node_data)
resp = cherrypy.response
resp.headers['Access-Control-Allow-Origin'] = '*'
return ret
@cherrypy.expose
@cherrypy.tools.save_params()
def key(self, tenant, project):
@ -594,6 +609,8 @@ class ZuulWeb(object):
controller=api, action='pipelines')
route_map.connect('api', '/api/tenant/{tenant}/labels',
controller=api, action='labels')
route_map.connect('api', '/api/tenant/{tenant}/nodes',
controller=api, action='nodes')
route_map.connect('api', '/api/tenant/{tenant}/key/{project:.*}.pub',
controller=api, action='key')
route_map.connect('api', '/api/tenant/{tenant}/'

View File

@ -294,6 +294,7 @@ class ZooKeeper(object):
return count
# Copy of nodepool/zk.py begins here
NODE_ROOT = "/nodepool/nodes"
LAUNCHER_ROOT = "/nodepool/launchers"
def _bytesToDict(self, data):
@ -302,6 +303,9 @@ class ZooKeeper(object):
def _launcherPath(self, launcher):
return "%s/%s" % (self.LAUNCHER_ROOT, launcher)
def _nodePath(self, node):
return "%s/%s" % (self.NODE_ROOT, node)
def getRegisteredLaunchers(self):
'''
Get a list of all launchers that have registered with ZooKeeper.
@ -325,6 +329,46 @@ class ZooKeeper(object):
objs.append(Launcher.fromDict(self._bytesToDict(data)))
return objs
def getNodes(self):
'''
Get the current list of all nodes.
:returns: A list of nodes.
'''
try:
return self.client.get_children(self.NODE_ROOT)
except kze.NoNodeError:
return []
def getNode(self, node):
'''
Get the data for a specific node.
:param str node: The node ID.
:returns: The node data, or None if the node was not found.
'''
path = self._nodePath(node)
try:
data, stat = self.client.get(path)
except kze.NoNodeError:
return None
if not data:
return None
d = self._bytesToDict(data)
d['id'] = node
return d
def nodeIterator(self):
'''
Utility generator method for iterating through all nodes.
'''
for node_id in self.getNodes():
node = self.getNode(node_id)
if node:
yield node
class Launcher():
'''