Mini Shell

Direktori : /usr/share/cloudlinux/cl_plus/
Upload File :
Current File : //usr/share/cloudlinux/cl_plus/manage_clplus

#!/opt/cloudlinux/venv/bin/python3 -bb
# coding=utf-8
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2020 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#

# Cloudlinux + sender daemon control utility

import sys
import subprocess
import syslog
import os
import requests
import json
import re
import logging

from functools import wraps
from urllib.parse import urlparse

from clcommon.lib.jwt_token import jwt_token_check
from clcommon.lib.cmt_utils import (
    is_cmt_disabled,
    client_activation_data,
    log_request_error_debug_info
)
from clcommon.lib.consts import (
    DISABLE_CMT_DIR,
    DISABLE_CMT_FILE,
    PUSHGATEWAY_ADDRESS,
    ACCELERATE_WP_INSTALLED_FROM_CM,
    ACCELERATE_WP_PREMIUM_INSTALLED_FROM_CM
)
from clsentry import init_sentry_client
from lve_utils import PKG_VERSION
from clcommon.clwpos_lib import (
    configure_accelerate_wp,
    configure_accelerate_wp_premium,
    configure_upgrade_url
)
from clcommon.const import Feature
from clcommon.cpapi import is_panel_feature_supported
from clcommon.utils import is_ubuntu

SETUP_CLPLUS_FILE = '/usr/share/cloudlinux/cl_plus/setup_clplus'
PKG_VERSION_TINY = re.sub(r'\.el\w(h?)\.', '.elX.', PKG_VERSION)


# https://cl.sentry.cloudlinux.com/settings/cloudlinux_os/projects/userland
SENTRY_DSN = 'https://9713d1296f804031b058b8f2d789d7ac:' \
             '8ddacae32d8246cf8b25cf826bf3fc0a@cl.sentry.cloudlinux.com/12'

BAD_JWT_WARNING = \
    "WARNING: it looks that this server is still marked as not having CloudLinux plus license. " \
    "Command that you run will still work, but have no " \
    "effect until CloudLinux plus license will be detected. " \
    "If you are sure that this server must have CloudLinux plus license, " \
    "try to run `rhn_check` and this command again. If warning still appears, " \
    "contact CloudLinux support for help (https://www.cloudlinux.com/support)."

NON_ACTIVATED_CM_WARN = \
    "Looks like you haven't activated statistics collection " \
    "via the Centralized Monitoring UI.\n" \
    "Check this link for more detailed instructions:\n" \
    "https://docs.cloudlinux.com/cloudlinux-os-plus/#installation-2" \
    " (paragraph 4). Command that you run will still work, but have no " \
    "effect until you activate Centralized Monitoring " \
    "using button on https://cm.cloudlinux.com."

def run_accelerate_wp_setup_only_once(marker_file_path):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):

            if os.path.exists(marker_file_path):
                logging.info('AccelerateWP was already configured, nothing to do')
                return

            try:
                func(*args, **kwargs)
            except Exception:
                logging.exception('AccelerateWP configuration upon Centralized Monitoring setting failed')
                return

            if os.path.exists(os.path.dirname(marker_file_path)):
                open(marker_file_path, 'w').close()

        return wrapper

    return decorator
@run_accelerate_wp_setup_only_once(ACCELERATE_WP_INSTALLED_FROM_CM)
def setup_accelerate_wp():
    configure_accelerate_wp()

@run_accelerate_wp_setup_only_once(ACCELERATE_WP_PREMIUM_INSTALLED_FROM_CM)
def setup_accelerate_wp_premium():
    configure_accelerate_wp_premium()

def setup_upgrade_url(upgrade_url):
    try:
        configure_upgrade_url(upgrade_url)
    except Exception:
        logging.exception('AccelerateWP upgrade url setup upon Centralized Monitoring setting failed')


def get_client_info(logger, component) -> dict:
    try:
        client_activation_info = client_activation_data(raise_exception=True)
    except requests.exceptions.RequestException as e:
        http_response = e.response
        if http_response is None or http_response.status_code not in (requests.codes.UNAUTHORIZED,
                                                                      requests.codes.FORBIDDEN):
            # 'https://cm.cloudlinux.com' -> cm.cloudlinux.com
            cm_domain = urlparse(PUSHGATEWAY_ADDRESS).hostname
            log_request_error_debug_info(component, logger, e, cm_domain)
        sys.exit(-1)
    except (
        KeyError,
        json.JSONDecodeError,
        OSError,
        IOError
    ) as e:
        logging.error("manage_clplus error: %s", str(e),
                      extra={'fingerprint': [component, e.__class__.__name__]})
        sys.exit(-1)
    return client_activation_info

def main():
    logger = logging.getLogger()
    component = 'manage_cl_plus'

    try:
        init_sentry_client('manage_clplus', PKG_VERSION_TINY, SENTRY_DSN, custom_length=7000)
    except Exception as e:
        # just in case sentry was not initialized - do not log anything to console
        handler = logging.StreamHandler()
        handler.setLevel(logging.CRITICAL)
        logger.addHandler(handler)
        syslog.syslog(syslog.LOG_ERR, f'Failed to init sentry client: {e}')

    if '--help' in sys.argv:
        print(
            "--help - will show this page\n"
            "enable - will turn on cl_plus service (this option will remove file '/etc/cl_plus/.disable')\n"
            "disable - will turn off cl_plus service (this option will add file '/etc/cl_plus/.disable')"
        )
        sys.exit(0)

    # we check this constraints before so we could avoid
    # unnecessary requests to backend
    is_valid, jwt_err_msg, _ = jwt_token_check()

    if 'enable' in sys.argv:
        if not is_valid:
            print(BAD_JWT_WARNING)
        try:
            os.remove(DISABLE_CMT_FILE)
        except OSError:
            pass
    elif 'disable' in sys.argv:
        if not is_valid:
            print(BAD_JWT_WARNING)
        # create .disable file
        if not os.path.isdir(DISABLE_CMT_DIR):
            os.mkdir(DISABLE_CMT_DIR, 0o644)
        open(DISABLE_CMT_FILE, "w+").close()

    is_disabled = is_cmt_disabled()

    # cm is not disabled on the server
    # acceleratewp was not activated yet via CMT
    request_cm_conditions = [not is_disabled,
                             not os.path.exists(ACCELERATE_WP_INSTALLED_FROM_CM),
                             not os.path.exists(ACCELERATE_WP_PREMIUM_INSTALLED_FROM_CM)]
    _is_client_enabled, _is_accelerate_wp_activated = False, False
    _is_accelerate_wp_premium_activated, _accelerate_wp_premium_upgrade_url = False, None

    if is_valid and any(request_cm_conditions):
        client_activation = get_client_info(logger, component)
        _is_client_enabled = client_activation.get('activate', False)

        if is_panel_feature_supported(Feature.WPOS):
            _is_accelerate_wp_activated = client_activation.get('accelerate_wp_free_activate', False)

            _is_accelerate_wp_premium_activated = client_activation.get('accelerate_wp_premium_status', False)
            _accelerate_wp_premium_upgrade_url = client_activation.get('accelerate_wp_premium_upgrade_url')

    if _is_accelerate_wp_activated:
        setup_accelerate_wp()

    if _is_accelerate_wp_premium_activated:
        setup_accelerate_wp_premium()

    if _accelerate_wp_premium_upgrade_url:
        setup_upgrade_url(_accelerate_wp_premium_upgrade_url)

    if is_valid and not is_disabled:
        # Warning, if enable mode was called without UI activation
        if 'enable' in sys.argv and not _is_client_enabled:
            print(NON_ACTIVATED_CM_WARN)

    if not(is_valid and not is_disabled and _is_client_enabled):
        # JWT token absent or invalid - remove daemons
        if os.path.isfile(SETUP_CLPLUS_FILE):
            subprocess.call(["yum", "-y", "remove", "cl-end-server-tools"])
        sys.exit(0)
    # JWT token check OK - install daemons
    if not os.path.isfile(SETUP_CLPLUS_FILE):
        subprocess.call(["yum", "-y", "install", "cl-end-server-tools"])


if __name__ == "__main__":
    if is_ubuntu():
        sys.exit(0)
    main()

Zerion Mini Shell 1.0