Merge branch 'master' into shiyang-locales
This commit is contained in:
commit
22c66b01df
21
api/init.go
21
api/init.go
|
@ -43,6 +43,27 @@ func Init(cfg *config.AppConfig) {
|
||||||
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/_aliases", alerting.GetAliases)
|
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/_aliases", alerting.GetAliases)
|
||||||
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/_mappings", alerting.GetMappings)
|
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/_mappings", alerting.GetMappings)
|
||||||
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/_plugins", alerting.GetPlugins)
|
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/_plugins", alerting.GetPlugins)
|
||||||
|
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.GetMonitor)
|
||||||
|
ui.HandleUIMethod(api.PUT, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.UpdateMonitor)
|
||||||
|
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/monitors", alerting.GetMonitors)
|
||||||
|
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/monitors", alerting.CreateMonitor)
|
||||||
|
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/monitors/_execute", alerting.ExecuteMonitor)
|
||||||
|
ui.HandleUIMethod(api.DELETE, "/elasticsearch/:id/alerting/monitors/:monitorID", alerting.DeleteMonitor)
|
||||||
|
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/_settings", alerting.GetSettings)
|
||||||
|
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/destinations", alerting.GetDestinations)
|
||||||
|
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/destinations", alerting.CreateDestination)
|
||||||
|
ui.HandleUIMethod(api.PUT, "/elasticsearch/:id/alerting/destinations/:destinationId", alerting.UpdateDestination)
|
||||||
|
ui.HandleUIMethod(api.DELETE, "/elasticsearch/:id/alerting/destinations/:destinationId", alerting.DeleteDestination)
|
||||||
|
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/destinations/email_accounts", alerting.CreateEmailAccount)
|
||||||
|
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/destinations/email_accounts", alerting.GetEmailAccounts)
|
||||||
|
ui.HandleUIMethod(api.DELETE, "/elasticsearch/:id/alerting/email_accounts/:emailAccountId", alerting.DeleteEmailAccount)
|
||||||
|
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/email_accounts/:emailAccountId", alerting.GetEmailAccount)
|
||||||
|
ui.HandleUIMethod(api.PUT, "/elasticsearch/:id/alerting/email_accounts/:emailAccountId", alerting.UpdateEmailAccount)
|
||||||
|
ui.HandleUIMethod(api.POST, "/elasticsearch/:id/alerting/destinations/email_groups", alerting.CreateEmailGroup)
|
||||||
|
ui.HandleUIMethod(api.GET, "/elasticsearch/:id/alerting/destinations/email_groups", alerting.GetEmailGroups)
|
||||||
|
ui.HandleUIMethod(api.DELETE, "/elasticsearch/:id/alerting/email_groups/:emailGroupId", alerting.DeleteEmailGroup)
|
||||||
|
ui.HandleUIMethod(api.PUT, "/elasticsearch/:id/alerting/email_groups/:emailGroupId", alerting.UpdateEmailGroup)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
task.RegisterScheduleTask(task.ScheduleTask{
|
task.RegisterScheduleTask(task.ScheduleTask{
|
||||||
|
|
|
@ -34,7 +34,7 @@ func GetAlerts (w http.ResponseWriter, req *http.Request, ps httprouter.Params){
|
||||||
var (
|
var (
|
||||||
from = getQueryParam(req, "from", "0")
|
from = getQueryParam(req, "from", "0")
|
||||||
size = getQueryParam(req, "size", "20")
|
size = getQueryParam(req, "size", "20")
|
||||||
search = getQueryParam(req, "search")
|
search = getQueryParam(req, "search", "")
|
||||||
sortDirection = getQueryParam(req, "sortDirection", "desc")
|
sortDirection = getQueryParam(req, "sortDirection", "desc")
|
||||||
sortField = getQueryParam(req, "sortField", "start_time")
|
sortField = getQueryParam(req, "sortField", "start_time")
|
||||||
severityLevel = getQueryParam(req, "severityLevel", "ALL")
|
severityLevel = getQueryParam(req, "severityLevel", "ALL")
|
||||||
|
@ -74,57 +74,65 @@ func GetAlerts (w http.ResponseWriter, req *http.Request, ps httprouter.Params){
|
||||||
clearSearch = strings.Join(searches, "* *")
|
clearSearch = strings.Join(searches, "* *")
|
||||||
params["searchString"] = fmt.Sprintf("*%s*", clearSearch)
|
params["searchString"] = fmt.Sprintf("*%s*", clearSearch)
|
||||||
}
|
}
|
||||||
reqUrl := conf.Endpoint + "/_opendistro/_alerting/monitors/alerts"
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/monitors/alerts", conf.Endpoint, API_PREFIX )
|
||||||
|
|
||||||
res, err := doRequest(reqUrl, http.MethodGet, params, nil)
|
res, err := doRequest(reqUrl, http.MethodGet, params, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var alertRes = AlertResponse{}
|
var alertRes = IfaceMap{}
|
||||||
err = decodeJSON(res.Body, &alertRes)
|
err = decodeJSON(res.Body, &alertRes)
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
alerts := []IfaceMap{}
|
||||||
|
rawAlerts := queryValue(alertRes, "alerts", nil)
|
||||||
|
if ds, ok := rawAlerts.([]interface{}); ok {
|
||||||
|
for _, alert := range ds {
|
||||||
|
if alertItem, ok := alert.(map[string]interface{}); ok {
|
||||||
|
|
||||||
var alerts = []IfaceMap{}
|
alertItem["version"] = queryValue(alertItem, "alert_version", "")
|
||||||
for _, hit := range alertRes.Alerts {
|
alertItem["id"] = queryValue(alertItem, "alert_id", "")
|
||||||
alert := IfaceMap{
|
alerts = append(alerts, alertItem)
|
||||||
"id": hit["alert_id"],
|
}
|
||||||
}
|
}
|
||||||
for k, v := range hit {
|
|
||||||
alert[k] = v
|
|
||||||
}
|
|
||||||
alert["version"] = hit["alert_version"]
|
|
||||||
}
|
}
|
||||||
writeJSON(w, IfaceMap{
|
writeJSON(w, IfaceMap{
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"alerts": alerts,
|
"alerts": alerts,
|
||||||
"totalAlerts": alertRes.TotalAlerts,
|
"totalAlerts": queryValue(alertRes, "totalAlerts", 0),
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
|
|
||||||
}
|
}
|
||||||
func writeError(w http.ResponseWriter, err error) {
|
func writeError(w http.ResponseWriter, err error) {
|
||||||
writeJSON(w, map[string]interface{}{
|
writeJSON(w, map[string]interface{}{
|
||||||
"body": map[string]interface{}{
|
"ok": false,
|
||||||
"ok": false,
|
"resp": err.Error(),
|
||||||
"err": err.Error(),
|
|
||||||
},
|
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
type IfaceMap map[string]interface{}
|
type IfaceMap map[string]interface{}
|
||||||
|
|
||||||
type AlertResponse struct {
|
|
||||||
Alerts []IfaceMap `json:"alerts"`
|
|
||||||
TotalAlerts int `json:"totalAlerts"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeJSON(reader io.Reader, obj interface{}) error{
|
func decodeJSON(reader io.Reader, obj interface{}) error{
|
||||||
dec := json.NewDecoder(reader)
|
dec := json.NewDecoder(reader)
|
||||||
return dec.Decode(obj)
|
err := dec.Decode(obj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m, ok := obj.(*IfaceMap); ok {
|
||||||
|
if errStr := queryValue(*m,"error", nil); errStr != nil {
|
||||||
|
if str, ok := errStr.(string); ok {
|
||||||
|
errors.New(str)
|
||||||
|
}
|
||||||
|
buf, _ := json.Marshal(errStr)
|
||||||
|
return errors.New(string(buf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeJSON(w http.ResponseWriter, data interface{}, statusCode int){
|
func writeJSON(w http.ResponseWriter, data interface{}, statusCode int){
|
||||||
|
@ -168,5 +176,36 @@ func doRequest(requestUrl string, method string, params map[string]string, body
|
||||||
}
|
}
|
||||||
req, _ = http.NewRequest(method, requestUrl, reader)
|
req, _ = http.NewRequest(method, requestUrl, reader)
|
||||||
req.Header.Set("content-type", "application/json")
|
req.Header.Set("content-type", "application/json")
|
||||||
|
req.Header.Set("User-Agent", "Kibana")
|
||||||
return alertClient.Do(req)
|
return alertClient.Do(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryValue(obj map[string]interface{}, key string, defaultValue interface{}) interface{} {
|
||||||
|
if key == "" {
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
idx := strings.Index(key, ".")
|
||||||
|
if idx == -1 {
|
||||||
|
if v, ok := obj[key]; ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
ckey := key[0:idx]
|
||||||
|
|
||||||
|
if v, ok := obj[ckey]; ok {
|
||||||
|
if vmap, ok := v.(map[string]interface{}); ok {
|
||||||
|
return queryValue(vmap, key[idx+1:], defaultValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func assignTo(dst IfaceMap, src IfaceMap){
|
||||||
|
if dst == nil || src == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for k, v := range src {
|
||||||
|
dst[k] = v
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package alerting
|
||||||
|
|
||||||
|
const INFINI_PREFIX = "opendistro"
|
||||||
|
|
||||||
|
const PLUGIN_NAME = INFINI_PREFIX + "-alerting"
|
||||||
|
const INDEX_PREFIX = INFINI_PREFIX +"-alerting"
|
||||||
|
|
||||||
|
const INDEX_ALL_ALERTS = "."+INDEX_PREFIX +`-alert*`
|
||||||
|
|
||||||
|
const API_PREFIX = "_opendistro"
|
|
@ -0,0 +1,720 @@
|
||||||
|
package alerting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
httprouter "infini.sh/framework/core/api/router"
|
||||||
|
"infini.sh/framework/core/elastic"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetDestination(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dstID := ps.ByName("destID")
|
||||||
|
reqUrl := fmt.Sprintf("%s/_opendistro/_alerting/monitors/%s", conf.Endpoint, dstID)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodGet, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res.Body.Close()
|
||||||
|
|
||||||
|
if _, ok := resBody["monitor"]; !ok {
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": false,
|
||||||
|
}, http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
queryDSL := ` {
|
||||||
|
"size": 0,
|
||||||
|
"query"": {
|
||||||
|
"bool": {
|
||||||
|
"must": {
|
||||||
|
"term"": {
|
||||||
|
"monitor_id": "%s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"aggs": {
|
||||||
|
"active_count": {
|
||||||
|
"terms": {
|
||||||
|
"field": "state",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"24_hour_count": {
|
||||||
|
"date_range": {
|
||||||
|
"field": "start_time",
|
||||||
|
"ranges": [{ "from": "now-24h/h" }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
queryDSL = fmt.Sprintf(queryDSL, id)
|
||||||
|
reqUrl = fmt.Sprintf("%s/_opendistro/_alerting/monitors/_search", conf.Endpoint)
|
||||||
|
res, err = doRequest(reqUrl, http.MethodPost, map[string]string{
|
||||||
|
"index": ".opendistro-alerting-alert*",
|
||||||
|
}, queryDSL)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var searchResBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &searchResBody)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dayCount := queryValue(searchResBody, "aggregations.24_hour_count.buckets.0.doc_count", 0)
|
||||||
|
activeBuckets := queryValue(searchResBody, "aggregations.active_count.buckets",[]interface{}{})
|
||||||
|
activeCount := 0
|
||||||
|
if ab, ok := activeBuckets.([]IfaceMap); ok {
|
||||||
|
for _, curr := range ab {
|
||||||
|
if curr["key"].(string) == "ACTIVE" {
|
||||||
|
activeCount = int(curr["doc_count"].(float64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"resp": resBody["monitor"],
|
||||||
|
"activeCount": activeCount,
|
||||||
|
"dayCount": dayCount,
|
||||||
|
"version": queryValue(resBody, "_version", nil),
|
||||||
|
"ifSeqNo": queryValue(resBody, "_seq_no", nil),
|
||||||
|
"ifPrimaryTerm": queryValue(resBody, "_primary_term", nil),
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDestinations(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
from = getQueryParam(req, "from", "0")
|
||||||
|
size = getQueryParam(req, "size", "20")
|
||||||
|
search = getQueryParam(req, "search", "")
|
||||||
|
sortDirection = getQueryParam(req, "sortDirection", "desc")
|
||||||
|
sortField = getQueryParam(req, "sortField", "start_time")
|
||||||
|
typ = getQueryParam(req, "type", "ALL")
|
||||||
|
)
|
||||||
|
|
||||||
|
var params = map[string]string{}
|
||||||
|
switch (sortField) {
|
||||||
|
case "name":
|
||||||
|
params = map[string]string{
|
||||||
|
"sortString": "destination.name.keyword",
|
||||||
|
"sortOrder": sortDirection,
|
||||||
|
}
|
||||||
|
case "type":
|
||||||
|
params = map[string]string{
|
||||||
|
"sortString": "destination.type",
|
||||||
|
"sortOrder": sortDirection,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
params["startIndex"] = from
|
||||||
|
params["size"] = size
|
||||||
|
params["searchString"] = search
|
||||||
|
params["destinationType"] = typ
|
||||||
|
if clearSearch := strings.TrimSpace(search); clearSearch != "" {
|
||||||
|
clearSearch = strings.ReplaceAll(clearSearch, " ", "* *")
|
||||||
|
params["searchString"] = clearSearch
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations", conf.Endpoint, API_PREFIX)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodGet, params, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rawDests := queryValue(resBody, "destinations", []interface{}{})
|
||||||
|
dests := []IfaceMap{}
|
||||||
|
|
||||||
|
if ds, ok := rawDests.([]interface{}); ok {
|
||||||
|
for _, dest := range ds {
|
||||||
|
if destination, ok := dest.(map[string]interface{}); ok {
|
||||||
|
|
||||||
|
destination["version"] = queryValue(destination, "schema_version", "")
|
||||||
|
destination["ifSeqNo"] = queryValue(destination, "seq_no", 0)
|
||||||
|
destination["ifPrimaryTerm"] = queryValue(destination, "primary_term", 0)
|
||||||
|
dests = append(dests, destination)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"destinations": dests,
|
||||||
|
"totalDestinations": queryValue(resBody, "totalDestinations", 0),
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateDestination(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations", conf.Endpoint, API_PREFIX)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPost, map[string]string{
|
||||||
|
"refresh": "wait_for",
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"resp": resBody,
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateDestination(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
destinationId := ps.ByName("destinationId")
|
||||||
|
var (
|
||||||
|
ifSeqNo = getQueryParam(req, "ifSeqNo")
|
||||||
|
ifPrimaryTerm = getQueryParam(req, "ifPrimaryTerm")
|
||||||
|
)
|
||||||
|
//PUT /_opendistro/_alerting/destinations/2g3CsHsB3EDgQAwRGzgS?if_seq_no=15&if_primary_term=2&refresh=wait_for
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/%s", conf.Endpoint, API_PREFIX, destinationId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPut, map[string]string{
|
||||||
|
"refresh": "wait_for",
|
||||||
|
"if_seq_no": ifSeqNo,
|
||||||
|
"if_primary_term": ifPrimaryTerm,
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"version": queryValue(resBody, "_version", ""),
|
||||||
|
"id": queryValue(resBody, "_id", ""),
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteDestination(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
destinationId := ps.ByName("destinationId")
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/%s", conf.Endpoint, API_PREFIX, destinationId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodDelete, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
resultIfce := queryValue(resBody, "result", "")
|
||||||
|
var isOk = false
|
||||||
|
if result, ok := resultIfce.(string); ok && result == "deleted" {
|
||||||
|
isOk = true
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": isOk,
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateEmailAccount(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_accounts", conf.Endpoint, API_PREFIX)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPost, map[string]string{
|
||||||
|
"refresh": "wait_for",
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"resp": resBody,
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateEmailAccount(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emailAccountId := ps.ByName("emailAccountId")
|
||||||
|
var (
|
||||||
|
ifSeqNo = getQueryParam(req, "ifSeqNo")
|
||||||
|
ifPrimaryTerm = getQueryParam(req, "ifPrimaryTerm")
|
||||||
|
)
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_accounts/%s", conf.Endpoint, API_PREFIX, emailAccountId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPut, map[string]string{
|
||||||
|
"refresh": "wait_for",
|
||||||
|
"if_seq_no": ifSeqNo,
|
||||||
|
"if_primary_term": ifPrimaryTerm,
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"id": queryValue(resBody, "_id", ""),
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteEmailAccount(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emailAccountId := ps.ByName("emailAccountId")
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_accounts/%s", conf.Endpoint, API_PREFIX, emailAccountId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodDelete, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
resultIfce := queryValue(resBody, "result", "")
|
||||||
|
var isOk = false
|
||||||
|
if result, ok := resultIfce.(string); ok && result == "deleted" {
|
||||||
|
isOk = true
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": isOk,
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEmailAccounts(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
from = getQueryParam(req, "from", "0")
|
||||||
|
size = getQueryParam(req, "size", "20")
|
||||||
|
search = getQueryParam(req, "search", "")
|
||||||
|
sortDirection = getQueryParam(req, "sortDirection", "desc")
|
||||||
|
sortField = getQueryParam(req, "sortField", "name")
|
||||||
|
)
|
||||||
|
|
||||||
|
must := IfaceMap{
|
||||||
|
"match_all": IfaceMap{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if clearSearch := strings.TrimSpace(search); clearSearch != "" {
|
||||||
|
clearSearch = strings.ReplaceAll(clearSearch, " ", "* *")
|
||||||
|
must = IfaceMap{
|
||||||
|
"query_string": IfaceMap{
|
||||||
|
"default_field": "email_account.name",
|
||||||
|
"default_operator": "AND",
|
||||||
|
"query": fmt.Sprintf(`*%s*`, clearSearch),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortQueryMap := IfaceMap{ "name": IfaceMap{ "email_account.name.keyword": sortDirection } }
|
||||||
|
var sort interface{}
|
||||||
|
if sortQuery, ok := sortQueryMap[sortField]; ok {
|
||||||
|
sort = sortQuery
|
||||||
|
}
|
||||||
|
reqBody := IfaceMap{
|
||||||
|
"from": from,
|
||||||
|
"size": size,
|
||||||
|
"sort": sort,
|
||||||
|
"query": IfaceMap{
|
||||||
|
"bool": IfaceMap{
|
||||||
|
"must": must,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_accounts/_search", conf.Endpoint, API_PREFIX)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPost, nil, reqBody)
|
||||||
|
//TODO to handle api error in doRequest function
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
totalEmailAccounts := queryValue(resBody, "hits.total.value", 0)
|
||||||
|
rawHits := queryValue(resBody, "hits.hits", []interface{}{})
|
||||||
|
emailAccounts := []IfaceMap{}
|
||||||
|
|
||||||
|
if rh, ok := rawHits.([]interface{}); ok {
|
||||||
|
for _, hit := range rh {
|
||||||
|
if emailAccount, ok := hit.(map[string]interface{}); ok {
|
||||||
|
newItem := IfaceMap{}
|
||||||
|
newItem["id"] = queryValue(emailAccount, "_id", "")
|
||||||
|
source := queryValue(emailAccount, "_source", nil)
|
||||||
|
if ms, ok := source.(map[string]interface{}); ok {
|
||||||
|
assignTo(newItem, ms)
|
||||||
|
}
|
||||||
|
newItem["ifSeqNo"] = queryValue(emailAccount, "_seq_no", 0)
|
||||||
|
newItem["ifPrimaryTerm"] = queryValue(emailAccount, "_primary_term", 0)
|
||||||
|
emailAccounts = append(emailAccounts, newItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"emailAccounts": emailAccounts,
|
||||||
|
"totalEmailAccounts": totalEmailAccounts,
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEmailAccount(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emailAccountId := ps.ByName("emailAccountId")
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_accounts/%s", conf.Endpoint, API_PREFIX, emailAccountId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodGet,nil, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"resp": queryValue(resBody, "email_account", nil),
|
||||||
|
"ifSeqNo": queryValue(resBody, "_seq_no", 0),
|
||||||
|
"ifPrimaryTerm": queryValue(resBody, "_primary_term", 0),
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --- email group
|
||||||
|
|
||||||
|
func CreateEmailGroup(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_groups", conf.Endpoint, API_PREFIX)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPost, map[string]string{
|
||||||
|
"refresh": "wait_for",
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"resp": resBody,
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateEmailGroup(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emailGroupId := ps.ByName("emailGroupId")
|
||||||
|
var (
|
||||||
|
ifSeqNo = getQueryParam(req, "ifSeqNo")
|
||||||
|
ifPrimaryTerm = getQueryParam(req, "ifPrimaryTerm")
|
||||||
|
)
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_groups/%s", conf.Endpoint, API_PREFIX, emailGroupId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPut, map[string]string{
|
||||||
|
"refresh": "wait_for",
|
||||||
|
"if_seq_no": ifSeqNo,
|
||||||
|
"if_primary_term": ifPrimaryTerm,
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"id": queryValue(resBody, "_id", ""),
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteEmailGroup(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emailGroupId := ps.ByName("emailGroupId")
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_groups/%s", conf.Endpoint, API_PREFIX, emailGroupId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodDelete, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
resultIfce := queryValue(resBody, "result", "")
|
||||||
|
var isOk = false
|
||||||
|
if result, ok := resultIfce.(string); ok && result == "deleted" {
|
||||||
|
isOk = true
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": isOk,
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEmailGroups(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
from = getQueryParam(req, "from", "0")
|
||||||
|
size = getQueryParam(req, "size", "20")
|
||||||
|
search = getQueryParam(req, "search", "")
|
||||||
|
sortDirection = getQueryParam(req, "sortDirection", "desc")
|
||||||
|
sortField = getQueryParam(req, "sortField", "name")
|
||||||
|
)
|
||||||
|
|
||||||
|
must := IfaceMap{
|
||||||
|
"match_all": IfaceMap{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if clearSearch := strings.TrimSpace(search); clearSearch != "" {
|
||||||
|
clearSearch = strings.ReplaceAll(clearSearch, " ", "* *")
|
||||||
|
must = IfaceMap{
|
||||||
|
"query_string": IfaceMap{
|
||||||
|
"default_field": "email_group.name",
|
||||||
|
"default_operator": "AND",
|
||||||
|
"query": fmt.Sprintf(`*%s*`, clearSearch),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortQueryMap := IfaceMap{ "name": IfaceMap{ "email_group.name.keyword": sortDirection } }
|
||||||
|
var sort interface{}
|
||||||
|
if sortQuery, ok := sortQueryMap[sortField]; ok {
|
||||||
|
sort = sortQuery
|
||||||
|
}
|
||||||
|
reqBody := IfaceMap{
|
||||||
|
"from": from,
|
||||||
|
"size": size,
|
||||||
|
"sort": sort,
|
||||||
|
"query": IfaceMap{
|
||||||
|
"bool": IfaceMap{
|
||||||
|
"must": must,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/destinations/email_groups/_search", conf.Endpoint, API_PREFIX)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPost, nil, reqBody)
|
||||||
|
//TODO to handle api error in doRequest function
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
totalEmailGroups := queryValue(resBody, "hits.total.value", 0)
|
||||||
|
rawHits := queryValue(resBody, "hits.hits", []interface{}{})
|
||||||
|
emailGroups := []IfaceMap{}
|
||||||
|
|
||||||
|
if rh, ok := rawHits.([]interface{}); ok {
|
||||||
|
for _, hit := range rh {
|
||||||
|
if emailGroup, ok := hit.(map[string]interface{}); ok {
|
||||||
|
newItem := IfaceMap{}
|
||||||
|
newItem["id"] = queryValue(emailGroup, "_id", "")
|
||||||
|
source := queryValue(emailGroup, "_source", nil)
|
||||||
|
if ms, ok := source.(map[string]interface{}); ok {
|
||||||
|
assignTo(newItem, ms)
|
||||||
|
}
|
||||||
|
newItem["ifSeqNo"] = queryValue(emailGroup, "seq_no", 0)
|
||||||
|
newItem["ifPrimaryTerm"] = queryValue(emailGroup, "primary_term", 0)
|
||||||
|
emailGroups = append(emailGroups, newItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"emailGroups": emailGroups,
|
||||||
|
"totalEmailGroups": totalEmailGroups,
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"infini.sh/framework/core/elastic"
|
"infini.sh/framework/core/elastic"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SearchBody struct {
|
type SearchBody struct {
|
||||||
|
@ -28,7 +29,7 @@ func Search(w http.ResponseWriter, req *http.Request, ps httprouter.Params){
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
reqUrl := conf.Endpoint +"/_opendistro/_alerting/monitors/_search"
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/monitors/_search", conf.Endpoint, API_PREFIX)
|
||||||
params := map[string]string{
|
params := map[string]string{
|
||||||
"index": body.Index,
|
"index": body.Index,
|
||||||
}
|
}
|
||||||
|
@ -47,10 +48,8 @@ func Search(w http.ResponseWriter, req *http.Request, ps httprouter.Params){
|
||||||
}
|
}
|
||||||
|
|
||||||
writeJSON(w, IfaceMap{
|
writeJSON(w, IfaceMap{
|
||||||
"body": IfaceMap{
|
"ok": true,
|
||||||
"ok": true,
|
"resp": resBody,
|
||||||
"resp": resBody,
|
|
||||||
},
|
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -90,10 +89,8 @@ func GetIndices(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeJSON(w, IfaceMap{
|
writeJSON(w, IfaceMap{
|
||||||
"body": IfaceMap{
|
"ok": true,
|
||||||
"ok": true,
|
"resp": resBody,
|
||||||
"resp": resBody,
|
|
||||||
},
|
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +134,8 @@ func GetAliases(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeJSON(w, IfaceMap{
|
writeJSON(w, IfaceMap{
|
||||||
"body": IfaceMap{
|
"ok": true,
|
||||||
"ok": true,
|
"resp": resBody,
|
||||||
"resp": resBody,
|
|
||||||
},
|
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,14 +148,14 @@ func GetMappings(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body = struct{
|
var body = struct{
|
||||||
Index string `json:"index"`
|
Index []string `json:"index"`
|
||||||
}{}
|
}{}
|
||||||
err := decodeJSON(req.Body, &body)
|
err := decodeJSON(req.Body, &body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
reqUrl := fmt.Sprintf("%s/%s/_mapping", conf.Endpoint, body.Index)
|
reqUrl := fmt.Sprintf("%s/%s/_mapping", conf.Endpoint, strings.Join(body.Index, ","))
|
||||||
res, err := doRequest(reqUrl, http.MethodGet, nil, nil)
|
res, err := doRequest(reqUrl, http.MethodGet, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
|
@ -175,10 +170,8 @@ func GetMappings(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeJSON(w, IfaceMap{
|
writeJSON(w, IfaceMap{
|
||||||
"body": IfaceMap{
|
"ok": true,
|
||||||
"ok": true,
|
"resp": resBody,
|
||||||
"resp": resBody,
|
|
||||||
},
|
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,9 +202,38 @@ func GetPlugins(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeJSON(w, IfaceMap{
|
writeJSON(w, IfaceMap{
|
||||||
"body": IfaceMap{
|
"ok": true,
|
||||||
"ok": true,
|
"resp": resBody,
|
||||||
"resp": resBody,
|
}, http.StatusOK)
|
||||||
},
|
}
|
||||||
|
|
||||||
|
func GetSettings(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// /_cluster/settings?include_defaults=true
|
||||||
|
reqUrl := fmt.Sprintf("%s/_cluster/settings", conf.Endpoint)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodGet, map[string]string{
|
||||||
|
"include_defaults": "true",
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"resp": resBody,
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
}
|
}
|
|
@ -6,10 +6,18 @@ import (
|
||||||
httprouter "infini.sh/framework/core/api/router"
|
httprouter "infini.sh/framework/core/api/router"
|
||||||
"infini.sh/framework/core/elastic"
|
"infini.sh/framework/core/elastic"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime/debug"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
func GetMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
debug.PrintStack()
|
||||||
|
}
|
||||||
|
}()
|
||||||
id := ps.ByName("id")
|
id := ps.ByName("id")
|
||||||
conf := elastic.GetConfig(id)
|
conf := elastic.GetConfig(id)
|
||||||
if conf == nil {
|
if conf == nil {
|
||||||
|
@ -19,7 +27,7 @@ func GetMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
|
|
||||||
mid := ps.ByName("monitorID")
|
mid := ps.ByName("monitorID")
|
||||||
// /_opendistro/_alerting/monitors/uiSjqXsBHT9Hsiy5Dq6g
|
// /_opendistro/_alerting/monitors/uiSjqXsBHT9Hsiy5Dq6g
|
||||||
reqUrl := fmt.Sprintf("%s/_opendistro/_alerting/monitors/%s", conf.Endpoint, mid)
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/monitors/%s", conf.Endpoint, API_PREFIX, mid)
|
||||||
res, err := doRequest(reqUrl, http.MethodGet, nil, nil)
|
res, err := doRequest(reqUrl, http.MethodGet, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
|
@ -35,29 +43,26 @@ func GetMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
|
|
||||||
if _, ok := resBody["monitor"]; !ok {
|
if _, ok := resBody["monitor"]; !ok {
|
||||||
writeJSON(w, IfaceMap{
|
writeJSON(w, IfaceMap{
|
||||||
"body": IfaceMap{
|
|
||||||
"ok": false,
|
"ok": false,
|
||||||
},
|
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
///_opendistro/_alerting/monitors/_search?index=.opendistro-alerting-alert*
|
|
||||||
|
|
||||||
queryDSL := ` {
|
queryDSL := ` {
|
||||||
"size": 0,
|
"size": 0,
|
||||||
"query"": {
|
"query": {
|
||||||
"bool": {
|
"bool": {
|
||||||
"must": {
|
"must": {
|
||||||
"term"": {
|
"term": {
|
||||||
"monitor_id": "%s",
|
"monitor_id": "%s"
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
"aggs": {
|
"aggs": {
|
||||||
"active_count": {
|
"active_count": {
|
||||||
"terms": {
|
"terms": {
|
||||||
"field": "state",
|
"field": "state"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"24_hour_count": {
|
"24_hour_count": {
|
||||||
|
@ -69,9 +74,9 @@ func GetMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
queryDSL = fmt.Sprintf(queryDSL, id)
|
queryDSL = fmt.Sprintf(queryDSL, id)
|
||||||
reqUrl = fmt.Sprintf("%s/_opendistro/_alerting/monitors/_search", conf.Endpoint)
|
reqUrl = fmt.Sprintf("%s/%s/_alerting/monitors/_search", conf.Endpoint, API_PREFIX)
|
||||||
res, err = doRequest(reqUrl, http.MethodPost, map[string]string{
|
res, err = doRequest(reqUrl, http.MethodPost, map[string]string{
|
||||||
"index": ".opendistro-alerting-alert*",
|
"index": INDEX_ALL_ALERTS,
|
||||||
}, queryDSL)
|
}, queryDSL)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -85,34 +90,400 @@ func GetMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params)
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//dayCount := queryValue(searchResBody, "aggregations.24_hour_count.buckets.0.doc_count", 0)
|
dayCount := queryValue(searchResBody, "aggregations.24_hour_count.buckets.0.doc_count", 0)
|
||||||
//activeBuckets := queryValue(searchResBody, "aggregations.active_count.buckets",[]interface{}{})
|
activeBuckets := queryValue(searchResBody, "aggregations.active_count.buckets",[]interface{}{})
|
||||||
|
activeCount := 0
|
||||||
|
if ab, ok := activeBuckets.([]IfaceMap); ok {
|
||||||
|
for _, curr := range ab {
|
||||||
|
if curr["key"].(string) == "ACTIVE" {
|
||||||
|
activeCount = int(curr["doc_count"].(float64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
writeJSON(w, IfaceMap{
|
writeJSON(w, IfaceMap{
|
||||||
"body": IfaceMap{
|
"ok": true,
|
||||||
"ok": true,
|
"resp": resBody["monitor"],
|
||||||
"resp": resBody,
|
"activeCount": activeCount,
|
||||||
},
|
"dayCount": dayCount,
|
||||||
|
"version": queryValue(resBody, "_version", nil),
|
||||||
|
"ifSeqNo": queryValue(resBody, "_seq_no", nil),
|
||||||
|
"ifPrimaryTerm": queryValue(resBody, "_primary_term", nil),
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func queryValue(obj map[string]interface{}, key string, defaultValue interface{}) interface{} {
|
func GetMonitors(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
if key == "" {
|
defer func() {
|
||||||
return obj
|
if err := recover(); err != nil {
|
||||||
}
|
debug.PrintStack()
|
||||||
idx := strings.Index(key, ".")
|
|
||||||
if idx == -1 {
|
|
||||||
if v, ok := obj[key]; ok {
|
|
||||||
return v
|
|
||||||
}
|
}
|
||||||
return defaultValue
|
}()
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
from = getQueryParam(req, "from")
|
||||||
|
size = getQueryParam(req, "size")
|
||||||
|
search = getQueryParam(req, "search")
|
||||||
|
sortDirection = getQueryParam(req, "sortDirection")
|
||||||
|
sortField = getQueryParam(req, "sortField")
|
||||||
|
state = getQueryParam(req, "state")
|
||||||
|
must = IfaceMap{ "match_all": IfaceMap{} }
|
||||||
|
)
|
||||||
|
if clearSearch := strings.TrimSpace(search); clearSearch != "" {
|
||||||
|
clearSearch = strings.ReplaceAll(clearSearch, " ", "* *")
|
||||||
|
must = IfaceMap{
|
||||||
|
"query_string": IfaceMap{
|
||||||
|
"default_field": "monitor.name",
|
||||||
|
"default_operator": "AND",
|
||||||
|
"query": fmt.Sprintf("*%s*", clearSearch),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var filter = []IfaceMap{
|
||||||
|
IfaceMap{ "term": IfaceMap{ "monitor.type": "monitor" }},
|
||||||
|
}
|
||||||
|
if state != "all" {
|
||||||
|
filter = append(filter, IfaceMap{
|
||||||
|
"term": IfaceMap{ "monitor.enabled": state == "enabled" },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var monitorSorts = IfaceMap{ "name": "monitor.name.keyword" }
|
||||||
|
sortPageData := IfaceMap{
|
||||||
|
"size": 1000,
|
||||||
|
"from": 0,
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
intSize int
|
||||||
|
intFrom int
|
||||||
|
)
|
||||||
|
if msort, ok := monitorSorts[sortField]; ok {
|
||||||
|
sortPageData["sort"] = []IfaceMap{
|
||||||
|
{ msort.(string): sortDirection },
|
||||||
|
}
|
||||||
|
intSize, _ = strconv.Atoi(size)
|
||||||
|
if intSize < 0 {
|
||||||
|
intSize = 1000
|
||||||
|
}
|
||||||
|
sortPageData["size"] = intSize
|
||||||
|
intFrom, _ = strconv.Atoi(from)
|
||||||
|
if intFrom < 0 {
|
||||||
|
intFrom = 0
|
||||||
|
}
|
||||||
|
sortPageData["from"] = intFrom
|
||||||
|
}
|
||||||
|
var params = IfaceMap{
|
||||||
|
"seq_no_primary_term": true,
|
||||||
|
"version": true,
|
||||||
|
"query": IfaceMap{
|
||||||
|
"bool": IfaceMap{
|
||||||
|
"filter": filter,
|
||||||
|
"must": must,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assignTo(params, sortPageData)
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/monitors/_search", conf.Endpoint, API_PREFIX )
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPost, nil, params)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ckey := key[0:idx]
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if v, ok := obj[ckey]; ok {
|
totalMonitors := queryValue(resBody, "hits.total.value", 0)
|
||||||
if vmap, ok := v.(map[string]interface{}); ok {
|
monitorMap:= map[string]IfaceMap{}
|
||||||
return queryValue(vmap, key[idx+1:], defaultValue)
|
var hits = queryValue(resBody, "hits.hits", []IfaceMap{})
|
||||||
|
monitorIDs := []interface{}{}
|
||||||
|
if hitsArr, ok := hits.([]interface{}); ok {
|
||||||
|
for _, hitIface := range hitsArr {
|
||||||
|
if hit, ok := hitIface.(map[string]interface{}); ok {
|
||||||
|
id := queryValue(hit, "_id", "")
|
||||||
|
monitorIDs = append(monitorIDs, id)
|
||||||
|
monitor := queryValue(hit, "_source", IfaceMap{}).(map[string]interface{})
|
||||||
|
monitorMap[id.(string)] = IfaceMap{
|
||||||
|
"id": id,
|
||||||
|
"version": queryValue(hit, "_version", ""),
|
||||||
|
"ifSeqNo": queryValue(hit, "_seq_no", false),
|
||||||
|
"ifPrimaryTerm": queryValue(hit, "_primary_term", false),
|
||||||
|
"name": queryValue(monitor, "name", ""),
|
||||||
|
"enabled": queryValue(monitor, "enabled", false),
|
||||||
|
"monitor": monitor,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
aggsOrderData := IfaceMap{}
|
||||||
|
aggsSorts := IfaceMap{
|
||||||
|
"active": "active",
|
||||||
|
"acknowledged": "acknowledged",
|
||||||
|
"errors": "errors",
|
||||||
|
"ignored": "ignored",
|
||||||
|
"lastNotificationTime": "last_notification_time",
|
||||||
|
}
|
||||||
|
|
||||||
|
if sortF, ok := aggsSorts[sortField]; ok {
|
||||||
|
aggsOrderData["order"] = IfaceMap{ sortF.(string): sortDirection }
|
||||||
|
}
|
||||||
|
var queryParams = map[string]string{
|
||||||
|
"index": INDEX_ALL_ALERTS,
|
||||||
|
}
|
||||||
|
var termsMap = IfaceMap{
|
||||||
|
"field": "monitor_id",
|
||||||
|
"size": intFrom + intSize,
|
||||||
|
}
|
||||||
|
assignTo(termsMap, aggsOrderData)
|
||||||
|
var aggsParams = IfaceMap{
|
||||||
|
"size": 0,
|
||||||
|
"query": IfaceMap{ "terms": IfaceMap{ "monitor_id": monitorIDs } },
|
||||||
|
"aggregations": IfaceMap{
|
||||||
|
"uniq_monitor_ids": IfaceMap{
|
||||||
|
"terms": termsMap,
|
||||||
|
"aggregations": IfaceMap{
|
||||||
|
"active": IfaceMap{ "filter": IfaceMap{ "term": IfaceMap{ "state": "ACTIVE" } } },
|
||||||
|
"acknowledged": IfaceMap{ "filter": IfaceMap{ "term": IfaceMap{ "state": "ACKNOWLEDGED" } } },
|
||||||
|
"errors": IfaceMap{ "filter": IfaceMap{ "term": IfaceMap{ "state": "ERROR" } } },
|
||||||
|
"ignored": IfaceMap{
|
||||||
|
"filter": IfaceMap{
|
||||||
|
"bool": IfaceMap{
|
||||||
|
"filter": IfaceMap{ "term": IfaceMap{ "state": "COMPLETED" } },
|
||||||
|
"must_not": IfaceMap{ "exists": IfaceMap{ "field": "acknowledged_time" } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"last_notification_time": IfaceMap{ "max": IfaceMap{ "field": "last_notification_time" } },
|
||||||
|
"latest_alert": IfaceMap{
|
||||||
|
"top_hits": IfaceMap{
|
||||||
|
"size": 1,
|
||||||
|
"sort": []IfaceMap{ { "start_time": IfaceMap{ "order": "desc" }} },
|
||||||
|
"_source": IfaceMap{
|
||||||
|
"includes": []string{"last_notification_time", "trigger_name"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
reqUrl = fmt.Sprintf("%s/%s/_alerting/monitors/_search", conf.Endpoint, API_PREFIX)
|
||||||
|
searchRes, err := doRequest(reqUrl, http.MethodPost, queryParams, aggsParams)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var searchResBody = IfaceMap{}
|
||||||
|
err = decodeJSON(searchRes.Body, &searchResBody)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buckets := queryValue(searchResBody, "aggregations.uniq_monitor_ids.buckets",[]IfaceMap{})
|
||||||
|
usedMonitors := []IfaceMap{}
|
||||||
|
if bks, ok := buckets.([]interface{}); ok {
|
||||||
|
for _, bk := range bks {
|
||||||
|
if bk, ok := bk.(map[string]interface{}); ok {
|
||||||
|
id := queryValue(bk, "key", "")
|
||||||
|
monitor := monitorMap[id.(string)]
|
||||||
|
monitor["lastNotificationTime"] = queryValue(bk, "last_notification_time.value", "")
|
||||||
|
monitor["ignored"] = queryValue(bk, "ignored.doc_count", 0)
|
||||||
|
alertHits := queryValue(bk, "latest_alert.hits.hits", nil)
|
||||||
|
var latestAlert interface{}
|
||||||
|
if hits, ok := alertHits.([]interface{}); ok && len(hits) > 0 {
|
||||||
|
if hitMap, ok := hits[0].(map[string]interface{}); ok {
|
||||||
|
latestAlert = queryValue(hitMap, "_source.trigger_name", nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
monitor["latestAlert"] = latestAlert
|
||||||
|
monitor["active"] = queryValue(bk, "active.doc_count", 0)
|
||||||
|
monitor["errors"] = queryValue(bk, "errors.doc_count", 0)
|
||||||
|
monitor["currentTime"] = time.Now().UnixNano() / 1e6
|
||||||
|
usedMonitors = append(usedMonitors, monitor)
|
||||||
|
delete(monitorMap, id.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unusedMonitors := []IfaceMap{}
|
||||||
|
|
||||||
|
for _, m := range monitorMap {
|
||||||
|
assignTo(m, IfaceMap{
|
||||||
|
"lastNotificationTime": nil,
|
||||||
|
"ignored": 0,
|
||||||
|
"active": 0,
|
||||||
|
"acknowledged": 0,
|
||||||
|
"errors": 0,
|
||||||
|
"latestAlert": "--",
|
||||||
|
"currentTime": time.Now().UnixNano()/1e6,
|
||||||
|
})
|
||||||
|
unusedMonitors = append(unusedMonitors,m)
|
||||||
|
}
|
||||||
|
|
||||||
|
results := append(usedMonitors, unusedMonitors...)
|
||||||
|
|
||||||
|
if _, ok := monitorSorts[sortField]; !ok {
|
||||||
|
results = results[intFrom: intFrom + intSize]
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"monitors": results,
|
||||||
|
"totalMonitors": totalMonitors,
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func CreateMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/monitors", conf.Endpoint, API_PREFIX)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPost, map[string]string{
|
||||||
|
"refresh": "wait_for",
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"resp": resBody,
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
monitorId := ps.ByName("monitorID")
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/monitors/%s", conf.Endpoint, API_PREFIX, monitorId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodDelete, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
resultIfce := queryValue(resBody, "result", "")
|
||||||
|
var isOk = false
|
||||||
|
if result, ok := resultIfce.(string); ok && result == "deleted" {
|
||||||
|
isOk = true
|
||||||
|
}
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": isOk,
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
monitorId := ps.ByName("monitorID")
|
||||||
|
var (
|
||||||
|
ifSeqNo = getQueryParam(req, "ifSeqNo")
|
||||||
|
ifPrimaryTerm = getQueryParam(req, "ifPrimaryTerm")
|
||||||
|
)
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/monitors/%s", conf.Endpoint, API_PREFIX, monitorId)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPut, map[string]string{
|
||||||
|
"refresh": "wait_for",
|
||||||
|
"if_seq_no": ifSeqNo,
|
||||||
|
"if_primary_term": ifPrimaryTerm,
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"version": queryValue(resBody, "_version", ""),
|
||||||
|
"id": queryValue(resBody, "_id", ""),
|
||||||
|
}, http.StatusOK)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteMonitor(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
id := ps.ByName("id")
|
||||||
|
conf := elastic.GetConfig(id)
|
||||||
|
if conf == nil {
|
||||||
|
writeError(w, errors.New("cluster not found"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
dryrun = getQueryParam(req, "dryrun", "true")
|
||||||
|
)
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/%s/_alerting/monitors/_execute", conf.Endpoint, API_PREFIX)
|
||||||
|
res, err := doRequest(reqUrl, http.MethodPost, map[string]string{
|
||||||
|
"dryrun": dryrun,
|
||||||
|
}, req.Body)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resBody = IfaceMap{}
|
||||||
|
err = decodeJSON(res.Body, &resBody)
|
||||||
|
res.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO error handle: check whether resBody has contains field error
|
||||||
|
|
||||||
|
writeJSON(w, IfaceMap{
|
||||||
|
"ok": true,
|
||||||
|
"resp": resBody,
|
||||||
|
}, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.2.0",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"use-query-params": "^1.2.3",
|
"use-query-params": "^1.2.3",
|
||||||
"uuidv4": "^6.2.12"
|
"uuid-v4": "^0.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"antd-pro-merge-less": "^0.1.0",
|
"antd-pro-merge-less": "^0.1.0",
|
||||||
|
|
|
@ -130,7 +130,7 @@ export async function getBreadcrumb(route, routeState, httpClient) {
|
||||||
// TODO::Everything else is considered as monitor, we should break this.
|
// TODO::Everything else is considered as monitor, we should break this.
|
||||||
let monitorName = base;
|
let monitorName = base;
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.get(`../api/alerting/monitors/${base}`);
|
const response = await httpClient.get(`/alerting/monitors/${base}`);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
monitorName = response.resp.name;
|
monitorName = response.resp.name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ const httpClient = new Fetch({
|
||||||
get: () => '',
|
get: () => '',
|
||||||
prepend: (url) => url,
|
prepend: (url) => url,
|
||||||
remove: (url) => url,
|
remove: (url) => url,
|
||||||
serverBasePath: '/elasticsearch',
|
serverBasePath: '',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const notifications = {
|
const notifications = {
|
||||||
|
@ -23,6 +23,11 @@ const notifications = {
|
||||||
description: text,
|
description: text,
|
||||||
duration: toastLifeTimeMs/1000,
|
duration: toastLifeTimeMs/1000,
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
addSuccess: (message) => {
|
||||||
|
notification.success({
|
||||||
|
description: message,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +37,8 @@ const AlertingUI = (props)=>{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
useMemo(()=>{
|
useMemo(()=>{
|
||||||
httpClient.getServerBasePath = ()=>{
|
httpClient.params.basePath.prepend = (url)=>{
|
||||||
return '/api/elasticsearch/'+ props.selectedCluster.id;
|
return '/elasticsearch/'+ props.selectedCluster.id + url;
|
||||||
}
|
}
|
||||||
}, [props.selectedCluster]);
|
}, [props.selectedCluster]);
|
||||||
const isDarkMode = false;
|
const isDarkMode = false;
|
||||||
|
|
|
@ -56,7 +56,7 @@ class AnomalyDetectorData extends React.Component {
|
||||||
preview: this.props.preview,
|
preview: this.props.preview,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.get(`../api/alerting/detectors/${detectorId}/results`, {
|
const response = await httpClient.get(`/alerting/detectors/${detectorId}/results`, {
|
||||||
query: requestParams,
|
query: requestParams,
|
||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ class AnomalyDetectors extends React.Component {
|
||||||
async searchDetectors() {
|
async searchDetectors() {
|
||||||
const { http: httpClient, notifications } = this.context;
|
const { http: httpClient, notifications } = this.context;
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.post('../api/alerting/detectors/_search');
|
const response = await httpClient.post('/alerting/detectors/_search');
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const detectorOptions = response.detectors
|
const detectorOptions = response.detectors
|
||||||
.filter((detector) => detector.detectionDateRange === undefined)
|
.filter((detector) => detector.detectionDateRange === undefined)
|
||||||
|
|
|
@ -77,7 +77,7 @@ export default class CreateMonitor extends Component {
|
||||||
async onCreate(monitor, { setSubmitting, setErrors }) {
|
async onCreate(monitor, { setSubmitting, setErrors }) {
|
||||||
const { httpClient, notifications } = this.props;
|
const { httpClient, notifications } = this.props;
|
||||||
try {
|
try {
|
||||||
const resp = await httpClient.post('../api/alerting/monitors', {
|
const resp = await httpClient.post('/alerting/monitors', {
|
||||||
body: JSON.stringify(monitor),
|
body: JSON.stringify(monitor),
|
||||||
});
|
});
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
|
|
|
@ -249,7 +249,7 @@ describe('CreateMonitor', () => {
|
||||||
);
|
);
|
||||||
wrapper.instance().onCreate(monitor, formikBag);
|
wrapper.instance().onCreate(monitor, formikBag);
|
||||||
expect(httpClientMock.post).toHaveBeenCalledTimes(1);
|
expect(httpClientMock.post).toHaveBeenCalledTimes(1);
|
||||||
expect(httpClientMock.post).toHaveBeenCalledWith('../api/alerting/monitors', {
|
expect(httpClientMock.post).toHaveBeenCalledWith('/alerting/monitors', {
|
||||||
body: JSON.stringify(monitor),
|
body: JSON.stringify(monitor),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -127,7 +127,7 @@ class DefineMonitor extends Component {
|
||||||
async getPlugins() {
|
async getPlugins() {
|
||||||
const { httpClient } = this.props;
|
const { httpClient } = this.props;
|
||||||
try {
|
try {
|
||||||
const pluginsResponse = await httpClient.get('../api/alerting/_plugins');
|
const pluginsResponse = await httpClient.get('/alerting/_plugins');
|
||||||
if (pluginsResponse.ok) {
|
if (pluginsResponse.ok) {
|
||||||
this.setState({ plugins: pluginsResponse.resp.map((plugin) => plugin.component) });
|
this.setState({ plugins: pluginsResponse.resp.map((plugin) => plugin.component) });
|
||||||
} else {
|
} else {
|
||||||
|
@ -187,7 +187,7 @@ class DefineMonitor extends Component {
|
||||||
_.set(monitor, 'name', 'TEMP_MONITOR');
|
_.set(monitor, 'name', 'TEMP_MONITOR');
|
||||||
_.set(monitor, 'triggers', []);
|
_.set(monitor, 'triggers', []);
|
||||||
_.set(monitor, 'inputs[0].search', searchRequest);
|
_.set(monitor, 'inputs[0].search', searchRequest);
|
||||||
return httpClient.post('../api/alerting/monitors/_execute', {
|
return httpClient.post('/alerting/monitors/_execute', {
|
||||||
body: JSON.stringify(monitor),
|
body: JSON.stringify(monitor),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -232,7 +232,7 @@ class DefineMonitor extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.props.httpClient.post('../api/alerting/_mappings', {
|
const response = await this.props.httpClient.post('/alerting/_mappings', {
|
||||||
body: JSON.stringify({ index }),
|
body: JSON.stringify({ index }),
|
||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
|
|
@ -121,7 +121,7 @@ class MonitorIndex extends React.Component {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const response = await this.props.httpClient.post('../api/alerting/_indices', {
|
const response = await this.props.httpClient.post('/alerting/_indices', {
|
||||||
body: JSON.stringify({ index }),
|
body: JSON.stringify({ index }),
|
||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
@ -151,7 +151,7 @@ class MonitorIndex extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.props.httpClient.post('../api/alerting/_aliases', {
|
const response = await this.props.httpClient.post('/alerting/_aliases', {
|
||||||
body: JSON.stringify({ alias }),
|
body: JSON.stringify({ alias }),
|
||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
|
|
@ -62,7 +62,7 @@ class ConfigureActions extends React.Component {
|
||||||
return destination.type;
|
return destination.type;
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.get('../api/alerting/destinations', {
|
const response = await httpClient.get('/alerting/destinations', {
|
||||||
query: { search: searchText, size: MAX_QUERY_RESULT_SIZE },
|
query: { search: searchText, size: MAX_QUERY_RESULT_SIZE },
|
||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
@ -97,7 +97,7 @@ class ConfigureActions extends React.Component {
|
||||||
const condition = { script: { lang: 'painless', source: 'return true' } };
|
const condition = { script: { lang: 'painless', source: 'return true' } };
|
||||||
const testMonitor = { ...monitor, triggers: [{ ...trigger, actions: [action], condition }] };
|
const testMonitor = { ...monitor, triggers: [{ ...trigger, actions: [action], condition }] };
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.post('../api/alerting/monitors/_execute', {
|
const response = await httpClient.post('/alerting/monitors/_execute', {
|
||||||
query: { dryrun: false },
|
query: { dryrun: false },
|
||||||
body: JSON.stringify(testMonitor),
|
body: JSON.stringify(testMonitor),
|
||||||
});
|
});
|
||||||
|
|
|
@ -128,7 +128,7 @@ export default class CreateTrigger extends Component {
|
||||||
_.set(monitorToExecute, 'inputs[0].search', searchRequest);
|
_.set(monitorToExecute, 'inputs[0].search', searchRequest);
|
||||||
}
|
}
|
||||||
httpClient
|
httpClient
|
||||||
.post('../api/alerting/monitors/_execute', { body: JSON.stringify(monitorToExecute) })
|
.post('/alerting/monitors/_execute', { body: JSON.stringify(monitorToExecute) })
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
this.setState({ executeResponse: resp.resp });
|
this.setState({ executeResponse: resp.resp });
|
||||||
|
|
|
@ -185,7 +185,7 @@ export default class Dashboard extends Component {
|
||||||
location.search;
|
location.search;
|
||||||
const { httpClient, history, notifications } = this.props;
|
const { httpClient, history, notifications } = this.props;
|
||||||
history.replace({ ...this.props.location, search: queryParamsString });
|
history.replace({ ...this.props.location, search: queryParamsString });
|
||||||
httpClient.get(httpClient.getServerBasePath()+'/alerting/alerts', { query: params }).then((resp) => {
|
httpClient.get('/alerting/alerts', { query: params }).then((resp) => {
|
||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
const { alerts, totalAlerts } = resp;
|
const { alerts, totalAlerts } = resp;
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -218,7 +218,7 @@ export default class Dashboard extends Component {
|
||||||
|
|
||||||
const promises = Object.entries(monitorAlerts).map(([monitorId, alerts]) =>
|
const promises = Object.entries(monitorAlerts).map(([monitorId, alerts]) =>
|
||||||
httpClient
|
httpClient
|
||||||
.post(`../api/alerting/monitors/${monitorId}/_acknowledge/alerts`, {
|
.post(`/alerting/monitors/${monitorId}/_acknowledge/alerts`, {
|
||||||
body: JSON.stringify({ alerts }),
|
body: JSON.stringify({ alerts }),
|
||||||
})
|
})
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
|
|
|
@ -52,7 +52,7 @@ export const columns = [
|
||||||
truncateText: true,
|
truncateText: true,
|
||||||
textOnly: true,
|
textOnly: true,
|
||||||
render: (name, alert) => (
|
render: (name, alert) => (
|
||||||
<EuiLink href={`${PLUGIN_NAME}#/monitors/${alert.monitor_id}`}>{name}</EuiLink>
|
<EuiLink href={`#/${PLUGIN_NAME}/monitors/${alert.monitor_id}`}>{name}</EuiLink>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,7 +89,7 @@ class CreateDestination extends React.Component {
|
||||||
getDestination = async (destinationId) => {
|
getDestination = async (destinationId) => {
|
||||||
const { httpClient, history, notifications } = this.props;
|
const { httpClient, history, notifications } = this.props;
|
||||||
try {
|
try {
|
||||||
const resp = await httpClient.get(`../api/alerting/destinations/${destinationId}`);
|
const resp = await httpClient.get(`/alerting/destinations/${destinationId}`);
|
||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
const ifSeqNo = _.get(resp, 'ifSeqNo');
|
const ifSeqNo = _.get(resp, 'ifSeqNo');
|
||||||
const ifPrimaryTerm = _.get(resp, 'ifPrimaryTerm');
|
const ifPrimaryTerm = _.get(resp, 'ifPrimaryTerm');
|
||||||
|
@ -118,7 +118,7 @@ class CreateDestination extends React.Component {
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { ifSeqNo, ifPrimaryTerm } = this.state;
|
const { ifSeqNo, ifPrimaryTerm } = this.state;
|
||||||
try {
|
try {
|
||||||
const resp = await httpClient.put(`../api/alerting/destinations/${destinationId}`, {
|
const resp = await httpClient.put(`/alerting/destinations/${destinationId}`, {
|
||||||
query: { ifSeqNo, ifPrimaryTerm },
|
query: { ifSeqNo, ifPrimaryTerm },
|
||||||
body: JSON.stringify(requestData),
|
body: JSON.stringify(requestData),
|
||||||
});
|
});
|
||||||
|
@ -139,7 +139,7 @@ class CreateDestination extends React.Component {
|
||||||
handleCreate = async (requestData, { setSubmitting }) => {
|
handleCreate = async (requestData, { setSubmitting }) => {
|
||||||
const { httpClient, history, notifications } = this.props;
|
const { httpClient, history, notifications } = this.props;
|
||||||
try {
|
try {
|
||||||
const resp = await httpClient.post('../api/alerting/destinations', {
|
const resp = await httpClient.post('/alerting/destinations', {
|
||||||
body: JSON.stringify(requestData),
|
body: JSON.stringify(requestData),
|
||||||
});
|
});
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { MAX_QUERY_RESULT_SIZE } from '../../../../../../utils/constants';
|
||||||
|
|
||||||
export default async function getEmailGroups(httpClient, searchText = '') {
|
export default async function getEmailGroups(httpClient, searchText = '') {
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.get('../api/alerting/destinations/email_groups', {
|
const response = await httpClient.get('/alerting/destinations/email_groups', {
|
||||||
query: { search: searchText, size: MAX_QUERY_RESULT_SIZE },
|
query: { search: searchText, size: MAX_QUERY_RESULT_SIZE },
|
||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { MAX_QUERY_RESULT_SIZE } from '../../../../../../utils/constants';
|
||||||
|
|
||||||
export default async function getSenders(httpClient, searchText = '') {
|
export default async function getSenders(httpClient, searchText = '') {
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.get('../api/alerting/destinations/email_accounts', {
|
const response = await httpClient.get('/alerting/destinations/email_accounts', {
|
||||||
query: { search: searchText, size: MAX_QUERY_RESULT_SIZE },
|
query: { search: searchText, size: MAX_QUERY_RESULT_SIZE },
|
||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
|
|
@ -119,7 +119,7 @@ export default class ManageEmailGroups extends React.Component {
|
||||||
emails: emailGroup.emails.map((email) => ({ email: email.label })),
|
emails: emailGroup.emails.map((email) => ({ email: email.label })),
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.post(`../api/alerting/destinations/email_groups`, {
|
const response = await httpClient.post(`/alerting/destinations/email_groups`, {
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
});
|
});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
@ -147,7 +147,7 @@ export default class ManageEmailGroups extends React.Component {
|
||||||
emails: updatedEmailGroup.emails.map((email) => ({ email: email.label })),
|
emails: updatedEmailGroup.emails.map((email) => ({ email: email.label })),
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.put(`../api/alerting/destinations/email_groups/${id}`, {
|
const response = await httpClient.put(`/alerting/email_groups/${id}`, {
|
||||||
query: { ifSeqNo, ifPrimaryTerm },
|
query: { ifSeqNo, ifPrimaryTerm },
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
});
|
});
|
||||||
|
@ -172,7 +172,7 @@ export default class ManageEmailGroups extends React.Component {
|
||||||
const { httpClient, notifications } = this.props;
|
const { httpClient, notifications } = this.props;
|
||||||
const { id } = emailGroup;
|
const { id } = emailGroup;
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.delete(`../api/alerting/destinations/email_groups/${id}`);
|
const response = await httpClient.delete(`/alerting/email_groups/${id}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
this.setState({ failedEmailGroups: true });
|
this.setState({ failedEmailGroups: true });
|
||||||
notifications.toasts.addDanger({
|
notifications.toasts.addDanger({
|
||||||
|
|
|
@ -107,7 +107,7 @@ export default class ManageSenders extends React.Component {
|
||||||
method: sender.method,
|
method: sender.method,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.post(`../api/alerting/destinations/email_accounts`, {
|
const response = await httpClient.post(`/alerting/destinations/email_accounts`, {
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
});
|
});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
@ -138,7 +138,7 @@ export default class ManageSenders extends React.Component {
|
||||||
method: updatedSender.method,
|
method: updatedSender.method,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.put(`../api/alerting/destinations/email_accounts/${id}`, {
|
const response = await httpClient.put(`/alerting/email_accounts/${id}`, {
|
||||||
query: { ifSeqNo, ifPrimaryTerm },
|
query: { ifSeqNo, ifPrimaryTerm },
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
});
|
});
|
||||||
|
@ -163,7 +163,7 @@ export default class ManageSenders extends React.Component {
|
||||||
const { httpClient, notifications } = this.props;
|
const { httpClient, notifications } = this.props;
|
||||||
const { id } = sender;
|
const { id } = sender;
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.delete(`../api/alerting/destinations/email_accounts/${id}`);
|
const response = await httpClient.delete(`/alerting/email_accounts/${id}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
this.setState({ failedSenders: true });
|
this.setState({ failedSenders: true });
|
||||||
notifications.toasts.addDanger({
|
notifications.toasts.addDanger({
|
||||||
|
|
|
@ -49,7 +49,7 @@ const customWebhookToFormik = ({
|
||||||
|
|
||||||
const getSender = async (httpClient, id) => {
|
const getSender = async (httpClient, id) => {
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.get(`../api/alerting/destinations/email_accounts/${id}`);
|
const response = await httpClient.get(`/alerting/email_accounts/${id}`);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
return response.resp;
|
return response.resp;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ const getSender = async (httpClient, id) => {
|
||||||
|
|
||||||
const getEmailGroup = async (httpClient, id) => {
|
const getEmailGroup = async (httpClient, id) => {
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.get(`../api/alerting/destinations/email_groups/${id}`);
|
const response = await httpClient.get(`/alerting/destinations/email_groups/${id}`);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
return response.resp;
|
return response.resp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ export const validateDestinationName = (httpClient, destinationToEdit) => async
|
||||||
index: INDEX.SCHEDULED_JOBS,
|
index: INDEX.SCHEDULED_JOBS,
|
||||||
query: { query: { term: { 'destination.name.keyword': value } } },
|
query: { query: { term: { 'destination.name.keyword': value } } },
|
||||||
};
|
};
|
||||||
const response = await httpClient.post('../api/alerting/monitors/_search', {
|
const response = await httpClient.post('/alerting/monitors/_search', {
|
||||||
body: JSON.stringify(options),
|
body: JSON.stringify(options),
|
||||||
});
|
});
|
||||||
if (_.get(response, 'resp.hits.total.value', 0)) {
|
if (_.get(response, 'resp.hits.total.value', 0)) {
|
||||||
|
|
|
@ -119,7 +119,7 @@ class DestinationsList extends React.Component {
|
||||||
query: isDeleteAllowedQuery(type, id),
|
query: isDeleteAllowedQuery(type, id),
|
||||||
index: INDEX.SCHEDULED_JOBS,
|
index: INDEX.SCHEDULED_JOBS,
|
||||||
};
|
};
|
||||||
const resp = await httpClient.post('../api/alerting/monitors/_search', {
|
const resp = await httpClient.post('/alerting/monitors/_search', {
|
||||||
body: JSON.stringify(requestBody),
|
body: JSON.stringify(requestBody),
|
||||||
});
|
});
|
||||||
const total = _.get(resp, 'resp.hits.total.value');
|
const total = _.get(resp, 'resp.hits.total.value');
|
||||||
|
@ -151,7 +151,7 @@ class DestinationsList extends React.Component {
|
||||||
const { id: destinationId } = this.state.destinationToDelete;
|
const { id: destinationId } = this.state.destinationToDelete;
|
||||||
const { httpClient, notifications } = this.props;
|
const { httpClient, notifications } = this.props;
|
||||||
try {
|
try {
|
||||||
const resp = await httpClient.delete(`../api/alerting/destinations/${destinationId}`);
|
const resp = await httpClient.delete(`/alerting/destinations/${destinationId}`);
|
||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
await this.getDestinations();
|
await this.getDestinations();
|
||||||
} else {
|
} else {
|
||||||
|
@ -214,7 +214,7 @@ class DestinationsList extends React.Component {
|
||||||
// search: queryParms,
|
// search: queryParms,
|
||||||
// });
|
// });
|
||||||
try {
|
try {
|
||||||
const resp = await httpClient.get('../api/alerting/destinations', {
|
const resp = await httpClient.get('/alerting/destinations', {
|
||||||
query: { from, ...params },
|
query: { from, ...params },
|
||||||
});
|
});
|
||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { backendErrorNotification } from '../../../utils/helpers';
|
||||||
|
|
||||||
export async function getAllowList(httpClient) {
|
export async function getAllowList(httpClient) {
|
||||||
try {
|
try {
|
||||||
const response = await httpClient.get('../api/alerting/_settings');
|
const response = await httpClient.get('/alerting/_settings');
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
// Attempt to resolve the value of allow_list in the order of 'persistent, 'transient' and 'defaults' settings
|
// Attempt to resolve the value of allow_list in the order of 'persistent, 'transient' and 'defaults' settings
|
||||||
const { defaults, transient, persistent } = response.resp;
|
const { defaults, transient, persistent } = response.resp;
|
||||||
|
|
|
@ -81,7 +81,7 @@ export default class MonitorDetails extends Component {
|
||||||
getDetector = (id) => {
|
getDetector = (id) => {
|
||||||
const { httpClient, notifications } = this.props;
|
const { httpClient, notifications } = this.props;
|
||||||
httpClient
|
httpClient
|
||||||
.get(`../api/alerting/detectors/${id}`)
|
.get(`/alerting/detectors/${id}`)
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
const { ok, detector, version: detectorVersion, seqNo, primaryTerm } = resp;
|
const { ok, detector, version: detectorVersion, seqNo, primaryTerm } = resp;
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
@ -101,7 +101,7 @@ export default class MonitorDetails extends Component {
|
||||||
getMonitor = (id) => {
|
getMonitor = (id) => {
|
||||||
const { httpClient } = this.props;
|
const { httpClient } = this.props;
|
||||||
httpClient
|
httpClient
|
||||||
.get(`../api/alerting/monitors/${id}`)
|
.get(`/alerting/monitors/${id}`)
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
const {
|
const {
|
||||||
ok,
|
ok,
|
||||||
|
@ -148,7 +148,7 @@ export default class MonitorDetails extends Component {
|
||||||
const { monitor, ifSeqNo, ifPrimaryTerm } = this.state;
|
const { monitor, ifSeqNo, ifPrimaryTerm } = this.state;
|
||||||
this.setState({ updating: true });
|
this.setState({ updating: true });
|
||||||
return httpClient
|
return httpClient
|
||||||
.put(`../api/alerting/monitors/${monitorId}`, {
|
.put(`/alerting/monitors/${monitorId}`, {
|
||||||
query: { ifSeqNo, ifPrimaryTerm },
|
query: { ifSeqNo, ifPrimaryTerm },
|
||||||
body: JSON.stringify({ ...monitor, ...update }),
|
body: JSON.stringify({ ...monitor, ...update }),
|
||||||
})
|
})
|
||||||
|
|
|
@ -200,7 +200,7 @@ class MonitorHistory extends PureComponent {
|
||||||
),
|
),
|
||||||
index: INDEX.ALL_ALERTS,
|
index: INDEX.ALL_ALERTS,
|
||||||
};
|
};
|
||||||
const resp = await httpClient.post('../api/alerting/monitors/_search', {
|
const resp = await httpClient.post('/alerting/monitors/_search', {
|
||||||
body: JSON.stringify(requestBody),
|
body: JSON.stringify(requestBody),
|
||||||
});
|
});
|
||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
|
@ -242,7 +242,7 @@ class MonitorHistory extends PureComponent {
|
||||||
monitorIds: monitorId,
|
monitorIds: monitorId,
|
||||||
};
|
};
|
||||||
|
|
||||||
const resp = await httpClient.get('../api/alerting/alerts', { query: params });
|
const resp = await httpClient.get('/alerting/alerts', { query: params });
|
||||||
var alerts;
|
var alerts;
|
||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
alerts = resp.alerts;
|
alerts = resp.alerts;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import uuidv4 from 'uuidv4';
|
import uuid from 'uuid-v4';
|
||||||
import { EuiButton, EuiInMemoryTable } from '@elastic/eui';
|
import { EuiButton, EuiInMemoryTable } from '@elastic/eui';
|
||||||
|
|
||||||
import ContentPanel from '../../../../components/ContentPanel';
|
import ContentPanel from '../../../../components/ContentPanel';
|
||||||
|
@ -28,7 +28,7 @@ export default class Triggers extends Component {
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
field: 'name',
|
field: 'name',
|
||||||
tableKey: uuidv4(),
|
tableKey: uuid(),
|
||||||
direction: 'asc',
|
direction: 'asc',
|
||||||
selectedItems: [],
|
selectedItems: [],
|
||||||
};
|
};
|
||||||
|
@ -45,7 +45,7 @@ export default class Triggers extends Component {
|
||||||
// which EuiInMemoryTable uses which causes items to not be updated correctly.
|
// which EuiInMemoryTable uses which causes items to not be updated correctly.
|
||||||
// Whenever the monitor is updated we'll generate a new key for the table
|
// Whenever the monitor is updated we'll generate a new key for the table
|
||||||
// which will cause the table component to remount
|
// which will cause the table component to remount
|
||||||
this.setState({ tableKey: uuidv4() });
|
this.setState({ tableKey: uuid() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,8 +144,8 @@ export default class Monitors extends Component {
|
||||||
const params = { from, size, search, sortField, sortDirection, state };
|
const params = { from, size, search, sortField, sortDirection, state };
|
||||||
const queryParamsString = queryString.stringify(params);
|
const queryParamsString = queryString.stringify(params);
|
||||||
const { httpClient, history } = this.props;
|
const { httpClient, history } = this.props;
|
||||||
history.replace({ ...this.props.location, search: queryParamsString });
|
//history.replace({ ...this.props.location, search: queryParamsString });
|
||||||
const response = await httpClient.get('../api/alerting/monitors', { query: params });
|
const response = await httpClient.get('/alerting/monitors', { query: params });
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const { monitors, totalMonitors } = response;
|
const { monitors, totalMonitors } = response;
|
||||||
this.setState({ monitors, totalMonitors });
|
this.setState({ monitors, totalMonitors });
|
||||||
|
@ -182,7 +182,7 @@ export default class Monitors extends Component {
|
||||||
const { httpClient, notifications } = this.props;
|
const { httpClient, notifications } = this.props;
|
||||||
const { id, ifSeqNo, ifPrimaryTerm, monitor } = item;
|
const { id, ifSeqNo, ifPrimaryTerm, monitor } = item;
|
||||||
return httpClient
|
return httpClient
|
||||||
.put(`../api/alerting/monitors/${id}`, {
|
.put(`/alerting/monitors/${id}`, {
|
||||||
query: { ifSeqNo, ifPrimaryTerm },
|
query: { ifSeqNo, ifPrimaryTerm },
|
||||||
body: JSON.stringify({ ...monitor, ...update }),
|
body: JSON.stringify({ ...monitor, ...update }),
|
||||||
})
|
})
|
||||||
|
@ -199,7 +199,7 @@ export default class Monitors extends Component {
|
||||||
const { httpClient, notifications } = this.props;
|
const { httpClient, notifications } = this.props;
|
||||||
const { id, version } = item;
|
const { id, version } = item;
|
||||||
return httpClient
|
return httpClient
|
||||||
.delete(`../api/alerting/monitors/${id}`, { query: { version } })
|
.delete(`/alerting/monitors/${id}`, { query: { version } })
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
if (!resp.ok) {
|
if (!resp.ok) {
|
||||||
backendErrorNotification(notifications, 'delete', 'monitor', resp.resp);
|
backendErrorNotification(notifications, 'delete', 'monitor', resp.resp);
|
||||||
|
@ -249,7 +249,7 @@ export default class Monitors extends Component {
|
||||||
|
|
||||||
const promises = Object.entries(monitorAlerts).map(([monitorId, alerts]) =>
|
const promises = Object.entries(monitorAlerts).map(([monitorId, alerts]) =>
|
||||||
httpClient
|
httpClient
|
||||||
.post(`../api/alerting/monitors/${monitorId}/_acknowledge/alerts`, {
|
.post(`/alerting/monitors/${monitorId}/_acknowledge/alerts`, {
|
||||||
body: JSON.stringify({ alerts }),
|
body: JSON.stringify({ alerts }),
|
||||||
})
|
})
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
|
@ -321,7 +321,7 @@ export default class Monitors extends Component {
|
||||||
|
|
||||||
const { httpClient, notifications } = this.props;
|
const { httpClient, notifications } = this.props;
|
||||||
|
|
||||||
const response = await httpClient.get('../api/alerting/alerts', { query: params });
|
const response = await httpClient.get('/alerting/alerts', { query: params });
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const { alerts, totalAlerts } = response;
|
const { alerts, totalAlerts } = response;
|
||||||
|
|
|
@ -160,7 +160,7 @@ describe('Monitors', () => {
|
||||||
|
|
||||||
expect(updateMonitor).toHaveBeenCalled();
|
expect(updateMonitor).toHaveBeenCalled();
|
||||||
expect(httpClientMock.put).toHaveBeenCalled();
|
expect(httpClientMock.put).toHaveBeenCalled();
|
||||||
expect(httpClientMock.put).toHaveBeenCalledWith(`../api/alerting/monitors/random_id`, {
|
expect(httpClientMock.put).toHaveBeenCalledWith(`/alerting/monitors/random_id`, {
|
||||||
query: { ifSeqNo: 17, ifPrimaryTerm: 20 },
|
query: { ifSeqNo: 17, ifPrimaryTerm: 20 },
|
||||||
body: JSON.stringify({ ...monitor, name: 'UNIQUE_NAME' }),
|
body: JSON.stringify({ ...monitor, name: 'UNIQUE_NAME' }),
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,7 +34,7 @@ export const columns = [
|
||||||
truncateText: true,
|
truncateText: true,
|
||||||
textOnly: true,
|
textOnly: true,
|
||||||
// width: '150px',
|
// width: '150px',
|
||||||
render: (name, item) => <EuiLink href={`${PLUGIN_NAME}#/monitors/${item.id}`}>{name}</EuiLink>,
|
render: (name, item) => <EuiLink href={`#/${PLUGIN_NAME}/monitors/${item.id}`}>{name}</EuiLink>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'user',
|
field: 'user',
|
||||||
|
|
|
@ -66,10 +66,10 @@ export const AD_PREVIEW_DAYS = 7;
|
||||||
export const MAX_QUERY_RESULT_SIZE = 200;
|
export const MAX_QUERY_RESULT_SIZE = 200;
|
||||||
|
|
||||||
|
|
||||||
export const OPEN_DISTRO_PREFIX = '';
|
export const OPEN_DISTRO_PREFIX = 'opendistro';
|
||||||
|
|
||||||
export const PLUGIN_NAME = `alerting`;
|
export const PLUGIN_NAME = `alerting`;
|
||||||
export const INDEX_PREFIX = `alerting`;
|
export const INDEX_PREFIX = `${OPEN_DISTRO_PREFIX}-alerting`;
|
||||||
export const INDEX = {
|
export const INDEX = {
|
||||||
SCHEDULED_JOBS: `.${INDEX_PREFIX}-config`,
|
SCHEDULED_JOBS: `.${INDEX_PREFIX}-config`,
|
||||||
ALERTS: `.${INDEX_PREFIX}-alerts`,
|
ALERTS: `.${INDEX_PREFIX}-alerts`,
|
||||||
|
|
|
@ -56,7 +56,7 @@ export const validateMonitorName = (httpClient, monitorToEdit) => async (value)
|
||||||
index: INDEX.SCHEDULED_JOBS,
|
index: INDEX.SCHEDULED_JOBS,
|
||||||
query: { query: { term: { 'monitor.name.keyword': value } } },
|
query: { query: { term: { 'monitor.name.keyword': value } } },
|
||||||
};
|
};
|
||||||
const response = await httpClient.post('../api/alerting/monitors/_search', {
|
const response = await httpClient.post('/alerting/monitors/_search', {
|
||||||
body: JSON.stringify(options),
|
body: JSON.stringify(options),
|
||||||
});
|
});
|
||||||
if (_.get(response, 'resp.hits.total.value', 0)) {
|
if (_.get(response, 'resp.hits.total.value', 0)) {
|
||||||
|
|
Loading…
Reference in New Issue