''' config.py used for generation service configuration based on input json file ''' from datetime import datetime from pathlib import Path from typing import Dict, List from ipaddress import IPv4Address from pydantic import BaseModel, validator, Field # pylint: disable=import-error,no-name-in-module import yaml # DEFAULTS DIFF_FILE = Path('/tmp/albs-oval-errata-diff.json') DOWNLOAD_DIR = Path('/tmp') LOG_FILE = Path('logs/albs-oval-errata-diff.log') PACKAGES_EXCLUDE = [] ADVISORY_EXCLUDE = [] SERVER_PORT = 3001 SERVER_IP = IPv4Address('127.0.0.1') # not checking anything before RHEL-9.0 release NOT_BEFORE = datetime(2022, 5, 18) UPDATE_INTERVAL_MINUTES = 30 class ReleaseUrls(BaseModel): """ ReleaseUrls represents list of RHEL/Alma Oval and Errata URLS for specific OS release """ rhel_oval_url: str = Field(description='URL for RHEL OVAL file') alma_oval_url: str = Field(description='URL for Alma OVAL file') alma_errata_url: str = Field(description='URL for Alma Errata file') class Config(BaseModel): """ Config represents service configuration """ diff_file: Path = Field(description="file to store diff JSON in", default=DIFF_FILE) download_dir: Path = Field( description='directory to download Oval/Errata files to', default=DOWNLOAD_DIR) log_file: Path = Field( description='file to write logs to', default=LOG_FILE) packages_exclude: List[str] = Field( description='list of RPM package names to exclude from checking', default=PACKAGES_EXCLUDE) releases: Dict[int, ReleaseUrls] = Field( description='list of OS releases with Oval/Errata URLs to check') advisory_exclude: List[str] = Field( description='list of Security Advisory IDs (ALSA-2022:5219) to exclude from checking', default=ADVISORY_EXCLUDE) server_port: int = Field( description='port that will be used by websever', default=SERVER_PORT) server_ip: IPv4Address = Field( description='IP that will be used by webserver', default=SERVER_IP) not_before: datetime = Field( description='date to start checking from (YYYY-mm-dd)', default=NOT_BEFORE) update_interval_minutes: int = Field( description='how often service will be running difference checks (in minutes)', default=UPDATE_INTERVAL_MINUTES) @validator("releases", pre=True) @classmethod def parse_releases(cls, value) -> Dict[int, ReleaseUrls]: """ parse_release converts releases attribute Dict[int, Dict[str, str]] -> Dict[str, ReleaseUrls] """ result: Dict[int, ReleaseUrls] = {} for release, urls in value.items(): result[release] = ReleaseUrls(rhel_oval_url=urls['rhel_oval_url'], alma_oval_url=urls['alma_oval_url'], alma_errata_url=urls['alma_errata_url']) return result @validator("not_before", pre=True) @classmethod def str_to_datetime(cls, value) -> datetime: """ str_to_datetime converts string attr str -> datetime """ return datetime.strptime( value, "%Y-%m-%d") def get_config(yml_path: str) -> Config: """ get_config loads yml file and generates Config instance """ with open(yml_path, 'r', encoding='utf-8') as flr: data = yaml.safe_load(flr) return Config(**data) if __name__ == "__main__": print(get_config('./config.default.yml'))