• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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