blob: b2359f30e06ec20d4526134602a779601713ecd3 [file] [log] [blame]
Xinan Linc61196b2019-08-13 10:37:30 -07001# Copyright 2017 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Module for interacting with Buildbucket."""
6import datetime
7
8import constants
9import file_getter
10
11from chromite.api.gen.test_platform import request_pb2
12from components.prpc import client as prpc_client
13from components import auth
14
15from google.protobuf import duration_pb2, json_format, struct_pb2
16from infra_libs.buildbucket.proto import rpc_pb2, build_pb2, common_pb2
17from infra_libs.buildbucket.proto.rpc_prpc_pb2 import BuildsServiceDescription
18
19from oauth2client import service_account
20from oauth2client.contrib import appengine
21
22
23NONSTANDARD_POOL_NAMES = {
24 'cq': request_pb2.Request.Params.Scheduling.MANAGED_POOL_CQ,
25 'bvt': request_pb2.Request.Params.Scheduling.MANAGED_POOL_BVT,
26 'suites': request_pb2.Request.Params.Scheduling.MANAGED_POOL_SUITES,
27 'cts': request_pb2.Request.Params.Scheduling.MANAGED_POOL_CTS,
28 'cts-perbuild': request_pb2.Request.Params.Scheduling.MANAGED_POOL_CTS_PERBUILD,
29 'continuous': request_pb2.Request.Params.Scheduling.MANAGED_POOL_CONTINUOUS,
30 'arc-presubmit': request_pb2.Request.Params.Scheduling.MANAGED_POOL_ARC_PRESUBMIT,
31 'quota': request_pb2.Request.Params.Scheduling.MANAGED_POOL_QUOTA,
32}
33
34def _get_client(address):
35 """Create a prpc client instance for given address."""
36 return prpc_client.Client(address, BuildsServiceDescription)
37
38
39class TestPlatformClient(object):
40 """prpc client for cros_test_platform, aka frontdoor."""
41
42 def __init__(self, address, project, bucket, builder):
43 self.client = _get_client(address)
44 self.builder = build_pb2.BuilderID(project=project,
45 bucket=bucket,
46 builder=builder)
47 self.scope = 'https://www.googleapis.com/auth/userinfo.email'
48 self.running_env = constants.environment()
49
50 def dummy_run(self):
51 """Perform a dummy run of prpc call to cros_test_platform-dev."""
52
53 req = request_pb2.Request()
54 req_struct = self._request_pb2_to_struct_pb2(req)
55
56 # Use the staging service account to authorize the request.
57 sa_key = self._gen_service_account_key(
58 file_getter.STAGING_CLIENT_SECRETS_FILE)
59 cred = prpc_client.service_account_credentials(service_account_key=sa_key)
60 return self.client.ScheduleBuild(
61 self._build_request(req_struct), credentials=cred)
62
63 # TODO(linxinan): Handle exceptions when fail to transform proto.
64 def _request_pb2_to_struct_pb2(self, req):
65 """"Transform test_platform_request to google struct proto.
66
67 Args:
68 req: A request_pb2 instance.
69
70 Returns:
71 A struct_pb2 instance.
72 """
73 json = json_format.MessageToJson(req)
74 structpb = struct_pb2.Struct()
75 return json_format.Parse(json, structpb, ignore_unknown_fields=True)
76
77 def _build_request(self, req_struct):
78 """"Generate ScheduleBuildRequest for calling buildbucket.
79
80 Args:
81 req_struct: A struct_pb2 instance.
82
83 Returns:
84 A ScheduleBuildRequest instance.
85 """
86 recipe_struct = struct_pb2.Struct(fields={
87 'request': struct_pb2.Value(struct_value=req_struct)})
88 return rpc_pb2.ScheduleBuildRequest(builder=self.builder,
89 properties=recipe_struct)
90
91 def _gen_service_account_key(self, sa):
92 """"Generate credentials to authorize the call.
93
94 Args:
95 sa: a string of the path to the service account json file.
96
97 Returns:
98 a service account key.
99 """
100 service_credentials = service_account.ServiceAccountCredentials
101 key = service_credentials.from_json_keyfile_name(sa, self.scope)
102 return auth.ServiceAccountKey(
103 client_email=key.service_account_email,
104 private_key=key._private_key_pkcs8_pem,
105 private_key_id=key._private_key_id)