Add nodes/nodeset-requests commands
This adds the ability to list and manipulate nodes and nodeset requests. No release note or documentation is added since these are related to nodepool-in-zuul which is in stealth mode. Change-Id: Ia3e987062122e017f19376ab30d9587becedca23
This commit is contained in:
@@ -371,3 +371,59 @@ class ZuulRESTClient(object):
|
||||
req = self.session.get(url)
|
||||
self._check_request_status(req)
|
||||
return req.json()
|
||||
|
||||
def get_nodes(self, tenant):
|
||||
if self.info.get('tenant'):
|
||||
self._check_scope(tenant)
|
||||
suffix = 'nodes'
|
||||
else:
|
||||
suffix = f'tenant/{tenant}/nodes'
|
||||
url = urllib.parse.urljoin(
|
||||
self.base_url,
|
||||
suffix)
|
||||
req = self.session.get(url)
|
||||
self._check_request_status(req)
|
||||
return req.json()
|
||||
|
||||
def put_node(self, tenant, node, **args):
|
||||
if not self.auth_token:
|
||||
raise Exception('Auth Token required')
|
||||
if self.info.get('tenant'):
|
||||
self._check_scope(tenant)
|
||||
suffix = f'nodes/{node}'
|
||||
else:
|
||||
suffix = f'tenant/{tenant}/nodes/{node}'
|
||||
url = urllib.parse.urljoin(
|
||||
self.base_url,
|
||||
suffix)
|
||||
req = self.session.put(url, json=args)
|
||||
self._check_request_status(req)
|
||||
return req.json()
|
||||
|
||||
def get_nodeset_requests(self, tenant):
|
||||
if self.info.get('tenant'):
|
||||
self._check_scope(tenant)
|
||||
suffix = 'nodeset-requests'
|
||||
else:
|
||||
suffix = f'tenant/{tenant}/nodeset-requests'
|
||||
url = urllib.parse.urljoin(
|
||||
self.base_url,
|
||||
suffix)
|
||||
req = self.session.get(url)
|
||||
self._check_request_status(req)
|
||||
return req.json()
|
||||
|
||||
def delete_nodeset_request(self, tenant, request):
|
||||
if not self.auth_token:
|
||||
raise Exception('Auth Token required')
|
||||
if self.info.get('tenant'):
|
||||
self._check_scope(tenant)
|
||||
suffix = f'nodeset-requests/{request}'
|
||||
else:
|
||||
suffix = f'tenant/{tenant}/nodeset-requests/{request}'
|
||||
url = urllib.parse.urljoin(
|
||||
self.base_url,
|
||||
suffix)
|
||||
req = self.session.delete(url)
|
||||
self._check_request_status(req)
|
||||
return (req.status_code == 204)
|
||||
|
@@ -130,6 +130,10 @@ class ZuulClient():
|
||||
self.add_build_info_subparser(subparsers)
|
||||
self.add_job_graph_subparser(subparsers)
|
||||
self.add_freeze_job_subparser(subparsers)
|
||||
self.add_node_list_subparser(subparsers)
|
||||
self.add_node_set_state_subparser(subparsers)
|
||||
self.add_nodeset_request_list_subparser(subparsers)
|
||||
self.add_nodeset_request_delete_subparser(subparsers)
|
||||
|
||||
return subparsers
|
||||
|
||||
@@ -556,6 +560,84 @@ class ZuulClient():
|
||||
client.tenant_state(tenant, **kwargs)
|
||||
return True
|
||||
|
||||
def add_node_list_subparser(self, subparsers):
|
||||
cmd = subparsers.add_parser('node-list',
|
||||
help='list nodes')
|
||||
cmd.add_argument('--tenant', help='tenant name',
|
||||
required=False, default='')
|
||||
cmd.set_defaults(func=self.node_list)
|
||||
self.cmd_node_list = cmd
|
||||
|
||||
def node_list(self):
|
||||
client = self.get_client()
|
||||
self._check_tenant_scope(client)
|
||||
tenant = self.tenant()
|
||||
nodes = client.get_nodes(tenant)
|
||||
formatted_result = self.formatter('NodeList')(nodes)
|
||||
print(formatted_result)
|
||||
|
||||
return True
|
||||
|
||||
def add_node_set_state_subparser(self, subparsers):
|
||||
cmd = subparsers.add_parser('node-set-state',
|
||||
help='set the state of a node')
|
||||
cmd.add_argument('--tenant', help='tenant name',
|
||||
required=False, default='')
|
||||
cmd.add_argument('node', help='node id')
|
||||
cmd.add_argument('state',
|
||||
help='new node state',
|
||||
choices=[
|
||||
'hold',
|
||||
'used',
|
||||
])
|
||||
cmd.set_defaults(func=self.node_set_state)
|
||||
self.cmd_node_set_state = cmd
|
||||
|
||||
def node_set_state(self):
|
||||
client = self.get_client()
|
||||
self._check_tenant_scope(client)
|
||||
tenant = self.tenant()
|
||||
self.log.info('Setting node with arguments: %s %s',
|
||||
self.args.node, self.args.state)
|
||||
r = client.put_node(tenant, self.args.node, state=self.args.state)
|
||||
return not r
|
||||
|
||||
def add_nodeset_request_list_subparser(self, subparsers):
|
||||
cmd = subparsers.add_parser('nodeset-request-list',
|
||||
help='list nodeset requests')
|
||||
cmd.add_argument('--tenant', help='tenant name',
|
||||
required=False, default='')
|
||||
cmd.set_defaults(func=self.nodeset_request_list)
|
||||
self.cmd_nodeset_request_list = cmd
|
||||
|
||||
def nodeset_request_list(self):
|
||||
client = self.get_client()
|
||||
self._check_tenant_scope(client)
|
||||
tenant = self.tenant()
|
||||
requests = client.get_nodeset_requests(tenant)
|
||||
formatted_result = self.formatter('NodesetRequestList')(requests)
|
||||
print(formatted_result)
|
||||
|
||||
return True
|
||||
|
||||
def add_nodeset_request_delete_subparser(self, subparsers):
|
||||
cmd = subparsers.add_parser('nodeset-request-delete',
|
||||
help='delete a nodeset request')
|
||||
cmd.add_argument('--tenant', help='tenant name',
|
||||
required=False, default='')
|
||||
cmd.add_argument('request', help='nodeset request id')
|
||||
cmd.set_defaults(func=self.nodeset_request_delete)
|
||||
self.cmd_nodeset_request_delete = cmd
|
||||
|
||||
def nodeset_request_delete(self):
|
||||
client = self.get_client()
|
||||
self._check_tenant_scope(client)
|
||||
tenant = self.tenant()
|
||||
self.log.info('Deleting nodeset request: %s',
|
||||
self.args.request)
|
||||
r = client.delete_nodeset_request(tenant, self.args.request)
|
||||
return r
|
||||
|
||||
def get_config_section(self):
|
||||
conf_sections = self.config.sections()
|
||||
if len(conf_sections) == 1 and self.args.zuul_config is None:
|
||||
|
@@ -70,6 +70,12 @@ class BaseFormatter:
|
||||
def formatFreezeJob(self, data):
|
||||
raise NotImplementedError
|
||||
|
||||
def formatNodeList(self, data):
|
||||
raise NotImplementedError
|
||||
|
||||
def formatNodesetRequestList(self, data):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class JSONFormatter(BaseFormatter):
|
||||
def __call__(self, data) -> str:
|
||||
@@ -332,6 +338,44 @@ class PrettyTableFormatter(BaseFormatter):
|
||||
ret += printer.pformat(data['vars'])
|
||||
return ret
|
||||
|
||||
def formatNodeList(self, data) -> str:
|
||||
table = prettytable.PrettyTable(
|
||||
field_names=[
|
||||
'UUID', 'Labels', 'Connection', 'Provider', 'State',
|
||||
'State Time', 'Comment'
|
||||
])
|
||||
|
||||
for node in data:
|
||||
table.add_row([
|
||||
node.get('uuid', 'N/A'),
|
||||
node.get('type', 'N/A'),
|
||||
node.get('connection_type', 'N/A'),
|
||||
node.get('provider', 'N/A'),
|
||||
node.get('state', 'N/A'),
|
||||
node.get('state_time', 'N/A'),
|
||||
node.get('comment', 'N/A'),
|
||||
])
|
||||
return str(table)
|
||||
|
||||
def formatNodesetRequestList(self, data) -> str:
|
||||
table = prettytable.PrettyTable(
|
||||
field_names=[
|
||||
'UUID', 'Labels', 'State', 'Request Time', 'Buildset',
|
||||
'Pipeline', 'Job'
|
||||
])
|
||||
|
||||
for node in data:
|
||||
table.add_row([
|
||||
node.get('uuid', 'N/A'),
|
||||
node.get('labels', 'N/A'),
|
||||
node.get('state', 'N/A'),
|
||||
node.get('request_time', 'N/A'),
|
||||
node.get('buildset_uuid', 'N/A'),
|
||||
node.get('pipeline_name', 'N/A'),
|
||||
node.get('job_name', 'N/A'),
|
||||
])
|
||||
return str(table)
|
||||
|
||||
|
||||
class DotFormatter(BaseFormatter):
|
||||
"""Format for graphviz"""
|
||||
|
Reference in New Issue
Block a user