Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: Uptycs query runner #3319

Merged
merged 17 commits into from
Jan 23, 2019
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added client/app/assets/images/db-logos/uptycs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
136 changes: 136 additions & 0 deletions redash/query_runner/uptycs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
from redash.query_runner import *
from redash.utils import json_dumps

import json
import jwt
import datetime
import requests
import logging

logger = logging.getLogger(__name__)


class Uptycs(BaseSQLQueryRunner):
noop_query = "SELECT 1"

@classmethod
def configuration_schema(cls):
return {
"type": "object",
"properties": {
"url": {
"type": "string"
},
"customer_id": {
"type": "string"
},
"key": {
"type": "string"
},
"SSL": {
vibhorkum marked this conversation as resolved.
Show resolved Hide resolved
"type": "boolean",
vibhorkum marked this conversation as resolved.
Show resolved Hide resolved
"default": True
},
"secret": {
"type": "string",
},
},
"order": ['url', 'customer_id', 'key', 'secret'],
"required": ["url", "customer_id", "key", "secret"],
"secret": ["secret", "key"]
}

@classmethod
def annotate_query(cls):
return False

def generate_header(self, key, secret):
header = {}
utcnow = datetime.datetime.utcnow()
date = utcnow.strftime("%a, %d %b %Y %H:%M:%S GMT")
auth_var = jwt.encode({'iss': key}, secret, algorithm='HS256')
authorization = "Bearer %s" % (auth_var)
header['date'] = date
header['Authorization'] = authorization
return header

def transformed_to_redash_json(self, data):
transformed_columns = []
rows = []
# convert all type to JSON string
# In future we correct data type mapping later
if 'columns' in data:
for json_each in data['columns']:
name = json_each['name']
new_json = {"name": name,
"type": "string",
"friendly_name": name}
transformed_columns.append(new_json)
# Transfored items into rows.
if 'items' in data:
rows = data['items']

redash_json_data = {"columns": transformed_columns,
"rows": rows}
return redash_json_data

def api_call(self, sql):
# JWT encoded header
header = self.generate_header(self.configuration.get('key'),
self.configuration.get('secret'))

# URL form using API key file based on GLOBAL
url = ("%s/public/api/customers/%s/query" %
(self.configuration.get('url'),
self.configuration.get('customer_id')))

# post data base sql
post_data_json = {"query": sql}

response = requests.post(url, headers=header, json=post_data_json,
verify=self.configuration.get('SSL'))
vibhorkum marked this conversation as resolved.
Show resolved Hide resolved

if response.status_code == 200:
response_output = json.loads(response.content)
else:
error = 'status_code ' + str(response.status_code) + '\n'
error = error + "failed to connect"
json_data = {}
return json_data, error
# if we get right status code then call transfored_to_redash
json_data = self.transformed_to_redash_json(response_output)
vibhorkum marked this conversation as resolved.
Show resolved Hide resolved
error = None
# if we got error from Uptycs include error information
if 'error' in response_output:
error = response_output['error']['message']['brief']
error = error + '\n' + response_output['error']['message']['detail']
return json_data, error

def run_query(self, query, user):
data, error = self.api_call(query)
json_data = json_dumps(data)
logger.debug("%s", json_data)
return json_data, error

def get_schema(self, get_stats=False):
header = self.generate_header(self.configuration.get('key'),
self.configuration.get('secret'))
url = ("%s/public/api/customers/%s/schema/global" %
(self.configuration.get('url'),
self.configuration.get('customer_id')))
response = requests.get(url, headers=header, verify=False)
vibhorkum marked this conversation as resolved.
Show resolved Hide resolved
redash_json = []
schema = json.loads(response.content)
for each_def in schema['tables']:
table_name = each_def['name']
columns = []
for col in each_def['columns']:
columns.append(col['name'])
table_json = {"name": table_name, "columns": columns}
redash_json.append(table_json)

logger.debug("%s", schema.values())
return redash_json


register(Uptycs)
1 change: 1 addition & 0 deletions redash/settings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def all_settings():
'redash.query_runner.druid',
'redash.query_runner.kylin',
'redash.query_runner.drill',
'redash.query_runner.uptycs',
]

enabled_query_runners = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join(default_query_runners)))
Expand Down