2019-10-08 09:39:27 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
"""Global settings definition."""
|
2019-10-07 12:44:45 +00:00
|
|
|
|
2019-10-07 06:52:00 +00:00
|
|
|
import os
|
|
|
|
|
2019-10-07 12:44:45 +00:00
|
|
|
from appdirs import AppDirs
|
2024-06-07 19:51:10 +00:00
|
|
|
from dynaconf import Dynaconf, ValidationError, Validator
|
2019-10-07 06:52:00 +00:00
|
|
|
|
2021-01-01 12:50:41 +00:00
|
|
|
import ansibledoctor.exception
|
|
|
|
from ansibledoctor.utils import Singleton
|
2019-10-07 06:52:00 +00:00
|
|
|
|
2019-10-07 12:44:45 +00:00
|
|
|
|
2023-06-28 07:57:00 +00:00
|
|
|
class Config:
|
2024-06-07 19:51:10 +00:00
|
|
|
"""Create configuration object."""
|
2019-10-08 22:56:39 +00:00
|
|
|
|
|
|
|
ANNOTATIONS = {
|
|
|
|
"meta": {
|
|
|
|
"name": "meta",
|
2019-10-15 07:54:03 +00:00
|
|
|
"automatic": True,
|
2022-02-21 20:38:47 +00:00
|
|
|
"subtypes": ["value"],
|
2023-11-10 13:50:50 +00:00
|
|
|
"allow_multiple": False,
|
2019-10-08 22:56:39 +00:00
|
|
|
},
|
|
|
|
"todo": {
|
|
|
|
"name": "todo",
|
|
|
|
"automatic": True,
|
2022-02-21 20:38:47 +00:00
|
|
|
"subtypes": ["value"],
|
2023-11-10 13:50:50 +00:00
|
|
|
"allow_multiple": True,
|
2019-10-08 22:56:39 +00:00
|
|
|
},
|
|
|
|
"var": {
|
|
|
|
"name": "var",
|
|
|
|
"automatic": True,
|
2023-03-27 11:18:42 +00:00
|
|
|
"subtypes": ["value", "example", "description", "type", "deprecated"],
|
2023-11-10 13:50:50 +00:00
|
|
|
"allow_multiple": False,
|
2019-10-08 22:56:39 +00:00
|
|
|
},
|
|
|
|
"example": {
|
|
|
|
"name": "example",
|
2019-10-15 07:54:03 +00:00
|
|
|
"automatic": True,
|
2022-02-21 20:38:47 +00:00
|
|
|
"subtypes": [],
|
2023-11-10 13:50:50 +00:00
|
|
|
"allow_multiple": False,
|
2019-10-08 22:56:39 +00:00
|
|
|
},
|
|
|
|
"tag": {
|
|
|
|
"name": "tag",
|
|
|
|
"automatic": True,
|
2022-02-26 12:35:34 +00:00
|
|
|
"subtypes": ["value", "description"],
|
2023-11-10 13:50:50 +00:00
|
|
|
"allow_multiple": False,
|
2019-10-08 22:56:39 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-06-07 19:51:10 +00:00
|
|
|
def __init__(self):
|
|
|
|
self.config_files = [
|
|
|
|
os.path.join(AppDirs("ansible-doctor").user_config_dir, "config.yml"),
|
|
|
|
".ansibledoctor",
|
|
|
|
".ansibledoctor.yml",
|
|
|
|
".ansibledoctor.yaml",
|
|
|
|
]
|
|
|
|
self.config_merge = True
|
|
|
|
self.args = {}
|
|
|
|
self.load()
|
|
|
|
|
|
|
|
def load(self, root_path=None, args=None):
|
|
|
|
if args:
|
|
|
|
if args.get("config_file"):
|
|
|
|
self.config_merge = False
|
|
|
|
self.config_files = [os.path.abspath(args.get("config_file"))]
|
|
|
|
args.pop("config_file")
|
|
|
|
|
|
|
|
self.args = args
|
|
|
|
|
|
|
|
self.config = Dynaconf(
|
|
|
|
envvar_prefix="ANSIBLE_DOCTOR",
|
|
|
|
merge_enabled=self.config_merge,
|
|
|
|
core_loaders=["YAML"],
|
|
|
|
root_path=root_path,
|
|
|
|
settings_files=self.config_files,
|
|
|
|
fresh_vars=["base_dir", "output_dir"],
|
|
|
|
validators=[
|
|
|
|
Validator(
|
|
|
|
"base_dir",
|
|
|
|
default=os.getcwd(),
|
|
|
|
apply_default_on_none=True,
|
|
|
|
is_type_of=str,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"dry_run",
|
|
|
|
default=False,
|
|
|
|
is_type_of=bool,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"recursive",
|
|
|
|
default=False,
|
|
|
|
is_type_of=bool,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"exclude_files",
|
|
|
|
default=[],
|
|
|
|
is_type_of=list,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"exclude_tags",
|
|
|
|
default=[],
|
|
|
|
is_type_of=list,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"role.name",
|
|
|
|
is_type_of=str,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"role.autodetect",
|
|
|
|
default=True,
|
|
|
|
is_type_of=bool,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"logging.level",
|
|
|
|
default="WARNING",
|
|
|
|
is_in=[
|
|
|
|
"DEBUG",
|
|
|
|
"INFO",
|
|
|
|
"WARNING",
|
|
|
|
"ERROR",
|
|
|
|
"CRITICAL",
|
|
|
|
"debug",
|
|
|
|
"info",
|
|
|
|
"warning",
|
|
|
|
"error",
|
|
|
|
"critical",
|
|
|
|
],
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"logging.json",
|
|
|
|
default=False,
|
|
|
|
is_type_of=bool,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"recursive",
|
|
|
|
default=False,
|
|
|
|
is_type_of=bool,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"template.src",
|
|
|
|
default=os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates"),
|
|
|
|
is_type_of=str,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"template.name",
|
|
|
|
default="readme",
|
|
|
|
is_type_of=str,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"template.options.tabulate_variables",
|
|
|
|
default=False,
|
|
|
|
is_type_of=bool,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"renderer.autotrim",
|
|
|
|
default=True,
|
|
|
|
is_type_of=bool,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"renderer.include_header",
|
|
|
|
default="",
|
|
|
|
is_type_of=str,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"renderer.dest",
|
|
|
|
default=os.path.relpath(os.getcwd()),
|
|
|
|
is_type_of=str,
|
|
|
|
),
|
|
|
|
Validator(
|
|
|
|
"renderer.force_overwrite",
|
|
|
|
default=False,
|
|
|
|
is_type_of=bool,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
2019-10-07 12:44:45 +00:00
|
|
|
|
2024-06-07 19:51:10 +00:00
|
|
|
self.validate()
|
2019-10-07 12:44:45 +00:00
|
|
|
|
|
|
|
# Override correct log level from argparse
|
|
|
|
levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
2024-06-07 19:51:10 +00:00
|
|
|
log_level = levels.index(self.config.logging.level.upper())
|
|
|
|
if self.args.get("logging.level") and isinstance(self.args["logging.level"], list):
|
|
|
|
for lvl in self.args["logging.level"]:
|
|
|
|
log_level = min(len(levels) - 1, max(log_level + lvl, 0))
|
2023-02-12 11:57:57 +00:00
|
|
|
|
2024-06-07 19:51:10 +00:00
|
|
|
self.args["logging__level"] = levels[log_level]
|
2023-02-12 11:57:57 +00:00
|
|
|
|
2024-06-07 19:51:10 +00:00
|
|
|
if root_path:
|
|
|
|
self.args["base_dir"] = root_path
|
2019-10-08 22:56:39 +00:00
|
|
|
|
2024-06-07 19:51:10 +00:00
|
|
|
self.config.update(self.args)
|
|
|
|
self.validate()
|
2019-10-07 12:44:45 +00:00
|
|
|
|
2024-06-07 19:51:10 +00:00
|
|
|
def validate(self):
|
2019-10-07 12:44:45 +00:00
|
|
|
try:
|
2024-06-07 19:51:10 +00:00
|
|
|
self.config.validators.validate_all()
|
|
|
|
except ValidationError as e:
|
|
|
|
raise ansibledoctor.exception.ConfigError("Configuration error", e.message) from e
|
2019-10-07 12:44:45 +00:00
|
|
|
|
2024-06-07 19:51:10 +00:00
|
|
|
def is_role(self):
|
|
|
|
self.config.role_name = self.config.get(
|
|
|
|
"role_name", os.path.basename(self.config.base_dir)
|
2023-11-10 13:50:50 +00:00
|
|
|
)
|
2024-06-07 19:51:10 +00:00
|
|
|
return os.path.isdir(os.path.join(self.config.base_dir, "tasks"))
|
2019-10-07 06:52:00 +00:00
|
|
|
|
|
|
|
def get_annotations_definition(self, automatic=True):
|
|
|
|
annotations = {}
|
|
|
|
if automatic:
|
2019-10-08 22:56:39 +00:00
|
|
|
for k, item in self.ANNOTATIONS.items():
|
2024-02-06 08:34:17 +00:00
|
|
|
if item.get("automatic"):
|
2019-10-07 06:52:00 +00:00
|
|
|
annotations[k] = item
|
|
|
|
return annotations
|
|
|
|
|
|
|
|
def get_annotations_names(self, automatic=True):
|
|
|
|
annotations = []
|
|
|
|
if automatic:
|
2019-10-08 22:56:39 +00:00
|
|
|
for k, item in self.ANNOTATIONS.items():
|
2024-02-06 08:34:17 +00:00
|
|
|
if item.get("automatic"):
|
2019-10-07 06:52:00 +00:00
|
|
|
annotations.append(k)
|
|
|
|
return annotations
|
|
|
|
|
2019-10-07 12:44:45 +00:00
|
|
|
def get_template(self):
|
2019-10-07 06:52:00 +00:00
|
|
|
"""
|
|
|
|
Get the base dir for the template to use.
|
|
|
|
|
|
|
|
:return: str abs path
|
|
|
|
"""
|
2024-06-07 19:51:10 +00:00
|
|
|
template_base = self.config.get("template.src")
|
|
|
|
template_name = self.config.get("template.name")
|
|
|
|
return os.path.realpath(os.path.join(template_base, template_name))
|
2019-10-07 06:52:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
class SingleConfig(Config, metaclass=Singleton):
|
2020-04-05 21:16:53 +00:00
|
|
|
"""Singleton config class."""
|
|
|
|
|
2019-10-07 06:52:00 +00:00
|
|
|
pass
|