HEX
Server: Apache
System: Linux sg241.singhost.net 2.6.32-896.16.1.lve1.4.51.el6.x86_64 #1 SMP Wed Jan 17 13:19:23 EST 2018 x86_64
User: honghock (909)
PHP: 8.0.30
Disabled: passthru,system,shell_exec,show_source,exec,popen,proc_open
Upload Files
File: //proc/self/root/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]) )