Add v1/stats/tactical_overview

master
René Jochum 4 years ago
parent 2d65aa7ec7
commit 511cdb5f00

@ -1,22 +0,0 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
func init() {
runCmd.Flags().StringP("htpasswd", "p", "/opt/sites/$SITE/etc/htpasswd", "htpasswd file")
rootCmd.AddCommand(runCmd)
}
var runCmd = &cobra.Command{
Use: "run [site]",
Short: "Run the Proxy",
Long: `Run the Check_MK LQL API Proxy`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Check_MK LQL API Proxy v0.1 -- HEAD")
},
}

@ -1,11 +1,15 @@
#!/bin/bash
ARGS=$2
# Configuration
SERVER="http://localhost:8080"
if [ -n "$1" ]; then
SERVER=$1
fi
ARGS=$2
# Execute
set -ex
# GET Hosts
@ -15,4 +19,7 @@ curl $2 -X POST -d '{"method": "GET", "table": "hosts", "columns": ["name", "add
curl $2 -X POST -d '{"method": "GET", "table": "hosts", "columns": ["name", "address", "groups"], "limit": 3}' $SERVER/v1/raw
# host stats from the tactical_overview widget
curl $2 -X POST -d '{"method": "GET", "table": "hosts", "query": [["Stats", "state >= 0"], ["Stats", "state > 0"], ["Stats", "scheduled_downtime_depth = 0"], ["StatsAnd", "2"], ["Stats", "state > 0"], ["Stats", "scheduled_downtime_depth = 0"], ["Stats", "acknowledged = 0"], ["StatsAnd", "3"], ["Stats", "host_staleness >= 1.5"], ["Stats", "host_scheduled_downtime_depth = 0"], ["StatsAnd", "2"]]}' $SERVER/v1/raw
curl $2 -X POST -d '{"method": "GET", "table": "hosts", "query": [["Stats", "state >= 0"], ["Stats", "state > 0"], ["Stats", "scheduled_downtime_depth = 0"], ["StatsAnd", "2"], ["Stats", "state > 0"], ["Stats", "scheduled_downtime_depth = 0"], ["Stats", "acknowledged = 0"], ["StatsAnd", "3"], ["Stats", "host_staleness >= 1.5"], ["Stats", "host_scheduled_downtime_depth = 0"], ["StatsAnd", "2"]]}' $SERVER/v1/raw
# Tactical overview data :)
curl $2 $SERVER/v1/stats/tactical_overview

@ -35,9 +35,11 @@ func NewServer(client *Client, logger *log.Logger, htpasswdPath string) (*Server
// the API that will be served with
// the specification.
infos := &openapi.Info{
Title: "LQL API",
Description: `This is the LQL API for your check_mk Server.`,
Version: "unset",
Title: "LQL API",
Description: `This is the LQL API for your check_mk Server.
All v1/ endpoints require http basic auth`,
Version: "unset",
}
// Create a new route that serve the OpenAPI spec.
fizz.GET("/openapi.json", nil, fizz.OpenAPI(infos, "json"))
@ -48,6 +50,11 @@ func NewServer(client *Client, logger *log.Logger, htpasswdPath string) (*Server
htpasswd := auth.HtpasswdFileProvider(htpasswdPath)
authenticator := auth.NewBasicAuthenticator("LQL API", htpasswd)
v1Group.Use(basicAuthMiddleware(authenticator))
} else {
// Inject empty user if not .htpasswd have been given
v1Group.Use(func(c *gin.Context) {
c.Set("user", "")
})
}
v1Routes(v1Group)

@ -6,22 +6,13 @@ import (
)
func v1Routes(grp *fizz.RouterGroup) {
// // Add a new fruit to the market.
// grp.POST("", []fizz.OperationOption{
// fizz.Summary("Add a fruit to the market"),
// fizz.Response("400", "Bad request", nil, nil),
// }, tonic.Handler(CreateFruit, 200))
// // Remove a fruit from the market,
// // probably because it rotted.
// grp.DELETE("/:name", []fizz.OperationOption{
// fizz.Summary("Remove a fruit from the market"),
// fizz.Response("400", "Fruit not found", nil, nil),
// }, tonic.Handler(DeleteFruit, 204))
// // List all available fruits.
grp.POST("/raw", []fizz.OperationOption{
fizz.Summary("GET RAW LQL Data or execute a COMMAND"),
fizz.Response("400", "Bad request", nil, nil),
}, tonic.Handler(v1RawPost, 200))
grp.GET("/stats/tactical_overview", []fizz.OperationOption{
fizz.Summary("GET tactical overview data"),
fizz.Response("400", "Bad request", nil, nil),
}, tonic.Handler(v1StatsGetTacticalOverview, 200))
}

@ -30,6 +30,7 @@ func v1RawPost(c *gin.Context, params *V1RawRequestParams) ([]gin.H, error) {
if err != nil {
return nil, err
}
user := c.GetString("user")
// Param validation and request building
request := []string{}
@ -63,5 +64,5 @@ func v1RawPost(c *gin.Context, params *V1RawRequestParams) ([]gin.H, error) {
return nil, fmt.Errorf("Unknown Method requested: '%s'", params.Method)
}
return client.Request(c, strings.Join(request, "\n"), "", params.Limit)
return client.Request(c, strings.Join(request, "\n"), user, params.Limit)
}

@ -0,0 +1,120 @@
package lql
import (
"errors"
"github.com/gin-gonic/gin"
)
type V1StatsTacticalOverview struct {
Host *V1StatsTacticalOverviewEntry `json:"host" validate:"required" description:"Host stats"`
Services *V1StatsTacticalOverviewEntry `json:"services" validate:"required" description:"Service stats"`
Events *V1StatsTacticalOverviewEntry `json:"events" validate:"required" description:"Event stats"`
}
type V1StatsTacticalOverviewEntry struct {
All float64 `json:"all" validate:"required" description:"all services/hosts"`
Problems float64 `json:"problems" validate:"require" description:"Num of problems"`
Unhandled float64 `json:"unhandled" validate:"require" description:"Num of unhandled"`
Stale float64 `json:"stale" validate:"require" description:"Num of stale"`
}
func v1StatsGetTacticalOverview(c *gin.Context) (*V1StatsTacticalOverview, error) {
client, err := GinGetLqlClient(c)
if err != nil {
return nil, err
}
user := c.GetString("user")
msg := `GET hosts
Stats: state >= 0
Stats: state > 0
Stats: scheduled_downtime_depth = 0
StatsAnd: 2
Stats: state > 0
Stats: scheduled_downtime_depth = 0
Stats: acknowledged = 0
StatsAnd: 3
Stats: host_staleness >= 1.5
Stats: host_scheduled_downtime_depth = 0
StatsAnd: 2`
rsp, err := client.Request(c, msg, user, 0)
if err != nil {
return nil, err
}
if len(rsp) < 1 {
return nil, errors.New("Received invalid host stats from socket")
}
host := &V1StatsTacticalOverviewEntry{}
host.All = rsp[0]["stats_1"].(float64)
host.Problems = rsp[0]["stats_2"].(float64)
host.Unhandled = rsp[0]["stats_3"].(float64)
host.Stale = rsp[0]["stats_4"].(float64)
msg = `GET services
Stats: state >= 0
Stats: state > 0
Stats: scheduled_downtime_depth = 0
Stats: host_scheduled_downtime_depth = 0
Stats: host_state = 0
StatsAnd: 4
Stats: state > 0
Stats: scheduled_downtime_depth = 0
Stats: host_scheduled_downtime_depth = 0
Stats: acknowledged = 0
Stats: host_state = 0
StatsAnd: 5
Stats: service_staleness >= 1.5
Stats: host_scheduled_downtime_depth = 0
Stats: service_scheduled_downtime_depth = 0
StatsAnd: 3`
rsp, err = client.Request(c, msg, user, 0)
if err != nil {
return nil, err
}
if len(rsp) < 1 {
return nil, errors.New("Received invalid host stats from socket")
}
svc := &V1StatsTacticalOverviewEntry{}
svc.All = rsp[0]["stats_1"].(float64)
svc.Problems = rsp[0]["stats_2"].(float64)
svc.Unhandled = rsp[0]["stats_3"].(float64)
svc.Stale = rsp[0]["stats_4"].(float64)
msg = `GET eventconsoleevents
Stats: event_phase = open
Stats: event_phase = ack
StatsOr: 2
Stats: event_phase = open
Stats: event_phase = ack
StatsOr: 2
Stats: event_state != 0
StatsAnd: 2
Stats: event_phase = open
Stats: event_state != 0
Stats: event_host_in_downtime != 1
StatsAnd: 3`
rsp, err = client.Request(c, msg, user, 0)
if err != nil {
return nil, err
}
if len(rsp) < 1 {
return nil, errors.New("Received invalid host stats from socket")
}
ev := &V1StatsTacticalOverviewEntry{}
ev.All = rsp[0]["stats_1"].(float64)
ev.Problems = rsp[0]["stats_2"].(float64)
ev.Unhandled = rsp[0]["stats_3"].(float64)
ev.Stale = 0
return &V1StatsTacticalOverview{Host: host, Services: svc, Events: ev}, nil
}
Loading…
Cancel
Save