Mini Shell
# coding:utf-8
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import re
import subprocess
from requests import Session
class ZendeskAPIError(Exception):
def __init__(self, message):
self.message = message
super(ZendeskAPIError, self).__init__(message)
_API_URL_TMPL = 'https://cloudlinux.zendesk.com/api/v2/{}'
_HC_URL_TMPL = 'https://cloudlinux.zendesk.com/hc/requests/{}'
CONTACT_SUPPORT_STRING = 'Please contact Cloudlinux support at https://cloudlinux.zendesk.com/hc/requests/new'
# Identifiers for custom fields in API
_PRODUCT_ID = 33267569
_DOCTOR_ID = 43297669
_CLN_ID = 43148369
_AGREEMENT = 12355021509788
def send_to_support(request_data):
params = request_data.get('params', {})
doctor_key = None
if params.get('clDoctor') == 'true':
# Generating doctor and extracting key from output
try:
doctor_key = _get_doctor_key()
except Exception:
doctor_key = None
# Sending request via Zendesk API
# https://developer.zendesk.com/rest_api/docs/core/requests#anonymous-requests
ticket_url = _send_request(
params.get('email'),
params.get('subject'),
params.get('description'),
doctor_key,
params.get('cln'),
params.get('agreement'),
request_data.get('attachments'))
return ticket_url
def _send_request(sender_email,
subject,
description,
doctor_key=None,
cln=None,
agreement=None,
attachments=None):
"""
Send request to support via Zendesk API
"""
with Session() as session:
# Uploading attachments to Zendesk
upload_token = _upload_attachments(attachments, session)
# Creating comment object: setting description and attaching
# uploads token
comment = dict(body=description + "\n\n [This ticket was created from CloudLinux Manager]")
if upload_token is not None:
comment['uploads'] = [upload_token]
# Author of request
requester = dict(name=sender_email,
email=sender_email)
# Custom fields for support convenience
custom_fields = [{'id': _PRODUCT_ID,
'value': 'cloudlinux'}]
if doctor_key:
custom_fields.append(
{'id': _DOCTOR_ID,
'value': doctor_key})
if cln:
custom_fields.append(
{'id': _CLN_ID,
'value': cln})
if agreement:
custom_fields.append(
{'id': _AGREEMENT,
'value': agreement})
# Ready request
request = dict(
requester=requester,
subject=subject,
comment=comment,
custom_fields=custom_fields
)
return _post_request(request, session)
def _post_request(request, session):
resp = session.post(_API_URL_TMPL.format('requests.json'),
json={'request': request})
data = resp.json(encoding='utf-8')
if resp.status_code == 201:
ticket_id = data.get('request', {}).get('id')
if data.get('request'):
return _HC_URL_TMPL.format(data['request']['id'])
elif data.get('suspended_ticket'):
raise ZendeskAPIError(
data['suspended_ticket']['cause'] + '. ' + CONTACT_SUPPORT_STRING)
raise ZendeskAPIError('Zendesk api error. ' + CONTACT_SUPPORT_STRING)
def _upload_attachments(attachments, session):
# Uploading attachments to Zendesk
upload_token = None
if attachments is None:
return upload_token
for attachment in attachments:
attachment_file = open(attachment['file'], 'rb')
params = {'filename': attachment['name']}
if upload_token is not None:
params['token'] = upload_token
resp = session.post(
_API_URL_TMPL.format('uploads.json'),
data=attachment_file.read(),
headers={'Content-Type': 'application/binary'},
params=params)
result = resp.json(encoding='utf-8')
if resp.status_code != 201:
continue
if upload_token is None:
upload_token = result['upload']['token']
attachment_file.close()
return upload_token
def _get_doctor_key():
command = ['/bin/bash',
'-c',
'curl -s https://repo.cloudlinux.com/cloudlinux/cldoctor/cldoctor.sh | bash']
response = subprocess.check_output(command, stderr=subprocess.STDOUT, text=True)
result = re.search('Key: ([^\n]+)\n', response)
return result.group(1)
Zerion Mini Shell 1.0