blob: 6cd16fbe7b196b40c65c97d81cca6df12394df54 [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Encapsulates a simplistic interface to the buildbucket service."""
import json
from apiclient import discovery
import httplib2
import oauth2client
from google.appengine.ext import ndb
_DISCOVERY_URL = (
'https://cr-buildbucket.appspot.com'
'/_ah/api/discovery/v1/apis/{api}/{apiVersion}/rest')
# Default Buildbucket bucket name.
_BUCKET_NAME = 'master.tryserver.chromium.perf'
# Scope required by the Build Bucket Service.
_OAUTH2_SCOPE = 'https://www.googleapis.com/auth/userinfo.email'
def _DiscoverService():
return discovery.build('buildbucket', 'v1',
discoveryServiceUrl=_DISCOVERY_URL)
class _AuthenticatedHttp(object):
"""Provides access via its constructor to a singleton authenticated http."""
_singleton = None
_singleton_credentials = None
def __new__(cls, credentials):
if credentials and credentials != cls._singleton_credentials:
cls._singleton_credentials = credentials
cls._MakeSingleton(credentials)
if not cls._singleton:
cls._MakeSingleton()
assert cls._singleton
return cls._singleton
@classmethod
def _MakeSingleton(cls, override_credentials=None):
"""Instantiates the singleton."""
# Uses rietveld credentials to authorize an http client. Note this same
# account is authorized for buildbucket.
cls._singleton = httplib2.Http()
if override_credentials:
rietveld_credentials = override_credentials
else:
rietveld_credentials = ndb.Key('RietveldConfig',
'default_rietveld_config').get()
# If we cannot pull the credentials from ndb we simply use the unauthorized
# client. This useful when running a local dev server.
if rietveld_credentials:
creds = oauth2client.client.SignedJwtAssertionCredentials(
rietveld_credentials.client_email,
rietveld_credentials.service_account_key,
_OAUTH2_SCOPE)
creds.authorize(cls._singleton)
def PutJob(job, bucket=_BUCKET_NAME, credentials=None):
"""Creates a job via buildbucket's API."""
parameters = job.GetBuildParameters()
service = _DiscoverService()
request = service.put(
body={
'bucket': bucket,
'parameters_json': json.dumps(parameters),
})
response_content = request.execute(http=_AuthenticatedHttp(credentials))
job.response_fields = response_content.get('build')
return job.response_fields.get('id')
def GetJobStatus(job_id, credentials=None):
"""Gets the details of a job via buildbucket's API."""
service = _DiscoverService()
request = service.get(id=job_id)
response_content = request.execute(http=_AuthenticatedHttp(credentials))
return response_content
# TODO(robertocn): Implement CancelJobByID