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
|
'voting': True
|
||||||
}], data)
|
}], 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):
|
def test_web_labels_list(self):
|
||||||
# can we fetch the labels list
|
# can we fetch the labels list
|
||||||
data = self.get_url('api/tenant/tenant-one/labels').json()
|
data = self.get_url('api/tenant/tenant-one/labels').json()
|
||||||
|
@ -356,6 +356,21 @@ class ZuulWebAPI(object):
|
|||||||
resp.headers['Access-Control-Allow-Origin'] = '*'
|
resp.headers['Access-Control-Allow-Origin'] = '*'
|
||||||
return ret
|
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.expose
|
||||||
@cherrypy.tools.save_params()
|
@cherrypy.tools.save_params()
|
||||||
def key(self, tenant, project):
|
def key(self, tenant, project):
|
||||||
@ -594,6 +609,8 @@ class ZuulWeb(object):
|
|||||||
controller=api, action='pipelines')
|
controller=api, action='pipelines')
|
||||||
route_map.connect('api', '/api/tenant/{tenant}/labels',
|
route_map.connect('api', '/api/tenant/{tenant}/labels',
|
||||||
controller=api, action='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',
|
route_map.connect('api', '/api/tenant/{tenant}/key/{project:.*}.pub',
|
||||||
controller=api, action='key')
|
controller=api, action='key')
|
||||||
route_map.connect('api', '/api/tenant/{tenant}/'
|
route_map.connect('api', '/api/tenant/{tenant}/'
|
||||||
|
44
zuul/zk.py
44
zuul/zk.py
@ -294,6 +294,7 @@ class ZooKeeper(object):
|
|||||||
return count
|
return count
|
||||||
|
|
||||||
# Copy of nodepool/zk.py begins here
|
# Copy of nodepool/zk.py begins here
|
||||||
|
NODE_ROOT = "/nodepool/nodes"
|
||||||
LAUNCHER_ROOT = "/nodepool/launchers"
|
LAUNCHER_ROOT = "/nodepool/launchers"
|
||||||
|
|
||||||
def _bytesToDict(self, data):
|
def _bytesToDict(self, data):
|
||||||
@ -302,6 +303,9 @@ class ZooKeeper(object):
|
|||||||
def _launcherPath(self, launcher):
|
def _launcherPath(self, launcher):
|
||||||
return "%s/%s" % (self.LAUNCHER_ROOT, launcher)
|
return "%s/%s" % (self.LAUNCHER_ROOT, launcher)
|
||||||
|
|
||||||
|
def _nodePath(self, node):
|
||||||
|
return "%s/%s" % (self.NODE_ROOT, node)
|
||||||
|
|
||||||
def getRegisteredLaunchers(self):
|
def getRegisteredLaunchers(self):
|
||||||
'''
|
'''
|
||||||
Get a list of all launchers that have registered with ZooKeeper.
|
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)))
|
objs.append(Launcher.fromDict(self._bytesToDict(data)))
|
||||||
return objs
|
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():
|
class Launcher():
|
||||||
'''
|
'''
|
||||||
|
Loading…
Reference in New Issue
Block a user