...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package cli
15
16 import (
17 "context"
18 "fmt"
19 "os"
20 "strings"
21
22 "github.com/xlab/treeprint"
23 "gopkg.in/alecthomas/kingpin.v2"
24
25 "github.com/prometheus/alertmanager/api/v2/models"
26 "github.com/prometheus/alertmanager/dispatch"
27 )
28
29 const routingTestHelp = `Test alert routing
30
31 Will return receiver names which the alert with given labels resolves to.
32 If the labelset resolves to multiple receivers, they are printed out in order as defined in the routing tree.
33
34 Routing is loaded from a local configuration file or a running Alertmanager configuration.
35 Specifying --config.file takes precedence over --alertmanager.url.
36
37 Example:
38
39 ./amtool config routes test --config.file=doc/examples/simple.yml --verify.receivers=team-DB-pager service=database
40
41 `
42
43 func configureRoutingTestCmd(cc *kingpin.CmdClause, c *routingShow) {
44 routingTestCmd := cc.Command("test", routingTestHelp)
45
46 routingTestCmd.Flag("verify.receivers", "Checks if specified receivers matches resolved receivers. The command fails if the labelset does not route to the specified receivers.").StringVar(&c.expectedReceivers)
47 routingTestCmd.Flag("tree", "Prints out matching routes tree.").BoolVar(&c.debugTree)
48 routingTestCmd.Arg("labels", "List of labels to be tested against the configured routes.").StringsVar(&c.labels)
49 routingTestCmd.Action(execWithTimeout(c.routingTestAction))
50 }
51
52
53 func resolveAlertReceivers(mainRoute *dispatch.Route, labels *models.LabelSet) ([]string, error) {
54 var (
55 finalRoutes []*dispatch.Route
56 receivers []string
57 )
58 finalRoutes = mainRoute.Match(convertClientToCommonLabelSet(*labels))
59 for _, r := range finalRoutes {
60 receivers = append(receivers, r.RouteOpts.Receiver)
61 }
62 return receivers, nil
63 }
64
65 func printMatchingTree(mainRoute *dispatch.Route, ls models.LabelSet) {
66 tree := treeprint.New()
67 getMatchingTree(mainRoute, tree, ls)
68 fmt.Println("Matching routes:")
69 fmt.Println(tree.String())
70 fmt.Print("\n")
71 }
72
73 func (c *routingShow) routingTestAction(ctx context.Context, _ *kingpin.ParseContext) error {
74 cfg, err := loadAlertmanagerConfig(ctx, alertmanagerURL, c.configFile)
75 if err != nil {
76 kingpin.Fatalf("%v\n", err)
77 return err
78 }
79
80 mainRoute := dispatch.NewRoute(cfg.Route, nil)
81
82
83 ls, err := parseLabels(c.labels)
84 if err != nil {
85 kingpin.Fatalf("Failed to parse labels: %v\n", err)
86 }
87
88 if c.debugTree {
89 printMatchingTree(mainRoute, ls)
90 }
91
92 receivers, err := resolveAlertReceivers(mainRoute, &ls)
93 receiversSlug := strings.Join(receivers, ",")
94 fmt.Printf("%s\n", receiversSlug)
95
96 if c.expectedReceivers != "" && c.expectedReceivers != receiversSlug {
97 fmt.Printf("WARNING: Expected receivers did not match resolved receivers.\n")
98 os.Exit(1)
99 }
100
101 return err
102 }
103
View as plain text