Skip to content

Commit

Permalink
Merge pull request #66 from NETWAYS/no-alerts-logic
Browse files Browse the repository at this point in the history
Rework logic when there are no alerts defined
  • Loading branch information
martialblog authored Dec 18, 2024
2 parents 271f051 + c4706c1 commit 67fb855
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 16 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,12 @@ Examples:
| total=2 firing=1 pending=0 inactive=1
Flags:
-h, --help help for alert
-n, --name strings The name of one or more specific alerts to check.
This parameter can be repeated e.G.: '--name alert1 --name alert2'
If no name is given, all alerts will be evaluated
-P, --problems Display only alerts which status is not inactive/OK
-h, --help help for alert
-n, --name strings The name of one or more specific alerts to check.
This parameter can be repeated e.G.: '--name alert1 --name alert2'
If no name is given, all alerts will be evaluated
-T, --no-alerts-state string State to assign when no alerts are found (0, 1, 2, 3, OK, WARNING, CRITICAL, UNKNOWN). If not set this defaults to OK (default "OK")
-P, --problems Display only alerts which status is not inactive/OK. Note that in combination with the --name flag this might result in no alerts being displayed
```
#### Checking all defined alerts
Expand Down
52 changes: 51 additions & 1 deletion cmd/alert.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package cmd

import (
"errors"
"fmt"
"strings"

"github.com/NETWAYS/check_prometheus/internal/alert"
"github.com/NETWAYS/go-check"
Expand All @@ -10,6 +12,15 @@ import (
"github.com/spf13/cobra"
)

type AlertConfig struct {
AlertName []string
Group []string
ProblemsOnly bool
NoAlertsState string
}

var cliAlertConfig AlertConfig

func contains(s string, list []string) bool {
// Tiny helper to see if a string is in a list of strings
for _, elem := range list {
Expand Down Expand Up @@ -40,14 +51,21 @@ inactive = 0`,
\_[CRITICAL] [PrometheusAlertmanagerJobMissing] - Job: [alertmanager] is firing - value: 1.00
| total=2 firing=1 pending=0 inactive=1`,
Run: func(_ *cobra.Command, _ []string) {
// Convert --no-alerts-state to integer and validate input
noAlertsState, err := convertStateToInt(cliAlertConfig.NoAlertsState)
if err != nil {
check.ExitError(fmt.Errorf("invalid value for --no-alerts-state: %s", cliAlertConfig.NoAlertsState))
}

var (
counterFiring int
counterPending int
counterInactive int
)

c := cliConfig.NewClient()
err := c.Connect()
err = c.Connect()

if err != nil {
check.ExitError(err)
}
Expand All @@ -65,6 +83,16 @@ inactive = 0`,
// Get all rules from all groups into a single list
rules := alert.FlattenRules(alerts.Groups)

// If there are no rules we can exit early
if len(rules) == 0 {
// Since the user is expecting the state of a certain alert and
// it that is not present it might be noteworthy.
if cliAlertConfig.AlertName != nil {
check.ExitRaw(check.Unknown, "No such alert defined")
}
check.ExitRaw(noAlertsState, "No alerts defined")
}

// Set initial capacity to reduce memory allocations
var l int
for _, rl := range rules {
Expand Down Expand Up @@ -164,11 +192,33 @@ inactive = 0`,

func init() {
rootCmd.AddCommand(alertCmd)

fs := alertCmd.Flags()

fs.StringVarP(&cliAlertConfig.NoAlertsState, "no-alerts-state", "T", "OK", "State to assign when no alerts are found (0, 1, 2, 3, OK, WARNING, CRITICAL, UNKNOWN). If not set this defaults to OK")

fs.StringSliceVarP(&cliAlertConfig.AlertName, "name", "n", nil,
"The name of one or more specific alerts to check."+
"\nThis parameter can be repeated e.G.: '--name alert1 --name alert2'"+
"\nIf no name is given, all alerts will be evaluated")

fs.BoolVarP(&cliAlertConfig.ProblemsOnly, "problems", "P", false,
"Display only alerts which status is not inactive/OK. Note that in combination with the --name flag this might result in no alerts being displayed")
}

// Function to convert state to integer.
func convertStateToInt(state string) (int, error) {
state = strings.ToUpper(state)
switch state {
case "OK", "0":
return check.OK, nil
case "WARNING", "1":
return check.Warning, nil
case "CRITICAL", "2":
return check.Critical, nil
case "UNKNOWN", "3":
return check.Unknown, nil
default:
return check.Unknown, errors.New("invalid state")
}
}
36 changes: 36 additions & 0 deletions cmd/alert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,42 @@ type AlertTest struct {

func TestAlertCmd(t *testing.T) {
tests := []AlertTest{
{
name: "alert-none",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"success","data":{"groups":[]}}`))
})),
args: []string{"run", "../main.go", "alert"},
expected: "[OK] - No alerts defined\n",
},
{
name: "alert-none-with-problems",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"success","data":{"groups":[]}}`))
})),
args: []string{"run", "../main.go", "alert", "--problems"},
expected: "[OK] - No alerts defined\n",
},
{
name: "alert-none-with-no-state",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"success","data":{"groups":[]}}`))
})),
args: []string{"run", "../main.go", "alert", "--no-alerts-state", "3"},
expected: "[UNKNOWN] - No alerts defined\nexit status 3\n",
},
{
name: "alert-none-with-name",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"success","data":{"groups":[]}}`))
})),
args: []string{"run", "../main.go", "alert", "--name", "MyPreciousAlert"},
expected: "[UNKNOWN] - No such alert defined\nexit status 3\n",
},
{
name: "alert-default",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down
11 changes: 1 addition & 10 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ import (
"github.com/prometheus/common/config"
)

type AlertConfig struct {
AlertName []string
Group []string
ProblemsOnly bool
}

type Config struct {
BasicAuth string `env:"CHECK_PROMETHEUS_BASICAUTH"`
Bearer string `env:"CHECK_PROMETHEUS_BEARER"`
Expand Down Expand Up @@ -57,10 +51,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see https://www.gnu.org/licenses/.
`

var (
cliConfig Config
cliAlertConfig AlertConfig
)
var cliConfig Config

func (c *Config) NewClient() *client.Client {
u := url.URL{
Expand Down

0 comments on commit 67fb855

Please sign in to comment.