zuul-client/zuulclient/api/__init__.py
Matthieu Huin ab852e407a Fix integration with Zuul before release
* Make default config files location a class attribute
* Add missing __init__.py file
* Fix incorrect parameter "change_ids" to "changes" in promote
* Add release notes to documentation

Change-Id: Ifdb6186e09cbc52cbcb1aea56863c25ddec22203
2020-09-24 18:01:42 +02:00

155 lines
5.4 KiB
Python

# Copyright 2020 Red Hat, inc
#
# 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.
import requests
import urllib.parse
class ZuulRESTException(Exception):
pass
class ZuulRESTClient(object):
"""Basic client for Zuul's REST API"""
def __init__(self, url, verify=False, auth_token=None):
self.url = url
if not self.url.endswith('/'):
self.url += '/'
self.auth_token = auth_token
self.verify = verify
self.base_url = urllib.parse.urljoin(self.url, 'api/')
self.session = requests.Session()
self.session.verify = self.verify
if self.auth_token:
self.session.headers.update(
dict(Authorization='Bearer %s' % self.auth_token))
def _check_request_status(self, req):
try:
req.raise_for_status()
except Exception as e:
if req.status_code == 401:
raise ZuulRESTException(
'Unauthorized - your token might be invalid or expired.')
elif req.status_code == 403:
raise ZuulRESTException(
'Insufficient privileges to perform the action.')
else:
raise ZuulRESTException(
'Unknown error code %s: "%s"' % (req.status_code, e))
def autohold(self, tenant, project, job, change, ref,
reason, count, node_hold_expiration):
if not self.auth_token:
raise Exception('Auth Token required')
args = {"reason": reason,
"count": count,
"job": job,
"change": change,
"ref": ref,
"node_hold_expiration": node_hold_expiration}
url = urllib.parse.urljoin(
self.base_url,
'tenant/%s/project/%s/autohold' % (tenant, project))
req = self.session.post(url, json=args)
self._check_request_status(req)
return req.json()
def autohold_list(self, tenant):
url = urllib.parse.urljoin(
self.base_url,
'tenant/%s/autohold' % tenant)
# auth not needed here
req = self.session.get(url)
self._check_request_status(req)
resp = req.json()
return resp
def autohold_delete(self, id, tenant):
if not self.auth_token:
raise Exception('Auth Token required')
url = urllib.parse.urljoin(
self.base_url,
'tenant/%s/autohold/%s' % (tenant, id))
req = self.session.delete(url)
self._check_request_status(req)
# DELETE doesn't return a body, just the HTTP code
return (req.status_code == 204)
def autohold_info(self, id, tenant):
url = urllib.parse.urljoin(
self.base_url,
'tenant/%s/autohold/%s' % (tenant, id))
# auth not needed here
req = self.session.get(url)
self._check_request_status(req)
resp = req.json()
return resp
def enqueue(self, tenant, pipeline, project, change):
if not self.auth_token:
raise Exception('Auth Token required')
args = {"change": change,
"pipeline": pipeline}
url = urllib.parse.urljoin(
self.base_url,
'tenant/%s/project/%s/enqueue' % (tenant, project))
req = self.session.post(url, json=args)
self._check_request_status(req)
return req.json()
def enqueue_ref(self, tenant, pipeline, project, ref, oldrev, newrev):
if not self.auth_token:
raise Exception('Auth Token required')
args = {"ref": ref,
"oldrev": oldrev,
"newrev": newrev,
"pipeline": pipeline}
url = urllib.parse.urljoin(
self.base_url,
'tenant/%s/project/%s/enqueue' % (tenant, project))
req = self.session.post(url, json=args)
self._check_request_status(req)
return req.json()
def dequeue(self, tenant, pipeline, project, change=None, ref=None):
if not self.auth_token:
raise Exception('Auth Token required')
args = {"pipeline": pipeline}
if change and not ref:
args['change'] = change
elif ref and not change:
args['ref'] = ref
else:
raise Exception('need change OR ref')
url = urllib.parse.urljoin(
self.base_url,
'tenant/%s/project/%s/dequeue' % (tenant, project))
req = self.session.post(url, json=args)
self._check_request_status(req)
return req.json()
def promote(self, tenant, pipeline, change_ids):
if not self.auth_token:
raise Exception('Auth Token required')
args = {'pipeline': pipeline,
'changes': change_ids}
url = urllib.parse.urljoin(
self.base_url,
'tenant/%s/promote' % tenant)
req = self.session.post(url, json=args)
self._check_request_status(req)
return req.json()