Mini Shell
#!/opt/imh-python/bin/python2.7
"""Code for parsing /var/cpanel/userdata"""
from __future__ import absolute_import, unicode_literals
import os
import yaml
from rads.exceptions import UserDataError
def _read_userdata_yaml(user, domfile, required):
"""Internal helper function for UserData to strictly parse YAML files"""
path = os.path.join('/var/cpanel/userdata', user, domfile)
try:
with open(path) as handle:
data = yaml.load(handle)
assert isinstance(data, dict)
except IOError:
raise UserDataError('{0!r} could not be opened'.format(path))
except ValueError:
raise UserDataError('{0!r} could not be parsed as YAML'.format(path))
except AssertionError:
raise UserDataError('{0!r} is invalid; not a YAML dict'.format(path))
for key, req_type in required.iteritems():
if key not in data:
raise UserDataError('{0!r} is missing {1!r}'.format(path, key))
if not isinstance(data[key], req_type):
raise UserDataError(
'{0!r} contains invalid data for {1!r}'.format(path, key)
)
data['has_ssl'] = os.path.isfile('{}_SSL'.format(path))
return data
class UserData(object):
"""Object representing the data parsed from userdata.
vars() can be run on this object to convert it into a dict.
Raises rads.exceptions.UserDataError on invalid userdata
Attributes:
user: username
primary: UserDomain object for the main domain
addon: list of UserDomain objects for addon domains
parked: list of UserDomain objects for parked domains
subs: list of UserDomain objects for subdomains
merged_roots: list of merged, top-level docroots"""
def __init__(self, user):
"""Initializes a UserData object given a cPanel username"""
self.user = user
main_data = _read_userdata_yaml(
user=user,
domfile='main',
required={
'main_domain': str,
'addon_domains': dict,
'parked_domains': list,
'sub_domains': list
}
)
dom_data = _read_userdata_yaml(
user=user,
domfile=main_data['main_domain'],
required={'documentroot': str}
)
# populate primary domain
self.primary = UserDomain(
domain=main_data['main_domain'],
has_ssl=dom_data['has_ssl'],
docroot=dom_data['documentroot']
)
# populate addon domains
self.addons = []
for addon, addon_file in main_data['addon_domains'].iteritems():
addon_data = _read_userdata_yaml(
user=user,
domfile=addon_file,
required={'documentroot': str}
)
self.addons.append(UserDomain(
domain=addon,
has_ssl=addon_data['has_ssl'],
docroot=addon_data['documentroot']
))
# populate parked domains
self.parked = []
for parked in main_data['parked_domains']:
self.parked.append(UserDomain(
domain=parked,
has_ssl=False,
docroot=self.primary.docroot
))
# populate subdomains
self.subs = []
for sub in main_data['sub_domains']:
sub_data = _read_userdata_yaml(
user=user,
domfile=sub,
required={'documentroot': str}
)
self.subs.append(UserDomain(
domain=sub,
has_ssl=sub_data['has_ssl'],
docroot=sub_data['documentroot']
))
def __repr__(self):
return 'UserData({0.user!r})'.format(self)
@property
def __dict__(self):
return {
'user': self.user,
'primary': vars(self.primary),
'addons': [vars(x) for x in self.addons],
'parked': [vars(x) for x in self.parked],
'subs': [vars(x) for x in self.subs]
}
@property
def all_roots(self):
"""All site document roots"""
all_dirs = set([self.primary.docroot])
all_dirs.update([x.docroot for x in self.subs])
all_dirs.update([x.docroot for x in self.addons])
return list(all_dirs)
@property
def merged_roots(self):
"""Merged, top-level document roots for a user"""
merged = []
for test_path in sorted(self.all_roots):
head, tail = os.path.split(test_path)
while head and tail:
if head in merged:
break
head, tail = os.path.split(head)
else:
if test_path not in merged:
merged.append(test_path)
return merged
class UserDomain(object):
"""Object representing a cPanel domain.
vars() can be run on this object to convert it into a dict.
Attributes:
domain: domain name
has_ssl: True/False if the domain has ssl
docroot: document root on the disk"""
def __init__(self, domain, has_ssl, docroot):
self.domain = domain
self.has_ssl = has_ssl
self.docroot = docroot
def __repr__(self):
return (
"UserDomain(domain={0.domain!r}, has_ssl={0.has_ssl!r}, "
"docroot={0.docroot!r})".format(self)
)
@property
def __dict__(self):
myvars = {}
for attr in ('domain', 'has_ssl', 'docroot'):
myvars[attr] = getattr(self, attr)
return myvars
Zerion Mini Shell 1.0