def main(): """slo-generator CLI entrypoint.""" utils.setup_logging() args = parse_args(sys.argv[1:]) export = args.export # Load error budget policy error_budget_path = utils.normalize(args.error_budget_policy) LOGGER.debug(f"Loading Error Budget config from {error_budget_path}") error_budget_policy = utils.parse_config(error_budget_path) # Parse SLO folder for configs slo_config = args.slo_config if os.path.isfile(slo_config): slo_config_paths = [args.slo_config] else: slo_config_folder = utils.normalize(slo_config) slo_config_paths = glob.glob(f'{slo_config_folder}/slo_*.yaml') # Abort if configs are not found if not slo_config_paths: LOGGER.error( f'No SLO configs found in SLO folder {slo_config_folder}.') # Load SLO configs and compute SLO reports for cfg in slo_config_paths: slo_config_path = utils.normalize(cfg) LOGGER.debug(f'Loading SLO config from {slo_config_path}') slo_config = utils.parse_config(slo_config_path) compute(slo_config, error_budget_policy, do_export=export)
def cli(args): """Main CLI function. Args: args (Namespace): Argparsed CLI parameters. Returns: dict: Dict of all reports indexed by config file path. """ utils.setup_logging() export = args.export delete = args.delete timestamp = args.timestamp start = time.time() # Load error budget policy LOGGER.debug( f"Loading Error Budget config from {args.error_budget_policy}") eb_path = utils.normalize(args.error_budget_policy) eb_policy = utils.parse_config(eb_path) # Parse SLO folder for configs slo_configs = utils.list_slo_configs(args.slo_config) if not slo_configs: LOGGER.error(f'No SLO configs found in SLO folder {args.slo_config}.') # Load SLO configs and compute SLO reports all_reports = {} for path in slo_configs: slo_config_name = path.split("/")[-1] LOGGER.debug(f'Loading SLO config "{slo_config_name}"') slo_config = utils.parse_config(path) reports = compute(slo_config, eb_policy, timestamp=timestamp, do_export=export, delete=delete) all_reports[path] = reports end = time.time() duration = round(end - start, 1) LOGGER.info(f'Run summary | SLO Configs: {len(slo_configs)} | ' f'Error Budget Policy Steps: {len(eb_policy)} | ' f'Total: {len(slo_configs) * len(eb_policy)} | ' f'Duration: {duration}s') return all_reports
def test_slo_config(name): slo_config_path = utils.get_slo_config(name)['_path'] ebp_config_path = os.path.abspath(constants.ERROR_BUDGET_POLICY_PATH) try: from slo_generator.utils import parse_config from slo_generator.compute import compute slo_config = parse_config(slo_config_path) ebp_config = parse_config(ebp_config_path) timestamp = time.time() reports = compute(slo_config, ebp_config, timestamp=timestamp, do_export=False) return {"success": True, "data": reports} except Exception as e: app.logger.exception(e) return { "success": False, "errorMessage": f"Test failed: {repr(e)}", "traceback": traceback.format_exc() }
def load_sample(filename, **ctx): """Load a sample from the samples/ directory and replace context environmental variables in it. Args: filename (str): Filename of the fixture to load. ctx (dict): Context dictionary (env variables). Returns: dict: Loaded sample. """ filename = os.path.join(SAMPLE_DIR, filename) return parse_config(filename, ctx)
def load_fixture(filename, **ctx): """Load a fixture from the test/fixtures/ directory and replace context environmental variables in it. Args: filename (str): Filename of the fixture to load. ctx (dict): Context dictionary (env variables). Returns: dict: Loaded fixture. """ filename = os.path.join(TEST_DIR, "fixtures/", filename) return parse_config(filename, ctx)