Kevin Cheng | 5272ca7 | 2016-01-11 11:55:31 -0800 | [diff] [blame] | 1 | # Copyright 2016 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 | import json |
| 6 | import urllib2 |
| 7 | |
Kevin Cheng | 5272ca7 | 2016-01-11 11:55:31 -0800 | [diff] [blame] | 8 | # HWID info types to request. |
| 9 | HWID_INFO_LABEL = 'dutlabel' |
| 10 | HWID_INFO_BOM = 'bom' |
| 11 | HWID_INFO_SKU = 'sku' |
| 12 | HWID_INFO_TYPES = [HWID_INFO_BOM, HWID_INFO_SKU, HWID_INFO_LABEL] |
| 13 | |
| 14 | # HWID url vars. |
| 15 | HWID_VERSION = 'v1' |
| 16 | HWID_BASE_URL = 'https://www.googleapis.com/chromeoshwid' |
| 17 | URL_FORMAT_STRING='%(base_url)s/%(version)s/%(info_type)s/%(hwid)s/?key=%(key)s' |
| 18 | |
Kevin Cheng | 80ad573 | 2016-03-31 16:01:56 -0700 | [diff] [blame] | 19 | # Key file name to use when we don't want hwid labels. |
| 20 | KEY_FILENAME_NO_HWID = 'no_hwid_labels' |
Kevin Cheng | 5272ca7 | 2016-01-11 11:55:31 -0800 | [diff] [blame] | 21 | |
| 22 | class HwIdException(Exception): |
| 23 | """Raised whenever anything fails in the hwid info request.""" |
| 24 | |
| 25 | |
| 26 | def get_hwid_info(hwid, info_type, key_file): |
| 27 | """Given a hwid and info type, return a dict of the requested info. |
| 28 | |
| 29 | @param hwid: hwid to use for the query. |
| 30 | @param info_type: String of info type requested. |
| 31 | @param key_file: Filename that holds the key for authentication. |
| 32 | |
| 33 | @return: A dict of the info. |
| 34 | |
| 35 | @raises HwIdException: If hwid/info_type/key_file is invalid or there's an |
| 36 | error anywhere related to getting the raw hwid info |
| 37 | or decoding it. |
| 38 | """ |
Kevin Cheng | 80ad573 | 2016-03-31 16:01:56 -0700 | [diff] [blame] | 39 | # There are situations we don't want to call out to the hwid service, we use |
| 40 | # the key_file name as the indicator for that. |
| 41 | if key_file == KEY_FILENAME_NO_HWID: |
| 42 | return {} |
| 43 | |
Kevin Cheng | 5272ca7 | 2016-01-11 11:55:31 -0800 | [diff] [blame] | 44 | if not isinstance(hwid, str): |
| 45 | raise ValueError('hwid is not a string.') |
| 46 | |
| 47 | if info_type not in HWID_INFO_TYPES: |
| 48 | raise ValueError('invalid info type: "%s".' % info_type) |
| 49 | |
| 50 | key = None |
| 51 | with open(key_file) as f: |
| 52 | key = f.read().strip() |
| 53 | |
| 54 | url_format_dict = {'base_url': HWID_BASE_URL, |
| 55 | 'version': HWID_VERSION, |
| 56 | 'info_type': info_type, |
Kevin Cheng | 80ad573 | 2016-03-31 16:01:56 -0700 | [diff] [blame] | 57 | 'hwid': urllib2.quote(hwid), |
Kevin Cheng | 5272ca7 | 2016-01-11 11:55:31 -0800 | [diff] [blame] | 58 | 'key': key} |
| 59 | |
| 60 | url_request = URL_FORMAT_STRING % url_format_dict |
| 61 | try: |
| 62 | page_contents = urllib2.urlopen(url_request) |
| 63 | except (urllib2.URLError, urllib2.HTTPError) as e: |
| 64 | # TODO(kevcheng): Might need to scrub out key from exception message. |
| 65 | raise HwIdException('error retrieving raw hwid info: %s' % e) |
| 66 | |
| 67 | try: |
| 68 | hwid_info_dict = json.load(page_contents) |
| 69 | except ValueError as e: |
| 70 | raise HwIdException('error decoding hwid info: %s - "%s"' % |
| 71 | (e, page_contents.getvalue())) |
| 72 | finally: |
| 73 | page_contents.close() |
| 74 | |
| 75 | return hwid_info_dict |
Kevin Cheng | 80ad573 | 2016-03-31 16:01:56 -0700 | [diff] [blame] | 76 | |
| 77 | |
| 78 | def get_all_possible_dut_labels(key_file): |
| 79 | """Return all possible labels that can be supplied by dutlabels. |
| 80 | |
| 81 | We can send a dummy key to the service to retrieve all the possible |
| 82 | labels the service will provide under the dutlabel api call. We need |
| 83 | this in order to track which labels we can remove if they're not detected |
| 84 | on a dut anymore. |
| 85 | |
| 86 | @param key_file: Filename that holds the key for authentication. |
| 87 | |
| 88 | @return: A list of all possible labels. |
| 89 | """ |
| 90 | return get_hwid_info('dummy_hwid', HWID_INFO_LABEL, key_file).get( |
| 91 | 'possible_labels', []) |