Skip to content

Commit

Permalink
Add enable flag to cli commands
Browse files Browse the repository at this point in the history
  • Loading branch information
prymitive committed Aug 23, 2024
1 parent 074b42b commit f99a6a1
Show file tree
Hide file tree
Showing 14 changed files with 439 additions and 166 deletions.
2 changes: 1 addition & 1 deletion cmd/pint/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ rule {
require.NoError(b, os.WriteFile(tmp+"/.pint.hcl", content, 0o644))

ctx := context.Background()
cfg, err := config.Load(tmp+"/.pint.hcl", false)
cfg, _, err := config.Load(tmp+"/.pint.hcl", false)
require.NoError(b, err)

gen := config.NewPrometheusGenerator(cfg, prometheus.NewRegistry())
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func actionConfig(c *cli.Context) (err error) {
return fmt.Errorf("failed to set log level: %w", err)
}

cfg, err := config.Load(c.Path(configFlag), c.IsSet(configFlag))
cfg, _, err := config.Load(c.Path(configFlag), c.IsSet(configFlag))
if err != nil {
return fmt.Errorf("failed to load config file %q: %w", c.Path(configFlag), err)
}
Expand Down
20 changes: 19 additions & 1 deletion cmd/pint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
const (
configFlag = "config"
logLevelFlag = "log-level"
enabledFlag = "enabled"
disabledFlag = "disabled"
offlineFlag = "offline"
noColorFlag = "no-color"
Expand Down Expand Up @@ -59,6 +60,12 @@ func newApp() *cli.App {
Value: cli.NewStringSlice(),
Usage: "List of checks to disable (example: promql/cost).",
},
&cli.StringSliceFlag{
Name: enabledFlag,
Aliases: []string{"e"},
Value: cli.NewStringSlice(),
Usage: "Only enable these checks (example: promql/cost).",
},
&cli.BoolFlag{
Name: offlineFlag,
Aliases: []string{"o"},
Expand Down Expand Up @@ -100,11 +107,22 @@ func actionSetup(c *cli.Context) (meta actionMeta, err error) {
return meta, fmt.Errorf("--%s flag must be > 0", workersFlag)
}

meta.cfg, err = config.Load(c.Path(configFlag), c.IsSet(configFlag))
var fromFile bool
meta.cfg, fromFile, err = config.Load(c.Path(configFlag), c.IsSet(configFlag))
if err != nil {
return meta, fmt.Errorf("failed to load config file %q: %w", c.Path(configFlag), err)
}
if fromFile {
slog.Debug("Adding pint config to the parser exclude list", slog.String("path", c.Path(configFlag)))
meta.cfg.Parser.Exclude = append(meta.cfg.Parser.Exclude, c.Path(configFlag))
}

meta.cfg.SetDisabledChecks(c.StringSlice(disabledFlag))
enabled := c.StringSlice(enabledFlag)
if len(enabled) > 0 {
meta.cfg.Checks.Enabled = enabled
}

if c.Bool(offlineFlag) {
meta.isOffline = true
meta.cfg.DisableOnlineChecks()
Expand Down
44 changes: 44 additions & 0 deletions cmd/pint/tests/0183_cli_enable.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
pint.ok -l debug --no-color -e promql/aggregate lint rules
! stdout .
cmp stderr stderr.txt

-- stderr.txt --
level=INFO msg="Loading configuration file" path=.pint.hcl
level=DEBUG msg="Adding pint config to the parser exclude list" path=.pint.hcl
level=INFO msg="Finding all rules to check" paths=["rules"]
level=DEBUG msg="File parsed" path=rules/0001.yml rules=3
level=DEBUG msg="Glob finder completed" count=3
level=DEBUG msg="Generated all Prometheus servers" count=0
level=DEBUG msg="Found alerting rule" path=rules/0001.yml alert=default-for lines=1-3
level=DEBUG msg="Configured checks for rule" enabled=[] path=rules/0001.yml rule=default-for
level=DEBUG msg="Found recording rule" path=rules/0001.yml record=sum:job lines=5-6
level=DEBUG msg="Configured checks for rule" enabled=["promql/aggregate(job:true)"] path=rules/0001.yml rule=sum:job
level=DEBUG msg="Found alerting rule" path=rules/0001.yml alert=no-comparison lines=8-9
level=DEBUG msg="Configured checks for rule" enabled=[] path=rules/0001.yml rule=no-comparison
rules/0001.yml:6 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate)
6 | expr: sum(foo)

level=INFO msg="Problems found" Warning=1
-- rules/0001.yml --
- alert: default-for
expr: foo > 1
for: 0m

- record: sum:job
expr: sum(foo)

- alert: no-comparison
expr: foo

-- .pint.hcl --
parser {
relaxed = [".*"]
}
rule {
match {
kind = "recording"
}
aggregate ".+" {
keep = [ "job" ]
}
}
40 changes: 40 additions & 0 deletions cmd/pint/tests/0184_ci_file_ignore.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
mkdir testrepo
cd testrepo
exec git init --initial-branch=main .

cp ../src/rules.yml rules.yml
cp ../src/.pint.hcl .
env GIT_AUTHOR_NAME=pint
env [email protected]
env GIT_COMMITTER_NAME=pint
env [email protected]
exec git add .
exec git commit -am 'import rules and config'

exec git checkout -b v2
exec touch .keep
exec git add .keep
exec git commit -am 'v2'

pint.ok --no-color ci
! stdout .
cmp stderr ../stderr.txt

-- stderr.txt --
level=INFO msg="Loading configuration file" path=.pint.hcl
level=INFO msg="Finding all rules to check on current git branch" base=main
-- src/rules.yml --
# pint ignore/file
- record: rule1
expr: sum(foo) by(job)
- record: rule2
expr: sum(foo)

-- src/.pint.hcl --
ci {
baseBranch = "main"
}
parser {
relaxed = [".*"]
include = ["rules.yml"]
}
3 changes: 3 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
See check docs for details.
- [promql/range_query](checks/promql/range_query.md) now allows to configure a custom maximum
duration for range queries - #1064.
- Added `--enabled` flag to the pint command. Passing this flag will only run selected check(s).

### Fixed

- Don't try to report problem on unmodified files when using GitHub reporter.
- If there is a pint config file present then pint will now always add it to the `parser` block `exclude` list.
This is to avoid trying to parse it as a rule file if it's included in the same folder as rules.

## v0.64.1

Expand Down
52 changes: 52 additions & 0 deletions internal/checks/promql_rate_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package checks_test

import (
"errors"
"fmt"
"testing"
"time"

v1 "github.com/prometheus/client_golang/api/prometheus/v1"

"github.com/cloudflare/pint/internal/checks"
"github.com/cloudflare/pint/internal/discovery"
"github.com/cloudflare/pint/internal/parser"
"github.com/cloudflare/pint/internal/promapi"
)
Expand Down Expand Up @@ -787,6 +789,56 @@ func TestRateCheck(t *testing.T) {
},
},
},
{
description: "sum_over_rate / ignore entry with PathError",
content: "- alert: my alert\n expr: rate(my:sum[5m])\n",
entries: []discovery.Entry{{PathError: errors.New("mock error")}},
checker: newRateCheck,
prometheus: newSimpleProm,
problems: noProblems,
mocks: []*prometheusMock{
{
conds: []requestCondition{requireConfigPath},
resp: configResponse{yaml: "global:\n scrape_interval: 1m\n"},
},
{
conds: []requestCondition{
requireMetadataPath,
formCond{"metric", "my:sum"},
},
resp: metadataResponse{metadata: map[string][]v1.Metadata{}},
},
},
},
{
description: "sum_over_rate / ignore entry with rule error",
content: "- alert: my alert\n expr: rate(my:sum[5m])\n",
entries: []discovery.Entry{
{
Rule: parser.Rule{
Error: parser.ParseError{
Err: errors.New("mock error"),
},
},
},
},
checker: newRateCheck,
prometheus: newSimpleProm,
problems: noProblems,
mocks: []*prometheusMock{
{
conds: []requestCondition{requireConfigPath},
resp: configResponse{yaml: "global:\n scrape_interval: 1m\n"},
},
{
conds: []requestCondition{
requireMetadataPath,
formCond{"metric", "my:sum"},
},
resp: metadataResponse{metadata: map[string][]v1.Metadata{}},
},
},
},
}
runTests(t, testCases)
}
31 changes: 16 additions & 15 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (cfg *Config) GetChecksForRule(ctx context.Context, gen *PrometheusGenerato
}

for _, rule := range cfg.Rules {
allChecks = append(allChecks, rule.resolveChecks(ctx, entry.Path.Name, entry.Rule, proms)...)
allChecks = append(allChecks, rule.resolveChecks(ctx, entry, proms)...)
}

for _, cm := range allChecks {
Expand Down Expand Up @@ -219,7 +219,7 @@ func getContext() *hcl.EvalContext {
return &hcl.EvalContext{Variables: vars}
}

func Load(path string, failOnMissing bool) (cfg Config, err error) {
func Load(path string, failOnMissing bool) (cfg Config, fromFile bool, err error) {
cfg = Config{
CI: &CI{
MaxCommits: 20,
Expand All @@ -237,81 +237,82 @@ func Load(path string, failOnMissing bool) (cfg Config, err error) {
}

if _, err = os.Stat(path); err == nil || failOnMissing {
fromFile = true
slog.Info("Loading configuration file", slog.String("path", path))
ectx := getContext()
err = hclsimple.DecodeFile(path, ectx, &cfg)
if err != nil {
return cfg, err
return cfg, fromFile, err
}
}

if cfg.CI != nil {
if err = cfg.CI.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}
}

if cfg.Owners != nil {
if err = cfg.Owners.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}
}

if cfg.Parser != nil {
if err = cfg.Parser.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}
}

if cfg.Repository != nil {
if err = cfg.Repository.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}
}

if cfg.Checks != nil {
if err = cfg.Checks.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}
}

for _, chk := range cfg.Check {
if err = chk.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}
}

promNames := make([]string, 0, len(cfg.Prometheus))
for i, prom := range cfg.Prometheus {
if err = prom.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}

if slices.Contains(promNames, prom.Name) {
return cfg, fmt.Errorf("prometheus server name must be unique, found two or more config blocks using %q name", prom.Name)
return cfg, fromFile, fmt.Errorf("prometheus server name must be unique, found two or more config blocks using %q name", prom.Name)
}
promNames = append(promNames, prom.Name)

cfg.Prometheus[i].applyDefaults()

if _, err = prom.TLS.toHTTPConfig(); err != nil {
return cfg, fmt.Errorf("invalid prometheus TLS configuration: %w", err)
return cfg, fromFile, fmt.Errorf("invalid prometheus TLS configuration: %w", err)
}
}

if cfg.Discovery != nil {
if err = cfg.Discovery.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}
}

for _, rule := range cfg.Rules {
if err = rule.validate(); err != nil {
return cfg, err
return cfg, fromFile, err
}
}

return cfg, nil
return cfg, fromFile, nil
}

func parseDuration(d string) (time.Duration, error) {
Expand Down
Loading

0 comments on commit f99a6a1

Please sign in to comment.