File: //usr/lib/python2.7/site-packages/DSCollector.py
#!/usr/bin/python2.7
# Dreamscape Network, cPanel Team
# https://jira.ds.network/browse/DSP18-32683
import json
import socket
import subprocess
import sys
import requests
# Basi class
class DSCollector(object):
# debug mode, can be assign by command argument
debug_mode = False
# any limit, can be assign by command argument
# 0 - umlimited/all
limit = 0
#
api_url = None
#
current_server_id = None
#
dataout = []
#
response_results = dict()
def set_debug(self, debug):
self.debug_mode = debug
def debug(self, message):
if self.debug_mode:
print("DEBUG: %s" % message)
def error(self, message):
print("ERROR: %s" % message)
def info(self, message):
print("%s" % message)
def set_limit(self, limit):
self.limit = limit
self.debug("Set limit: %s" % self.limit)
def response_result_inc(self, name):
if self.response_results.has_key(name):
self.response_results[name] += 1
else:
self.response_results[name] = 1
def set_hosting_api_url(self):
if 'development' in socket.gethostname().lower().split('.'):
api_url = "https://hosting-api.development.au.ds.network/api/1.0"
else:
api_url = "https://hosting-api.au.ds.network/api/1.0"
self.debug("Set url: %s" % api_url)
self.api_url = api_url
def get_shell_command(self, command):
out = None
self.debug("Execute shell command: %s" % command)
try:
output = subprocess.check_output(command,
stderr=subprocess.STDOUT,
shell=True)
out = output.rstrip()
out = out.splitlines()
except subprocess.CalledProcessError as exc:
self.error("Execution error code: %s\n Output: %s" % (exc.returncode, exc.output))
out = None
finally:
return out
def uapi_request(self, params):
command = ("uapi --output json %s 2>/dev/null" % params)
self.debug("Execute UAPI request: %s" % command)
stream = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE)
try:
result = json.loads(stream.stdout.read())
except ValueError:
self.error('JSON decode error')
return None
if (result['result']['status'] != 1):
self.error('UAPI request failed [%s]. Error message: %s' % (params, result['result']['errors']))
return None
return result
def whmapi_request(self, params):
command = ("whmapi1 --output json %s 2>/dev/null" % params)
self.debug("Execute WHMAPI request: %s" % command)
stream = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE)
try:
result = json.loads(stream.stdout.read())
except ValueError:
self.error('JSON decode error')
return None
if (result['metadata']['result'] != 1):
self.error('WHMAPI request failed [%s]. Error message: %s' % (params, result['metadata']['reason']))
return None
return result
def cpapi2_request(self, params):
command = ("cpapi2 --output json %s 2>/dev/null" % params)
self.debug("Execute CPAPI2 request: %s" % command)
stream = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE)
try:
result = json.loads(stream.stdout.read())
except ValueError:
self.error('JSON decode error')
return None
if (result['cpanelresult']['event']['result'] != 1):
self.error('CPAPI2 request failed [%s]. Error message: %s' % (params, result['cpanelresult']['event']['reason']))
return None
return result
# user_info (dict)
# example: {'user': 'petrov', 'domain': 'petrov.com'}
def get_user_info(self, user):
s = self.get_shell_command("grep ^%s /etc/domainusers" % user)
# for value as string type
if (isinstance(s,str)):
# ... will do list type
s = [s]
if (s is None):
return None
a = s[0].split(":", 1)
return {'user': a[0].strip(), 'domain': a[1].strip()}
def get_account_id_on_server(self, username):
if (self.current_server_id is None):
self.error("Value current_server_id is not defined")
return None
requestData = dict()
requestData['server_id'] = self.current_server_id
requestData['username'] = username
self.debug("Request data: %s" % requestData.__str__())
try:
response = requests.get("%s/account" % self.api_url, params=requestData, timeout=5)
except requests.RequestException as e:
self.error("Error of requests: %s" % str(e))
return None
else:
self.debug("Response code: %s" % response.status_code)
self.debug("Response content: %s" % response.content)
try:
responseJson = response.json()
except ValueError:
self.error("Decode JSON from response failed")
return None
if (len(responseJson['data'])>1 and len(responseJson['data'][0])):
self.error("Got more than 1 account for name [%s] on server [%s]" % (username,self.current_server_id))
return None
self.debug('Got account_id for username [%s]: %s ' % (username, responseJson['data'][0]['account_id']))
if (responseJson['data'][0]['account_id'] is not None):
return responseJson['data'][0]['account_id']
return None
def get_server_id(self):
requestData = dict()
requestData['hostname'] = socket.gethostname()
try:
response = requests.get("%s/server" % self.api_url, params=requestData, timeout=20)
except requests.RequestException as e:
msg = str(e)
self.error("Error of requests: %s" % msg)
return None
else:
self.debug("Response %s" % response)
responseJson = response.json()
result = responseJson['data'][0]['server_id']
if result is not None:
self.debug('Got server_id: %s' % result )
return result
return None
def get_current_server_id(self):
self.current_server_id = self.get_server_id()
def send_all_data(self, request):
outJson = dict()
outJson['data'] = self.dataout
data = json.dumps(outJson)
self.debug("OUTPUT DATA DUMP:")
self.debug(data)
url = "%s/%s" % (self.api_url, request)
self.info("Data rows: %s Size (bytes): %s " % ( len(self.dataout), sys.getsizeof(data)))
self.info("PUT Request URL: %s " % url)
if (len(self.dataout) == 0 ):
self.error('No data to send')
return None
self.response_result_inc('Sent')
headers = {'content-type': 'application/json'}
try:
response = requests.put(url, data=data, headers=headers, timeout=20)
except requests.RequestException as e:
msg = str(e)
self.error("api request: %s" % msg)
else:
self.info("Response code: %s" % response.status_code)
self.info("Response content: %s" % response.content)
if (response.ok):
self.response_result_inc('Ok')
else:
self.response_result_inc('Fail')
def send_one_item(self, request_path, data_param):
data = json.dumps(data_param)
self.debug("OUTPUT DATA DUMP:")
self.debug(data)
url = "%s/%s" % (self.api_url, request_path)
self.info("Data rows: %s Size (bytes): %s " % ( len(data_param), sys.getsizeof(data)))
self.info("PUT Request URL: %s " % url)
if (len(data) == 0 ):
self.error('No data to send')
return None
self.response_result_inc('Sent')
headers = {'content-type': 'application/json'}
try:
response = requests.put(url, data=data, headers=headers, timeout=20)
except requests.RequestException as e:
msg = str(e)
self.error("api request: %s" % msg)
else:
self.info("Response code: %s" % response.status_code)
self.info("Response content: %s" % response.content)
if (response.ok):
self.response_result_inc('Ok')
else:
self.response_result_inc('Fail')
def show_response_results(self):
self.info('Response results:')
for i in self.response_results.keys():
self.info(' %s: %s' % (i,self.response_results[i]) )