blob: 892f6773afe894654e86e9158ff6e040561d2543 [file] [log] [blame]
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Chrome OS Parnter Concole remote actions."""
from __future__ import print_function
import base64
import logging
import common
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import utils
from autotest_lib.server.hosts import moblab_host
from autotest_lib.site_utils import pubsub_utils
_PUBSUB_TOPIC = global_config.global_config.get_config_value(
'CROS', 'cloud_notification_topic', default=None)
# Test upload pubsub notification attributes
NOTIFICATION_ATTR_VERSION = 'version'
NOTIFICATION_ATTR_GCS_URI = 'gcs_uri'
NOTIFICATION_ATTR_MOBLAB_MAC = 'moblab_mac_address'
NOTIFICATION_ATTR_MOBLAB_ID = 'moblab_id'
NOTIFICATION_VERSION = '1'
# the message data for new test result notification.
NEW_TEST_RESULT_MESSAGE = 'NEW_TEST_RESULT'
ALERT_CRITICAL = 'Critical'
ALERT_MAJOR = 'Major'
ALERT_MINOR = 'Minor'
LOG_INFO = 'Info'
LOG_WARNING = 'Warning'
LOG_SEVERE = 'Severe'
LOG_FATAL = 'Fatal'
def is_cloud_notification_enabled():
"""Checks if cloud pubsub notification is enabled.
@returns: True if cloud pubsub notification is enabled. Otherwise, False.
"""
return global_config.global_config.get_config_value(
'CROS', 'cloud_notification_enabled', type=bool, default=False)
class CloudConsoleClient(object):
"""The remote interface to the Cloud Console."""
def send_heartbeat(self):
"""Sends a heartbeat.
@returns True if the notification is successfully sent.
Otherwise, False.
"""
pass
def send_event(self, event_type=None, event_data=None):
"""Sends an event notification to the remote console.
@param event_type: The event type that is defined in the protobuffer
file 'cloud_console.proto'.
@param event_data: The event data.
@returns True if the notification is successfully sent.
Otherwise, False.
"""
pass
def send_log(self, msg, level=LOG_INFO, session_id=None):
"""Sends a log message to the remote console.
@param msg: The log message.
@param level: The logging level as string.
@param session_id: The current session id.
@returns True if the notification is successfully sent.
Otherwise, False.
"""
pass
def send_alert(self, msg, level=ALERT_MINOR, session_id=None):
"""Sends an alert to the remote console.
@param msg: The alert message.
@param level: The logging level as string.
@param session_id: The current session id.
@returns True if the notification is successfully sent.
Otherwise, False.
"""
pass
def send_test_job_offloaded_message(self, gcs_uri):
"""Sends a test job offloaded message to the remote console.
@param gcs_uri: The test result Google Cloud Storage URI.
@returns True if the notification is successfully sent.
Otherwise, False.
"""
pass
# Make it easy to mock out
def _create_pubsub_client(credential):
return pubsub_utils.PubSubClient(credential)
class PubSubBasedClient(CloudConsoleClient):
"""A Cloud PubSub based implementation of the CloudConsoleClient interface.
"""
def __init__(
self,
credential=moblab_host.MOBLAB_SERVICE_ACCOUNT_LOCATION,
pubsub_topic=_PUBSUB_TOPIC):
"""Constructor.
@param credential: The service account credential filename. Default to
'/home/moblab/.service_account.json'.
@param pubsub_topic: The cloud pubsub topic name to use.
"""
super(PubSubBasedClient, self).__init__()
self._pubsub_client = _create_pubsub_client(credential)
self._pubsub_topic = pubsub_topic
def _create_notification_message(self, data, msg_attributes):
"""Creates a cloud pubsub notification object.
@param data: The message data as a string.
@param msg_attributes: The message attribute map.
@returns: A pubsub message object with data and attributes.
"""
message = {'data': data}
message['attributes'] = msg_attributes
return message
def _create_notification_attributes(self):
"""Creates a cloud pubsub notification message attribute map.
Fills in the version, moblab mac address, and moblab id information
as attributes.
@returns: A pubsub messsage attribute map.
"""
msg_attributes = {}
msg_attributes[NOTIFICATION_ATTR_VERSION] = NOTIFICATION_VERSION
msg_attributes[NOTIFICATION_ATTR_MOBLAB_MAC] = (
utils.get_default_interface_mac_address())
msg_attributes[NOTIFICATION_ATTR_MOBLAB_ID] = utils.get_moblab_id()
return msg_attributes
def _create_test_result_notification(self, gcs_uri):
"""Construct a test result notification.
@param gcs_uri: The test result Google Cloud Storage URI.
@returns The notification message.
"""
data = base64.b64encode(NEW_TEST_RESULT_MESSAGE)
msg_attributes = self._create_notification_attributes()
msg_attributes[NOTIFICATION_ATTR_GCS_URI] = gcs_uri
return self._create_notification_message(data, msg_attributes)
def send_test_job_offloaded_message(self, gcs_uri):
"""Notify the cloud console a test job is offloaded.
@param gcs_uri: The test result Google Cloud Storage URI.
@returns True if the notification is successfully sent.
Otherwise, False.
"""
logging.info('Notification on gcs_uri %s', gcs_uri)
message = self._create_test_result_notification(gcs_uri)
msg_ids = self._pubsub_client.publish_notifications(
self._pubsub_topic, [message])
if msg_ids:
return True
logging.warning('Failed to send notification on gcs_uri %s', gcs_uri)
return False