class Config(object): """The base Cachito Flask configuration.""" DEBUG = False # Additional loggers to set to the level defined in CACHITO_LOG_LEVEL CACHITO_ADDITIONAL_LOGGERS: List[str] = ["cachito.common.packages_data"] CACHITO_DEFAULT_PACKAGE_MANAGERS: List[str] = ["gomod"] # This sets the level of the "flask.app" logger, which is accessed from current_app.logger CACHITO_LOG_LEVEL = "INFO" CACHITO_LOG_FORMAT = "[%(asctime)s %(name)s %(levelname)s %(module)s.%(funcName)s] %(message)s" CACHITO_MAX_PER_PAGE = 100 # Pairs of mutually exclusive package managers (cannot process the same package) CACHITO_MUTUALLY_EXCLUSIVE_PACKAGE_MANAGERS = [("npm", "yarn")] CACHITO_PACKAGE_MANAGERS = ["gomod"] CACHITO_REQUEST_FILE_LOGS_DIR: Optional[str] = None # Users that are allowed to use the "user" property when creating a request CACHITO_USER_REPRESENTATIVES: List[str] = [] CACHITO_WORKER_USERNAMES: List[str] = [] LOGIN_DISABLED = False TESTING = False # Temp dir used by the Prometheus Flask Exporter to coalesce the metrics from the threads if "PROMETHEUS_MULTIPROC_DIR" not in os.environ.keys(): raise ConfigError( "The environment variable PROMETHEUS_MULTIPROC_DIR must be set prior to execution" ) else: PROMETHEUS_METRICS_TEMP_DIR = os.environ["PROMETHEUS_MULTIPROC_DIR"]
def validate_celery_config(conf, **kwargs): """ Perform basic validatation on the Celery configuration when the worker is initialized. :param celery.app.utils.Settings conf: the Celery application configuration to validate :raises ConfigError: if the configuration is invalid """ for required_dir_conf in ('cachito_bundles_dir', 'cachito_sources_dir'): required_dir = conf.get(required_dir_conf) if not required_dir or not os.path.isdir(required_dir): raise ConfigError( f'The configuration "{required_dir_conf}" must be set to an existing directory' ) if not conf.get('cachito_api_url'): raise ConfigError('The configuration "cachito_api_url" must be set')
def validate_cachito_config(config, cli=False): """ Perform basic validatation on the Cachito configuration. :param dict config: a dictionary of configuration values :param bool cli: a boolean that denotes if the configuration should be validated for the CLI :raises ConfigError: if the configuration is invalid """ # Validate the required config variables for config_var in ( "CACHITO_DEFAULT_PACKAGE_MANAGERS", "CACHITO_LOG_LEVEL", "CACHITO_MAX_PER_PAGE", "CACHITO_MUTUALLY_EXCLUSIVE_PACKAGE_MANAGERS", "CACHITO_LOG_FORMAT", "CACHITO_BUNDLES_DIR", "SQLALCHEMY_DATABASE_URI", "PROMETHEUS_METRICS_TEMP_DIR", ): if config_var == "CACHITO_BUNDLES_DIR": if cli: # Don't verify CACHITO_BUNDLES_DIR if this is coming from the CLI since it's not # used and requires the CACHITO_BUNDLES_DIR to exist. This is a hassle for hooks # in the deployments for OpenShift/Kubernetes. continue required_dir = config.get(config_var) if not required_dir or not os.path.isdir(required_dir): raise ConfigError( f'The configuration "{config_var}" must be set to an existing directory' ) elif config_var == "CACHITO_MUTUALLY_EXCLUSIVE_PACKAGE_MANAGERS": mutually_exclusive = config.get(config_var) if mutually_exclusive is None: raise ConfigError( f'The configuration "{config_var}" must be set') if not all( isinstance(pair, (tuple, list)) and len(pair) == 2 for pair in mutually_exclusive): raise ConfigError( f'All values in "{config_var}" must be pairs (2-tuples or 2-item lists)' ) elif not config.get(config_var): raise ConfigError(f'The configuration "{config_var}" must be set')
def validate_nexus_config(): """ Perform validation on the Celery configuration for package managers that require Nexus. :raise ConfigError: if the Celery configuration isn't configured for Nexus """ conf = get_worker_config() for nexus_conf in ("cachito_nexus_password", "cachito_nexus_url", "cachito_nexus_username"): if not conf.get(nexus_conf): raise ConfigError( f'The configuration "{nexus_conf}" must be set for this package manager' )
def validate_npm_config(): """ Perform validation on the Celery configuration for the npm package manager. :raise ConfigError: if the Celery configuration isn't configured for npm """ validate_nexus_config() conf = get_worker_config() if not conf.get("cachito_nexus_npm_proxy_repo_url"): raise ConfigError( 'The configuration "cachito_nexus_npm_proxy_repo_url" must be set for this package ' "manager")
def validate_pip_config(): """ Perform validation on the Celery configuration for the pip package manager. :raise ConfigError: if the Celery configuration isn't configured for pip """ validate_nexus_config() conf = get_worker_config() for pip_config in ("cachito_nexus_pypi_proxy_url", "cachito_nexus_pip_raw_repo_name"): if not conf.get(pip_config): raise ConfigError( f'The configuration "{pip_config}" must be set for this package manager' )
def validate_celery_config(conf, **kwargs): """ Perform basic validation on the Celery configuration when the worker is initialized. :param celery.app.utils.Settings conf: the Celery application configuration to validate :raises ConfigError: if the configuration is invalid """ for required_dir_conf in ("cachito_bundles_dir", "cachito_sources_dir"): required_dir = conf.get(required_dir_conf) if not required_dir or not os.path.isdir(required_dir): raise ConfigError( f'The configuration "{required_dir_conf}" must be set to an existing directory' ) if not conf.get("cachito_api_url"): raise ConfigError('The configuration "cachito_api_url" must be set') hoster_username = conf.get("cachito_nexus_hoster_username") hoster_password = conf.get("cachito_nexus_hoster_password") if (hoster_username or hoster_password) and not (hoster_username and hoster_password): raise ConfigError( 'If "cachito_nexus_hoster_username" or "cachito_nexus_hoster_password" is set, ' "the other must also be set" ) if conf.get("cachito_auth_type") == "cert" and conf.get("cachito_auth_cert") is None: raise ConfigError('cachito_auth_cert configuration must be set for "cert" authentication') if not isinstance(conf.get("cachito_default_environment_variables"), dict): raise ConfigError( 'The configuration "cachito_default_environment_variables" must be a dictionary' ) default_env_vars = conf.cachito_default_environment_variables for pkg_manager_value in default_env_vars.values(): if not isinstance(pkg_manager_value, dict): raise ConfigError( 'The configuration "cachito_default_environment_variables" must be a ' "dictionary of dictionaries" ) for env_var_info in pkg_manager_value.values(): if not isinstance(env_var_info, dict): raise ConfigError( 'The configuration "cachito_default_environment_variables" must be a ' "dictionary of dictionaries of dictionaries!" ) if set(env_var_info.keys()) != {"value", "kind"}: raise ConfigError( 'Each environment variable in the "cachito_default_environment_variables" ' 'configuration must contain the "value" and "kind" keys' ) invalid_gomod_env_vars = default_env_vars.get("gomod", {}).keys() & {"GOCACHE", "GOPATH"} if invalid_gomod_env_vars: raise ConfigError( 'The configuration "cachito_default_environment_variables.gomod" cannot overwrite the ' f"following environment variables: {', '.join(invalid_gomod_env_vars)}" ) cachito_request_file_logs_dir = conf.get("cachito_request_file_logs_dir") if cachito_request_file_logs_dir: if not os.path.isdir(cachito_request_file_logs_dir): raise ConfigError( f"cachito_request_file_logs_dir, {cachito_request_file_logs_dir}," " must exist and be a directory" ) if not os.access(cachito_request_file_logs_dir, os.W_OK): raise ConfigError( f"cachito_request_file_logs_dir, {cachito_request_file_logs_dir}, is not writable!" )