# Copyright (c) Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2018 All Rights Reserved
#
# 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 string
import sys
import os
import traceback
import json
import configparser
from io import StringIO
from pipes import quote
import exec_command
class StatUtilsException(Exception):
pass
def cpanel_whmapi(cmd, **kwargs):
"""
Perform cPanel WHM API console request and return data from result
:param cmd: whm api command
:return: data dict from result
"""
joined_kwargs = ' '.join([quote('{0}={1}'.format(k, v)) for k, v in kwargs.items()])
result = exec_command.exec_command("/usr/sbin/whmapi1 {cmd} {kw} --output json".format(cmd=cmd, kw=joined_kwargs))
try:
dict_result = json.loads(''.join(result))
except ValueError:
# if result is not JSON
raise StatUtilsException(
"Failed to get JSON from this API request: {0} {1}; output: {2}".format(cmd,
joined_kwargs,
''.join(result)))
try:
return dict_result['data']
except KeyError:
# if there are no data field in received JSON
raise StatUtilsException("Failed to get data from this API result: {0}".format(dict_result))
def plesk_bin_php_handler(cmd, **kwargs):
"""
Perform Plesk php_handler utility console request and return result
:param cmd: php_handler command
:return: dict result
"""
# need to quote only value (-k 'v'), quoting full params ('-k v') causes API failure
joined_kwargs = ' '.join(['-{0} {1}'.format(k, quote(v)) for k, v in kwargs.items()])
result = exec_command.exec_command("/usr/local/psa/bin/php_handler --{cmd} {kw} -json true".format(cmd=cmd,
kw=joined_kwargs))
try:
return json.loads(''.join(result))
except ValueError:
raise StatUtilsException(
"Failed to get JSON from this API request: php_handler {0} {1}; output: {2}".format(cmd,
joined_kwargs,
''.join(result)))
def get_da_domains():
"""
Get domains per user
:return: dict(
user: list of domains
)
"""
da_users_path = '/usr/local/directadmin/data/users'
da_domains_path = '/usr/local/directadmin/data/users/{user}/domains.list'
da_users = os.listdir(da_users_path)
domains = dict.fromkeys(da_users)
try:
for user in da_users:
with open(da_domains_path.format(user=user), 'r') as domains_list_file:
domains[user] = set([l.strip() for l in domains_list_file.readlines()])
except (OSError, IOError):
raise StatUtilsException(''.join(traceback.format_exc().split('\n')))
return domains
def get_da_php_options():
"""
Get php settings from options.conf
:return: dict(
first php setting: {version, mode},
second php setting: {version, mode},
)
"""
options_path = '/usr/local/directadmin/custombuild/options.conf'
try:
config_parser, global_section = read_da_config(options_path)
php1_ver = config_parser.get(global_section, 'php1_release')
php2_ver = config_parser.get(global_section, 'php2_release')
php1_handler = config_parser.get(global_section, 'php1_mode')
php2_handler = config_parser.get(global_section, 'php2_mode')
except configparser.NoOptionError:
raise StatUtilsException('No option found: {0}'.format(''.join(traceback.format_exc().split('\n'))))
return {
1: {
'version': php1_ver,
'handler': 'lsapi' if php1_handler == 'lsphp' else php1_handler
},
2: {
'version': php2_ver,
'handler': 'lsapi' if php2_handler == 'lsphp' else php2_handler
}
}
def read_da_config(conf_file, append_section_name='dummy_section'):
"""
Read DA config file with ConfigParser.
Need to add dummy section for success
:param conf_file: config file name
:param append_section_name: name of section to place in the beginning of file
:return: RawConfigParser instance
"""
try:
with open(conf_file) as f:
file_content = StringIO('[{s}]\n'.format(s=append_section_name) + f.read())
config_parser = configparser.RawConfigParser(strict=False)
config_parser.read_file(file_content)
except (OSError, IOError):
raise StatUtilsException(''.join(traceback.format_exc().split('\n')))
return config_parser, append_section_name
def pretty_version_keys(php_ver, pre='php'):
"""
Convert simple php versions to pretty format
:param php_ver: {major}.{minor} version
:param pre: desired key start
:return: alt-php{major}{minor} or desired `pre`{major}{minor}
"""
template = '{0}%s%s'.format(pre)
try:
return template % tuple(php_ver.split('.'))
except Exception:
return php_ver
def dump_lsapi(ctl_path='/usr/sbin/httpd'):
"""
Get `httpd -t -D DUMP_RUN_LSAPI` info
For httpd24 this default path is `/opt/rh/httpd24/root/usr/sbin/httpd`, generated in make_from_templates.sh script
:param ctl_path: path to httpd (also apachectl may be used)
:return: dict(
lsapi_option: value
)
"""
apache_conf_data = exec_command.exec_command('{ctl} -t -D DUMP_RUN_LSAPI'.format(ctl=ctl_path))
try:
return dict([l.lower().split(' ') for l in apache_conf_data])
except:
return dict()
def dump_loaded_modules(ctl_path='/usr/sbin/httpd'):
"""
Get `httpd -M`
For httpd24 this default path is `/opt/rh/httpd24/root/usr/sbin/httpd`, generated in make_from_templates.sh script
:param ctl_path: path to httpd (also apachectl may be used)
:return: dict(
apache_module: value
)
"""
apache_modules = exec_command.exec_command('{ctl} -M'.format(ctl=ctl_path))
try:
return dict([l.lower().split(' ') for l in apache_modules])
except:
return dict()
def liblsapi_path():
"""
Retrieve path to liblsapi, depends on arch
:return: path to liblsapi
"""
is_64bits = sys.maxsize > 2**32
return '/usr/lib{a}/liblscapi.so'.format(a='64' if is_64bits else '')
def rpm_query(pkg):
"""
Get version-release from rpm -q `pkg`
:param pkg: package name to query
:return: version-release
"""
try:
ver, rel = ''.join(exec_command.exec_command('/bin/rpm -q ' + pkg + ' --qf %{v}-%{r}')).split('-')
return '{ver}-{rel}'.format(ver=ver, rel=rel.split('.')[0])
except ValueError:
return None
def query_strings(fname, template):
"""
Filter strings by given template
Also split string upon given template
:param fname: path to file
:param template: template to find in string
:return: first template occurrence splitted by template
"""
try:
return [l for l in strings(fname) if template in l][0].split(template)[1].strip()
except (IndexError, IOError, OSError):
return None
def strings(fname, n=6):
"""
Strings utility analog.
Finds printable strings in executable
:param fname: path to file
:param n: minimum string length
:return: generator, yeilds string
"""
with open(fname, errors='ignore') as f:
result = ""
for c in f.read():
if c in string.printable:
result += c
continue
if len(result) >= n:
yield result
result = ""
if len(result) >= n: # catch result at EOF
yield result
def count_domains(handler_struct, default_keys, only_lsapi=True):
"""
Count domains
:param handler_struct: handler: version: set_of_domains structure
:param default_keys: sequence of keys to add as default if no `lsapi` found
:param only_lsapi: return only lsapi statistics
:return: statistics - number of lsapi domains per version if only_lsapi=True
number of lsapi domains per version per handler otherwise
"""
result_stat = dict()
for h, data in handler_struct.items():
result_stat[h] = dict((k, len(v)) for k, v in data.items())
# if there are no lsapi handler domains, return 0 per each installed version
try:
return result_stat['lsapi'] if only_lsapi else result_stat
except KeyError:
return dict.fromkeys([x for x in default_keys if x != 'no'], 0)
Anons79 File Manager Version 1.0, Coded By Anons79
Email: [email protected]