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"""Chrome OS Parnter Concole remote actions.""" 6 7from __future__ import print_function 8 9import base64 10import logging 11 12import common 13 14from autotest_lib.client.common_lib import global_config 15from autotest_lib.client.common_lib import utils 16from autotest_lib.server.hosts import moblab_host 17from autotest_lib.site_utils import pubsub_utils 18 19 20_PUBSUB_TOPIC = global_config.global_config.get_config_value( 21 'CROS', 'cloud_notification_topic', default=None) 22 23# Test upload pubsub notification attributes 24NOTIFICATION_ATTR_VERSION = 'version' 25NOTIFICATION_ATTR_GCS_URI = 'gcs_uri' 26NOTIFICATION_ATTR_MOBLAB_MAC = 'moblab_mac_address' 27NOTIFICATION_ATTR_MOBLAB_ID = 'moblab_id' 28NOTIFICATION_VERSION = '1' 29# the message data for new test result notification. 30NEW_TEST_RESULT_MESSAGE = 'NEW_TEST_RESULT' 31 32 33ALERT_CRITICAL = 'Critical' 34ALERT_MAJOR = 'Major' 35ALERT_MINOR = 'Minor' 36 37LOG_INFO = 'Info' 38LOG_WARNING = 'Warning' 39LOG_SEVERE = 'Severe' 40LOG_FATAL = 'Fatal' 41 42 43def is_cloud_notification_enabled(): 44 """Checks if cloud pubsub notification is enabled. 45 46 @returns: True if cloud pubsub notification is enabled. Otherwise, False. 47 """ 48 return global_config.global_config.get_config_value( 49 'CROS', 'cloud_notification_enabled', type=bool, default=False) 50 51 52class CloudConsoleClient(object): 53 """The remote interface to the Cloud Console.""" 54 def send_heartbeat(self): 55 """Sends a heartbeat. 56 57 @returns True if the notification is successfully sent. 58 Otherwise, False. 59 """ 60 pass 61 62 def send_event(self, event_type=None, event_data=None): 63 """Sends an event notification to the remote console. 64 65 @param event_type: The event type that is defined in the protobuffer 66 file 'cloud_console.proto'. 67 @param event_data: The event data. 68 69 @returns True if the notification is successfully sent. 70 Otherwise, False. 71 """ 72 pass 73 74 def send_log(self, msg, level=LOG_INFO, session_id=None): 75 """Sends a log message to the remote console. 76 77 @param msg: The log message. 78 @param level: The logging level as string. 79 @param session_id: The current session id. 80 81 @returns True if the notification is successfully sent. 82 Otherwise, False. 83 """ 84 pass 85 86 def send_alert(self, msg, level=ALERT_MINOR, session_id=None): 87 """Sends an alert to the remote console. 88 89 @param msg: The alert message. 90 @param level: The logging level as string. 91 @param session_id: The current session id. 92 93 @returns True if the notification is successfully sent. 94 Otherwise, False. 95 """ 96 pass 97 98 def send_test_job_offloaded_message(self, gcs_uri): 99 """Sends a test job offloaded message to the remote console. 100 101 @param gcs_uri: The test result Google Cloud Storage URI. 102 103 @returns True if the notification is successfully sent. 104 Otherwise, False. 105 """ 106 pass 107 108 109# Make it easy to mock out 110def _create_pubsub_client(credential): 111 return pubsub_utils.PubSubClient(credential) 112 113 114class PubSubBasedClient(CloudConsoleClient): 115 """A Cloud PubSub based implementation of the CloudConsoleClient interface. 116 """ 117 def __init__( 118 self, 119 credential=moblab_host.MOBLAB_SERVICE_ACCOUNT_LOCATION, 120 pubsub_topic=_PUBSUB_TOPIC): 121 """Constructor. 122 123 @param credential: The service account credential filename. Default to 124 '/home/moblab/.service_account.json'. 125 @param pubsub_topic: The cloud pubsub topic name to use. 126 """ 127 super(PubSubBasedClient, self).__init__() 128 self._pubsub_client = _create_pubsub_client(credential) 129 self._pubsub_topic = pubsub_topic 130 131 132 def _create_notification_message(self, data, msg_attributes): 133 """Creates a cloud pubsub notification object. 134 135 @param data: The message data as a string. 136 @param msg_attributes: The message attribute map. 137 138 @returns: A pubsub message object with data and attributes. 139 """ 140 message = {'data': data} 141 message['attributes'] = msg_attributes 142 return message 143 144 def _create_notification_attributes(self): 145 """Creates a cloud pubsub notification message attribute map. 146 147 Fills in the version, moblab mac address, and moblab id information 148 as attributes. 149 150 @returns: A pubsub messsage attribute map. 151 """ 152 msg_attributes = {} 153 msg_attributes[NOTIFICATION_ATTR_VERSION] = NOTIFICATION_VERSION 154 msg_attributes[NOTIFICATION_ATTR_MOBLAB_MAC] = ( 155 utils.get_default_interface_mac_address()) 156 msg_attributes[NOTIFICATION_ATTR_MOBLAB_ID] = utils.get_moblab_id() 157 return msg_attributes 158 159 def _create_test_result_notification(self, gcs_uri): 160 """Construct a test result notification. 161 162 @param gcs_uri: The test result Google Cloud Storage URI. 163 164 @returns The notification message. 165 """ 166 data = base64.b64encode(NEW_TEST_RESULT_MESSAGE) 167 msg_attributes = self._create_notification_attributes() 168 msg_attributes[NOTIFICATION_ATTR_GCS_URI] = gcs_uri 169 170 return self._create_notification_message(data, msg_attributes) 171 172 173 def send_test_job_offloaded_message(self, gcs_uri): 174 """Notify the cloud console a test job is offloaded. 175 176 @param gcs_uri: The test result Google Cloud Storage URI. 177 178 @returns True if the notification is successfully sent. 179 Otherwise, False. 180 """ 181 logging.info('Notification on gcs_uri %s', gcs_uri) 182 message = self._create_test_result_notification(gcs_uri) 183 msg_ids = self._pubsub_client.publish_notifications( 184 self._pubsub_topic, [message]) 185 if msg_ids: 186 return True 187 logging.warning('Failed to send notification on gcs_uri %s', gcs_uri) 188 return False 189 190