web: add /{tenant}/nodes route
This change adds a /nodes route to return the nodes status. Change-Id: I81b495d29659f9a130c75f4c3f32cfd0f47ef15f
This commit is contained in:
parent
22efec8423
commit
8436ed38b7
|
@ -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()
|
||||
|
|
|
@ -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}/'
|
||||
|
|
44
zuul/zk.py
44
zuul/zk.py
|
@ -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():
|
||||
'''
|
||||
|
|
Loading…
Reference in New Issue