You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.7 KiB
116 lines
3.7 KiB
|
|
# Copyright 2016 Google Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import base64
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import tempfile
|
|
|
|
from oauth2client import service_account
|
|
|
|
_OPENID_SCOPE = 'openid'
|
|
|
|
class DashboardRestClient(object):
|
|
"""Instance of the Dashboard REST client.
|
|
|
|
Attributes:
|
|
post_cmd: String, The command-line string to post data to the dashboard,
|
|
e.g. 'wget <url> --post-file '
|
|
service_json_path: String, The path to the service account keyfile
|
|
created from Google App Engine settings.
|
|
auth_token: ServiceAccountCredentials object or None if not
|
|
initialized.
|
|
"""
|
|
|
|
def __init__(self, post_cmd, service_json_path):
|
|
self.post_cmd = post_cmd
|
|
self.service_json_path = service_json_path
|
|
self.auth_token = None
|
|
|
|
def Initialize(self):
|
|
"""Initializes the client with an auth token and access token.
|
|
|
|
Returns:
|
|
True if the client is initialized successfully, False otherwise.
|
|
"""
|
|
try:
|
|
self.auth_token = service_account.ServiceAccountCredentials.from_json_keyfile_name(
|
|
self.service_json_path, [_OPENID_SCOPE])
|
|
self.auth_token.get_access_token()
|
|
except IOError as e:
|
|
logging.error("Error reading service json keyfile: %s", e)
|
|
return False
|
|
except (ValueError, KeyError) as e:
|
|
logging.error("Invalid service json keyfile: %s", e)
|
|
return False
|
|
return True
|
|
|
|
|
|
def _GetToken(self):
|
|
"""Gets an OAuth2 token using from a service account json keyfile.
|
|
|
|
Uses the service account keyfile located at 'service_json_path', provided
|
|
to the constructor, to request an OAuth2 token.
|
|
|
|
Returns:
|
|
String, an OAuth2 token using the service account credentials.
|
|
None if authentication fails.
|
|
"""
|
|
return str(self.auth_token.get_access_token().access_token)
|
|
|
|
def AddAuthToken(self, post_message):
|
|
"""Add OAuth2 token to the dashboard message.
|
|
|
|
Args:
|
|
post_message: DashboardPostMessage, The data to post.
|
|
|
|
Returns:
|
|
True if successful, False otherwise
|
|
"""
|
|
token = self._GetToken()
|
|
if not token:
|
|
return False
|
|
|
|
post_message.access_token = token
|
|
|
|
def PostData(self, post_message):
|
|
"""Post data to the dashboard database.
|
|
|
|
Puts data into the dashboard database using its proto REST endpoint.
|
|
|
|
Args:
|
|
post_message: DashboardPostMessage, The data to post.
|
|
|
|
Returns:
|
|
True if successful, False otherwise
|
|
"""
|
|
post_bytes = base64.b64encode(post_message.SerializeToString())
|
|
|
|
with tempfile.NamedTemporaryFile(delete=False) as file:
|
|
file.write(post_bytes)
|
|
p = subprocess.Popen(
|
|
self.post_cmd.format(path=file.name),
|
|
shell=True,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE)
|
|
output, err = p.communicate()
|
|
os.remove(file.name)
|
|
|
|
if p.returncode or err:
|
|
logging.error("Row insertion failed: %s", err)
|
|
return False
|
|
return True
|