zuul/tools/zuul-changes.py
Felix Edel 8b7535b7a0 Don't fail on missing change_queues key in status json
Since the pipeline state is stored in ZooKeeper, there could be cases
where the change_queues key is missing in the status json. This makes
API requests fail:

2022-02-22 17:56:18,390 ERROR cherrypy.error.139989033522128: [22/Feb/2022:17:56:18] HTTP
Traceback (most recent call last):
  File "/opt/zuul/lib/python3.8/site-packages/cherrypy/_cprequest.py", line 638, in respond
    self._do_respond(path_info)
  File "/opt/zuul/lib/python3.8/site-packages/cherrypy/_cprequest.py", line 697, in _do_respond
    response.body = self.handler()
  File "/opt/zuul/lib/python3.8/site-packages/cherrypy/lib/encoding.py", line 223, in __call__
    self.body = self.oldhandler(*args, **kwargs)
  File "/opt/zuul/lib/python3.8/site-packages/cherrypy/lib/jsontools.py", line 59, in json_handler
    value = cherrypy.serving.request._json_inner_handler(*args, **kwargs)
  File "/opt/zuul/lib/python3.8/site-packages/cherrypy/_cpdispatch.py", line 54, in __call__
    return self.callable(*self.args, **self.kwargs)
  File "/opt/zuul/lib/python3.8/site-packages/zuul/web/__init__.py", line 1050, in status_change
    return result_filter.filterPayload(payload)
  File "/opt/zuul/lib/python3.8/site-packages/zuul/web/__init__.py", line 193, in filterPayload
    for change_queue in pipeline['change_queues']:
KeyError: 'change_queues'

Fix this by using a .get() call rather than directly accessing the
dictionary key by name.

A similar issue was already fixed in [1].

[1]: https://review.opendev.org/c/zuul/zuul/+/829018

Change-Id: I947f58f02c3da7dad35d1fc186c7026800f7cbdd
2022-02-23 08:25:54 +01:00

96 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright 2013 OpenStack Foundation
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
import json
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('url', help='The URL of the running Zuul instance')
parser.add_argument('tenant', help='The Zuul tenant', nargs='?')
parser.add_argument('pipeline', help='The name of the Zuul pipeline',
nargs='?')
parser.add_argument('--use-config',
metavar='CONFIG',
help='The name of the zuul-client config to use')
options = parser.parse_args()
command = 'zuul-client'
if options.use_config:
command += f' --use-config {options.use_config}'
# Check if tenant is white label
info = json.loads(urlopen('%s/api/info' % options.url).read())
api_tenant = info.get('info', {}).get('tenant')
tenants = []
if api_tenant:
if api_tenant == options.tenant:
tenants.append(None)
else:
print("Error: %s doesn't match tenant %s (!= %s)" % (
options.url, options.tenant, api_tenant))
exit(1)
else:
tenants_url = '%s/api/tenants' % options.url
data = json.loads(urlopen(tenants_url).read())
for tenant in data:
tenants.append(tenant['name'])
for tenant in tenants:
if tenant is None:
status_url = '%s/api/status' % options.url
else:
status_url = '%s/api/tenant/%s/status' % (options.url, tenant)
data = json.loads(urlopen(status_url).read())
for pipeline in data['pipelines']:
if options.pipeline and pipeline['name'] != options.pipeline:
continue
for queue in pipeline.get('change_queues', []):
for head in queue['heads']:
for change in head:
if not change['live']:
continue
if change['id'] and ',' in change['id']:
# change triggered
cid, cps = change['id'].split(',')
print("%s enqueue"
" --tenant %s"
" --pipeline %s"
" --project %s"
" --change %s,%s" % (command, tenant,
pipeline['name'],
change['project_canonical'],
cid, cps))
else:
# ref triggered
cmd = '%s enqueue-ref' \
' --tenant %s' \
' --pipeline %s' \
' --project %s' \
' --ref %s' % (command, tenant,
pipeline['name'],
change['project_canonical'],
change['ref'])
if change['id']:
cmd += ' --newrev %s' % change['id']
print(cmd)