Mini Shell
"""CPanel API core functions"""
import requests
def api_success(json_response):
"""Most whm_api responses store their result status the same way
Import this to avoid repeating yourself for each call. Don't use this for
cpanel_api calls."""
try:
return int(json_response['status']) == 1
except (TypeError, KeyError, ValueError):
pass
try:
return int(json_response['metadata']['result']) == 1
except (TypeError, KeyError, ValueError):
pass
try:
return int(json_response['result']['status']) == 1
except (TypeError, KeyError, ValueError):
try:
return int(json_response['result'][0]['status']) == 1
except (TypeError, IndexError, KeyError, ValueError):
pass
return False
def get_access_hash():
"""Read /root/.accesshash or raise IOError"""
with open('/root/.accesshash', 'r') as hash_file:
access_hash = hash_file.read().splitlines()
return ''.join(access_hash)
def json_api_get(api_function, params=None, version=1, timeout=180):
"""DEPRECATED: use whm_api instead. This was a workaround
for an issue in an older version of cPanel we do not use, and
is now just redirected to json_api_post."""
return json_api_post(
api_function,
version=version,
timeout=timeout,
data=params
)
def json_api_post(api_function, data=None, version=1, timeout=180):
"""DEPRECATED: use whm_api instead. This function still works,
but whm_api is much cleaner."""
if data is None:
data = {'api.version': version}
elif 'api.version' not in data:
data['api.version'] = version
try:
access_hash = get_access_hash()
except IOError:
return None
try:
return requests.post(
'https://127.0.0.1:2087/json-api/%s' % api_function,
data=data,
headers={'Authorization': 'WHM root:%s' % access_hash},
timeout=timeout,
verify=False
).json()
except (
requests.exceptions.RequestException,
ValueError, # JSON issues
TypeError # JSON issues
):
return None
def whm_api(function, version, timeout=180, whmhost='127.0.0.1', access_hash=None, _data=None, **kwargs):
"""Make a POST request to the WHM JSON API.
Args:
function (str): function name posted to /json-api/NAME
version (int): version of the API to use (0 or 1)
timeout (int, default 180): seconds to give the API to respond
whmhost (str, default 127.0.0.1): WHM host to reach
access_hash (str, optional): Access hash to use for WHM authorization.
If contacting the local server, do not supply this arg and it will
be determined automatically.
All other data which must be supplied to the API can be
supplied as additional kwargs.
Special arg:
_data (dict): This shouldn't be necessary to use. If an
argument is impossible to send to the API as a kwarg for
whatever reason, it can be forced in using this. For example,
in python a kwarg cannot have a period in its name or begin
with a number. If you needed to supply stupid.arg as an argument,
you can do _data={'stupid.arg': value_here}
"""
data = {} if _data is None else _data
data['api.version'] = version
for key, val in kwargs.iteritems():
data[key] = val
if access_hash is None:
try:
access_hash = get_access_hash()
except IOError:
return None
try:
return requests.post(
'https://{}:2087/json-api/{}'.format(whmhost, function),
data=data,
headers={'Authorization': 'WHM root:%s' % access_hash},
timeout=timeout,
verify=False
).json()
except (
requests.exceptions.RequestException,
ValueError, # JSON issues
TypeError # JSON issues
):
return None
def cpanel_api(function, version, module, pos=None, timeout=180, _data=None, **kwargs):
"""Make a POST request to the cPanel JSON API.
Args:
function (str): function name posted as cpanel_jsonapi_func
version (int): version of the API to use (1 or 2)
module (str): module name posted as cpanel_jsonapi_module
pos (list): list of positional args sent into the function as arg-0, arg-1, et al.
timeout (int, default 180): seconds to give the API to respond
All other data which must be supplied to the API can be
supplied as additional kwargs.
Special arg:
_data (dict): This shouldn't be necessary to use. If an
argument is impossible to send to the API as a kwarg for
whatever reason, it can be forced in using this. For example,
in python a kwarg cannot have a period in its name or begin
with a number. If you needed to supply stupid.arg as an argument,
you can do _data={'stupid.arg': value_here}
"""
data = {} if _data is None else _data
# required kwargs. All others are supplied inside data{}
data['cpanel_jsonapi_module'] = module
data['cpanel_jsonapi_func'] = function
data['cpanel_jsonapi_apiversion'] = version
for key, val in kwargs.iteritems():
data[key] = val
# positional args are sent in as post variables, in format
# &arg-0=SOMETHING&arg-1=SOMETHING
# the pos (pun intended) variable holds them in the order
# they are sent into the function
if isinstance(pos, str):
# even if there is only one arg, it should be a list
raise ValueError('pos should be a list, received string')
if isinstance(pos, list):
for pos_index, pos_arg in enumerate(pos):
data['arg-%d' % pos_index] = pos_arg
try:
access_hash = get_access_hash()
except IOError:
return None
try:
return requests.post(
'https://127.0.0.1:2087/json-api/cpanel',
data=data,
headers={'Authorization': 'WHM root:%s' % access_hash},
timeout=timeout,
verify=False
).json()
except (
requests.exceptions.RequestException,
ValueError, # JSON issues
TypeError # JSON issues
):
return None
Zerion Mini Shell 1.0