| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from collections import defaultdict | 5 from collections import defaultdict |
| 6 import datetime | 6 import datetime |
| 7 import json | 7 import json |
| 8 | 8 |
| 9 from apiclient import discovery | 9 from apiclient import discovery |
| 10 from apiclient.errors import HttpError | 10 from apiclient.errors import HttpError |
| 11 import httplib2 | 11 import httplib2 |
| 12 from oauth2client import client | 12 from oauth2client import client |
| 13 | 13 |
| 14 from infra_libs import ts_mon | 14 from infra_libs import ts_mon |
| 15 | 15 |
| 16 | 16 |
| 17 # Dictionary mapping whitelisted lower-case labels to corresponding tree names. | 17 # Dictionary mapping whitelisted lower-case labels to corresponding tree names. |
| 18 WHITELISTED_LABELS = {'sheriff-chromium': 'chromium', | 18 WHITELISTED_LABELS = {'sheriff-chromium': 'chromium', |
| 19 'sheriff-blink': 'blink', | 19 'sheriff-blink': 'blink', |
| 20 'infra-troopers': 'trooper'} | 20 'infra-troopers': 'trooper'} |
| 21 BATCH_SIZE = 10 | 21 BATCH_SIZE = 10 |
| 22 | 22 |
| 23 | 23 |
| 24 def _build_crbug_service(crbug_service_account, | 24 def _build_crbug_service(crbug_service_account): # pragma: no cover |
| 25 use_monorail): # pragma: no cover | |
| 26 with open(crbug_service_account) as crbug_sa_file: | 25 with open(crbug_service_account) as crbug_sa_file: |
| 27 service_account = json.load(crbug_sa_file) | 26 service_account = json.load(crbug_sa_file) |
| 28 | 27 |
| 29 if use_monorail: | |
| 30 api_name = 'monorail' | |
| 31 api_version = 'v1' | |
| 32 scope = 'https://www.googleapis.com/auth/userinfo.email' | |
| 33 discovery_url = ('https://monorail-prod.appspot.com/_ah/api/discovery/v1/' | |
| 34 'apis/{api}/{apiVersion}/rest') | |
| 35 else: | |
| 36 api_name = 'projecthosting' | |
| 37 api_version = 'v2' | |
| 38 scope = 'https://www.googleapis.com/auth/projecthosting' | |
| 39 discovery_url = ('https://www.googleapis.com/discovery/v1/apis/{api}/' | |
| 40 '{apiVersion}/rest') | |
| 41 | |
| 42 creds = client.SignedJwtAssertionCredentials( | 28 creds = client.SignedJwtAssertionCredentials( |
| 43 service_account['client_email'], service_account['private_key'], scope) | 29 service_account['client_email'], service_account['private_key'], |
| 30 'https://www.googleapis.com/auth/userinfo.email') |
| 44 http = creds.authorize(httplib2.Http()) | 31 http = creds.authorize(httplib2.Http()) |
| 45 return discovery.build( | 32 return discovery.build( |
| 46 api_name, api_version, discoveryServiceUrl=discovery_url, http=http) | 33 'monorail', 'v1', discoveryServiceUrl='https://monorail-prod.appspot.com/' |
| 34 '_ah/api/discovery/v1/apis/{api}/{apiVersion}/rest', http=http) |
| 47 | 35 |
| 48 | 36 |
| 49 def _list_issues(crbug_service_account, use_monorail): | 37 def _list_issues(crbug_service_account): |
| 50 service = _build_crbug_service(crbug_service_account, use_monorail) | 38 service = _build_crbug_service(crbug_service_account) |
| 51 issues = [] | 39 issues = [] |
| 52 seen_issue_ids = set() | 40 seen_issue_ids = set() |
| 53 for whitelisted_label in WHITELISTED_LABELS: | 41 for whitelisted_label in WHITELISTED_LABELS: |
| 54 start_index = 0 | 42 start_index = 0 |
| 55 while True: | 43 while True: |
| 56 request = service.issues().list( | 44 request = service.issues().list( |
| 57 projectId='chromium', label=whitelisted_label, | 45 projectId='chromium', label=whitelisted_label, |
| 58 startIndex=start_index, maxResults=BATCH_SIZE, can='open') | 46 startIndex=start_index, maxResults=BATCH_SIZE, can='open') |
| 59 response = request.execute(num_retries=5) | 47 response = request.execute(num_retries=5) |
| 60 | 48 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 75 # such as when an issue is closed and then immediately reopened again | 63 # such as when an issue is closed and then immediately reopened again |
| 76 # before we run the next query. | 64 # before we run the next query. |
| 77 new_issues = [issue for issue in response['items'] | 65 new_issues = [issue for issue in response['items'] |
| 78 if issue['id'] not in seen_issue_ids] | 66 if issue['id'] not in seen_issue_ids] |
| 79 issues.extend(new_issues) | 67 issues.extend(new_issues) |
| 80 seen_issue_ids.update(issue['id'] for issue in new_issues) | 68 seen_issue_ids.update(issue['id'] for issue in new_issues) |
| 81 | 69 |
| 82 return issues | 70 return issues |
| 83 | 71 |
| 84 | 72 |
| 85 def query(crbug_service_account, use_monorail): | 73 def query(crbug_service_account): |
| 86 """Queries issue tracker for issues with whitelisted labels. | 74 """Queries issue tracker for issues with whitelisted labels. |
| 87 | 75 |
| 88 Raises QuotaExceededError if requests result in quota errors. Callers should | 76 Raises QuotaExceededError if requests result in quota errors. Callers should |
| 89 retry calling this function again later. | 77 retry calling this function again later. |
| 90 | 78 |
| 91 Returns: | 79 Returns: |
| 92 A dict mapping tree name to a list of issue dicts, each dict having the | 80 A dict mapping tree name to a list of issue dicts, each dict having the |
| 93 following properties: | 81 following properties: |
| 94 - key: 'crbug_issue_id:' + issue id. | 82 - key: 'crbug_issue_id:' + issue id. |
| 95 - title: summary of the issue. | 83 - title: summary of the issue. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 ... | 126 ... |
| 139 } | 127 } |
| 140 """ | 128 """ |
| 141 # Initialize each tree with an empty list to ensure that we POST updates into | 129 # Initialize each tree with an empty list to ensure that we POST updates into |
| 142 # each tree's endpoint even if there are no current issues. | 130 # each tree's endpoint even if there are no current issues. |
| 143 sheriff_issues = {} | 131 sheriff_issues = {} |
| 144 whitelisted_trees = WHITELISTED_LABELS.values() | 132 whitelisted_trees = WHITELISTED_LABELS.values() |
| 145 for tree_name in whitelisted_trees: | 133 for tree_name in whitelisted_trees: |
| 146 sheriff_issues[tree_name] = [] | 134 sheriff_issues[tree_name] = [] |
| 147 | 135 |
| 148 raw_issues = _list_issues(crbug_service_account, use_monorail) | 136 raw_issues = _list_issues(crbug_service_account) |
| 149 for raw_issue in raw_issues: | 137 for raw_issue in raw_issues: |
| 150 sheriff_issue = {'key': 'crbug_issue_id:%d' % raw_issue['id'], | 138 sheriff_issue = {'key': 'crbug_issue_id:%d' % raw_issue['id'], |
| 151 'title': raw_issue['title'], | 139 'title': raw_issue['title'], |
| 152 'body': '', | 140 'body': '', |
| 153 'links': [{ | 141 'links': [{ |
| 154 'title': 'crbug.com/%d' % raw_issue['id'], | 142 'title': 'crbug.com/%d' % raw_issue['id'], |
| 155 'href': 'https://crbug.com/%s' % raw_issue['id'] | 143 'href': 'https://crbug.com/%s' % raw_issue['id'] |
| 156 }], | 144 }], |
| 157 'start_time': raw_issue['published'], | 145 'start_time': raw_issue['published'], |
| 158 'time': datetime.datetime.utcnow().isoformat() + 'Z', | 146 'time': datetime.datetime.utcnow().isoformat() + 'Z', |
| (...skipping 17 matching lines...) Expand all Loading... |
| 176 | 164 |
| 177 sheriff_issue['tags'] = sorted(tags) # converts back to list | 165 sheriff_issue['tags'] = sorted(tags) # converts back to list |
| 178 if severity is not None: | 166 if severity is not None: |
| 179 sheriff_issue['severity'] = severity | 167 sheriff_issue['severity'] = severity |
| 180 | 168 |
| 181 # We assume that a tags have 1:1 mapping to trees here. | 169 # We assume that a tags have 1:1 mapping to trees here. |
| 182 for tree_name in sheriff_issue['tags']: | 170 for tree_name in sheriff_issue['tags']: |
| 183 sheriff_issues[tree_name].append(sheriff_issue) | 171 sheriff_issues[tree_name].append(sheriff_issue) |
| 184 | 172 |
| 185 return sheriff_issues | 173 return sheriff_issues |
| OLD | NEW |