/
opt
/
cloudlinux
/
venv
/
lib64
/
python3.11
/
site-packages
/
xray
/
manager
/
Upload Filee
HOME
# -*- coding: utf-8 -*- # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT """ This module contains classes implementing X-Ray Manager behaviour for custom integration """ from collections import ChainMap from typing import Optional from clcommon.cpapi.plugins.vendors import PublicApi from xray import gettext as _ from xray.internal import phpinfo_utils from .base import BaseManager from ..internal.exceptions import XRayManagerError, XRayMissingDomain from ..internal.types import DomainInfo from ..internal.user_plugin_utils import ( user_mode_verification, with_fpm_reload_restricted ) class CustomManager(BaseManager): """ Manager supporting integration scripts """ VERSIONS_CUSTOM = { '54': None, '55': None, '56': None, '70': None, '71': None, '72': None, '73': None, '74': None, '80': None, '81': None, '82': None, '83': None } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.api = PublicApi() if self.is_xray_integrated: self.all_domains = self.get_all_domains() else: raise XRayManagerError( _('X-Ray is not supported by control panel vendor')) def supported_versions(self) -> ChainMap: """ Get supported PHP versions :return: dict with custom supported versions """ return ChainMap(self.VERSIONS, self.VERSIONS_CUSTOM) @property def is_xray_integrated(self): """ Check the X-Ray feature status through the panel_info script """ _info = self.api.panel_info() # PanelInfo instance features = _info.supported_cl_features if features is None: return True return features.get('xray', False) def get_all_domains(self) -> dict: """ Collect domains from integration script """ return self.api.domains(with_php=True) @user_mode_verification @with_fpm_reload_restricted def get_domain_info(self, domain_name: str) -> DomainInfo: """ Retrieve PHP setting for given domain_name """ try: domain_conf = self.all_domains[domain_name] # DomainData instance except KeyError: self.logger.warning( 'Domain does not exist on the server', extra={'domain_name': domain_name}) raise XRayMissingDomain(domain_name) if self.phpinfo_mode: config = phpinfo_utils.get_php_configuration( domain_conf.owner, domain=domain_name) return DomainInfo( name=domain_name, panel_php_version=config.get_full_php_version(''), php_ini_scan_dir=config.absolute_ini_scan_dir, # indicates that there is no need to apply selector # and try to resolve php version, the one given in # php_version is final one is_selector_applied=True, user=domain_conf.owner, panel_fpm=config.is_php_fpm, ) else: domain_info = DomainInfo( name=domain_name, user=domain_conf.owner, panel_php_version=domain_conf.php.version, panel_fpm=domain_conf.php.fpm, is_native=domain_conf.php.is_native, ini_path=domain_conf.php.ini_path ) self.logger.info( 'Retrieved domain info: domain %s owned by %s uses php version %s', domain_name, domain_info.user, domain_info.panel_php_version) return domain_info def panel_specific_selector_enabled(self, domain_info: DomainInfo) -> bool: """ Check if selector is enabled specifically for custom panels Required to be implemented by child classes :param domain_info: a DomainInfo object :return: True if yes, False otherwise """ return domain_info.is_native and not domain_info.panel_fpm def fpm_service_name(self, dom_info: DomainInfo) -> Optional[str]: """ Retrieve FPM service name """ return dom_info.panel_fpm def _ini_path(self, domain_info: DomainInfo) -> str: """ Path to additional .ini files specific custom panel getter """ return domain_info.ini_path def get_ini_path(self, domain_info: DomainInfo) -> str: """ Resolve a path to directory for additional ini file. It depends on version set for domain and on selector NOTE: This method is overrided to manage php.d.location=selector resolving. In custom integration we do not know if PHP version is alt or not, it is set as just two digits. Thus, we only could rely on resolved path -- if it is '/opt/alt'. :param domain_info: a DomainInfo object :return: path to directory for ini files """ if domain_info.php_ini_scan_dir: return domain_info.php_ini_scan_dir # here follows the hack to resolve php.d.location=selector # for custom integration ini_path = super().get_ini_path(domain_info) if ini_path.startswith( '/opt/alt') and not domain_info.panel_php_version.startswith( 'alt-php'): saved_panel_php = domain_info.panel_php_version domain_info.panel_php_version = f'alt-php{domain_info.panel_php_version}' try: ini_path = domain_info.phpd_location_ini_path or ini_path except ValueError: # failed to resolve CageFS prefix for user pass domain_info.panel_php_version = saved_panel_php self.logger.info('Ini path re-resolved as %s', ini_path) return ini_path