Example #1
0
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)
Example #2
0
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
Example #3
0
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()
        }
Example #4
0
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)
Example #5
0
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)