diff options
author | Lars Wirzenius <liw@liw.fi> | 2012-08-11 12:10:45 +0100 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2012-08-11 12:10:45 +0100 |
commit | 67acf03ae11343a5299218bd14c660eeb8ff6e59 (patch) | |
tree | 8607b6e01d900992471633d2a66c932b13539a92 /simplejenkinsapi | |
parent | 9ab26c8577cc723fb947f6fa70a2a4bffdb81c7a (diff) | |
download | jenkinstool-67acf03ae11343a5299218bd14c660eeb8ff6e59.tar.gz |
Move Jenkins class into package, fix so ./check passes
Diffstat (limited to 'simplejenkinsapi')
-rw-r--r-- | simplejenkinsapi/__init__.py | 4 | ||||
-rw-r--r-- | simplejenkinsapi/api.py | 126 |
2 files changed, 128 insertions, 2 deletions
diff --git a/simplejenkinsapi/__init__.py b/simplejenkinsapi/__init__.py index 693b180..6d18b76 100644 --- a/simplejenkinsapi/__init__.py +++ b/simplejenkinsapi/__init__.py @@ -16,5 +16,5 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. -from .jobconfig import JobConfig - +from jobconfig import JobConfig +from api import Jenkins diff --git a/simplejenkinsapi/api.py b/simplejenkinsapi/api.py new file mode 100644 index 0000000..5571298 --- /dev/null +++ b/simplejenkinsapi/api.py @@ -0,0 +1,126 @@ +# simplejenkinsapi/api.py -- simple job management in Jenkins +# +# Copyright 2012 Lars Wirzenius +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +'''Simple job management in Jenkins. + +This module provides tools for listing, creating, updating, and +removing jobs in a running Jenkins instance, using its HTTP API. + +''' + + +import httplib +import json +import logging +import urlparse + + +class Jenkins(object): + + '''Access a running Jenkins server.''' + + def __init__(self, url): # pragma: no cover + self._url = url + + def _connect(self): # pragma: no cover + '''Connect to HTTP server, return httplib.HTTPConnection.''' + (scheme, netloc, path, params, query, + fragment) = urlparse.urlparse(self._url) + assert path == '/' + assert params == '' + assert fragment == '' + + if ':' in netloc: + host, port = netloc.split(':', 1) + port = int(port) + else: + host = netloc + port = None + + if scheme == 'https': + return httplib.HTTPSConnection(host, port) + else: + return httplib.HTTPConnection(host, port) + + def _do(self, method, path, body='', headers={}): + '''Make an HTTP request, return result. + + If server returned JSON, return it as a Python object. + Otherwise, return as string. + + ''' + + conn = self._connect() + conn.request(method, path, body, headers) + resp = conn.getresponse() + text = resp.read() + + logging.debug('HTTP status: %d' % resp.status) + logging.debug('HTTP reason: %s' % resp.reason) + logging.debug('HTTP text: %s' % repr(text)) + + ok = [httplib.OK, httplib.FOUND] + if resp.status not in ok: # pragma: no cover + raise httplib.HTTPException('Error %d (%s) from server:\n%s' % + (resp.status, resp.reason, text)) + + typ = resp.getheader('Content-Type') or 'application/octet-stream' + if typ == 'application/json' or typ.startswith('application/json;'): + return json.loads(text) + else: + return text + + def list_jobs(self): + '''Return list of job ids on the server.''' + + obj = self._do('GET', '/api/json') + logging.debug('obj: %s' % repr(obj)) + return [job['name'] for job in obj['jobs']] + + def delete_job(self, job_id): + '''Delete a job from Jenkins server, given job id.''' + + self._do('POST', '/job/%s/doDelete' % job_id) + + def create_job(self, job_id, config_xml): + '''Create a new job. + + ``config_xml`` is a string containing the XML format configuration + of the job. + + ''' + + self._do('POST', '/createItem?name=%s' % job_id, body=config_xml, + headers={'Content-Type': 'text/xml'}) + + def update_job(self, job_id, config_xml): + '''Update the configuration of a new job. + + ``config_xml`` is a string containing the XML format configuration + of the job. + + ''' + + self._do('POST', '/job/%s/config.xml' % job_id, body=config_xml, + headers={ 'Content-Type': 'text/xml' }) + + def get_job_config(self, job_id): + '''Return the XML configuration of a job.''' + + return self._do('GET', '/job/%s/config.xml' % job_id) + |