cortex-tools icon indicating copy to clipboard operation
cortex-tools copied to clipboard

YAML format of `rules get` should match `rules sync`

Open lukebigum opened this issue 4 years ago • 2 comments
trafficstars

It would be helpful if the output format of cortextool rules get <namespace> <group> matched the exact format expected to cortextool rules sync. This would make it easier to get down all rules and commit them into Git, then sync them back again. Right now I have to munge the YAML slightly to make it compatible to sync.

Right now the format is this:

$ cortextool rules get somenamespace anygroup
name: anygroup
rules:
    - alert: FrontEnd Prometheus
      expr: .......

Ideally it would be this:

namespace: somenamespace
groups:
    - name: anygroup
      rules:
        - alert: FrontEnd Prometheus
          expr: ........

lukebigum avatar Jan 13 '21 15:01 lukebigum

A simper test:

$ cortextool rules print --disable-color > tmp.yml
$ cortextool rules sync tmp.yml 
ERRO[0000] unable parse rules file                       error="yaml: unmarshal errors:\n  line 1: field group1 not found in type rules.RuleNamespace\n  line 13: field group2 not found in type rules.RuleNamespace" file=tmp.yml
cortextool: error: sync operation unsuccessful, unable to parse rules files: file read error, try --help

lukebigum avatar Jan 13 '21 15:01 lukebigum

To circumvent this annoyance I've written a small script to convert the content generated by coretextool rules print.

$ cortextool rules print --disable-color > tmp.yml
$ ./split.py tmp.yml
$ rules check --rule-dirs=rules && echo OK
OK
#!/usr/bin/env python3

import argparse
import os
import yaml


def _load_yaml(path):
    with open(path) as file:
        return yaml.load(file, Loader=yaml.FullLoader)


def _write_yaml(data, path):
    with open(path, "w") as file:
        yaml.dump(data, file, sort_keys=False, width=9999)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("namespaces_file", type=str)
    args = parser.parse_args()

    base_dir = os.path.dirname(os.path.abspath(args.namespaces_file))
    rules_dir = os.path.join(base_dir, "rules")
    os.makedirs(rules_dir)

    for namespace, groups in _load_yaml(args.namespaces_file).items():
        _write_yaml(
            data={"namespace": namespace, "groups": groups},
            path=os.path.join(rules_dir, f"{namespace}.yaml"),
        )


if __name__ == "__main__":
    main()

Granddave avatar Jul 06 '21 12:07 Granddave