func (c *Config) initSensu() { for i, api := range c.Sensu { prot := "http" if api.Name == "" { logger.Warningf("Sensu API %s has no name property. Generating random one...", api.URL) c.Sensu[i].Name = fmt.Sprintf("sensu-%v", rand.Intn(100)) } // escape special characters in DC name r := strings.NewReplacer(":", "", "/", "", ";", "", "?", "") c.Sensu[i].Name = r.Replace(api.Name) if api.Host == "" { logger.Fatalf("Sensu API %q Host is missing", api.Name) } if api.Timeout == 0 { c.Sensu[i].Timeout = 10 } else if api.Timeout >= 1000 { // backward compatibility with < 0.3.0 version c.Sensu[i].Timeout = api.Timeout / 1000 } if api.Port == 0 { c.Sensu[i].Port = 4567 } if api.Ssl { prot += "s" } c.Sensu[i].URL = fmt.Sprintf("%s://%s:%d%s", prot, api.Host, c.Sensu[i].Port, api.Path) } }
func setDc(v interface{}, dc string) { m, ok := v.(map[string]interface{}) if !ok { logger.Warningf("Could not assert interface: %+v", v) } else { m["dc"] = dc } }
func getRedisStatus(info map[string]interface{}) string { redis, ok := info["redis"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert info's redis interface %+v", info["redis"]) return "unknown" } return fmt.Sprintf("%t", redis["connected"]) }
func getSensuVersion(info map[string]interface{}) string { sensu, ok := info["sensu"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert info's sensu interface %+v", info["sensu"]) return "?" } return sensu["version"].(string) }
// BuildEvents constructs events objects for frontend consumption func BuildEvents() { for _, e := range tmpResults.Events { m := e.(map[string]interface{}) // build backward compatible event object for Sensu < 0.13.0 if m["id"] == nil { // build client object c := m["client"] delete(m, "client") m["client"] = map[string]interface{}{"name": c} // build check object c = m["check"] delete(m, "check") m["check"] = map[string]interface{}{"name": c, "issued": m["issued"], "output": m["output"], "status": m["status"]} // is flapping? if m["action"] == false { m["action"] = "create" } else { m["action"] = "flapping" } // remove old entries delete(m, "issued") delete(m, "output") delete(m, "status") } c, ok := m["client"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert event's client interface: %+v", c) continue } k := m["check"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert event's check interface: %+v", k) continue } m["acknowledged"] = isAcknowledged(c["name"].(string), k["name"].(string), m["dc"].(string)) } }
func (u *Uchiwa) findOutput(id *string, h map[string]interface{}, dc *string) string { if h["last_status"] == 0 { return "" } for _, e := range u.Data.Events { // does the dc match? m, ok := e.(map[string]interface{}) if !ok { logger.Warningf("Could not assert event interface %+v", e) continue } if m["dc"] != *dc { continue } // does the client match? c, ok := m["client"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert event's client interface: %+v", c) continue } if c["name"] != *id { continue } // does the check match? k := m["check"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert event's check interface: %+v", k) continue } if k["name"] != h["check"] { continue } return k["output"].(string) } return "" }
func findModel(id string, dc string, checks []interface{}) map[string]interface{} { for _, k := range checks { m, ok := k.(map[string]interface{}) if !ok { logger.Warningf("Could not assert check interface %+v", k) continue } if m["name"] == id && m["dc"] == dc { return m } } return nil }
func findDcFromInterface(data interface{}) (*sensu.Sensu, map[string]interface{}, error) { m, ok := data.(map[string]interface{}) if !ok { logger.Warningf("Type assertion failed. Could not assert the given interface into a map: %+v", data) return nil, nil, errors.New("Could not determine the datacenter.") } id := m["dc"].(string) if id == "" { logger.Warningf("The received interface does not contain any datacenter information: ", data) return nil, nil, errors.New("Could not determine the datacenter.") } for _, dc := range datacenters { if dc.Name == id { return &dc, m, nil } } logger.Warningf("Could not find the datacenter %s into %+v: ", id, data) return nil, nil, fmt.Errorf("Could not find the datacenter %s", id) }
func (u *Uchiwa) findClientInClients(id *string, dc *string) (map[string]interface{}, error) { for _, c := range u.Data.Clients { m, ok := c.(map[string]interface{}) if !ok { logger.Warningf("Could not assert client interface %+v", c) continue } if m["name"] == *id && m["dc"] == *dc { return m, nil } } return nil, fmt.Errorf("Could not find client %s", *id) }
func buildClientHistory(id *string, history *[]interface{}, dc *string) { for _, h := range *history { m, ok := h.(map[string]interface{}) if !ok { logger.Warningf("Could not assert history interface %+v", h) continue } m["acknowledged"] = isAcknowledged(*id, m["check"].(string), *dc) m["output"] = findOutput(id, m, dc) m["model"] = findModel(m["check"].(string), *dc) m["client"] = id m["dc"] = dc } }
// DeleteStash send a DELETE request to the /stashes/*path* endpoint in order to delete a stash func DeleteStash(data interface{}) error { api, m, err := findDcFromInterface(data) p, ok := m["payload"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert data interface %+v", data) return errors.New("Could not assert data interface") } err = api.DeleteStash(p["path"].(string)) if err != nil { logger.Warning(err) return err } return nil }
func (u *Uchiwa) buildClientHistory(id *string, history *[]interface{}, dc *string) { for _, h := range *history { m, ok := h.(map[string]interface{}) if !ok { logger.Warningf("Could not assert history interface %+v", h) continue } // last_status comes in as a float64, so needs 0.0 if m["last_status"] == 0.0 { lastResult := m["last_result"] lr, _ := lastResult.(map[string]interface{}) m["output"] = lr["output"] } else { m["output"] = u.findOutput(id, m, dc) } m["model"] = findModel(m["check"].(string), *dc, u.Data.Checks) m["client"] = id m["dc"] = dc m["acknowledged"] = daemon.IsAcknowledged(*id, m["check"].(string), *dc, u.Data.Stashes) } }
// GetIdentification retrieves the user & pass from a POST and authenticates the user against the Identification driver func (a *Config) GetIdentification() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { http.Redirect(w, r, "/#/login", http.StatusFound) return } decoder := json.NewDecoder(r.Body) var data interface{} err := decoder.Decode(&data) if err != nil { logger.Warningf("Could not decode the body: %s", err) http.Error(w, "", http.StatusInternalServerError) return } m, ok := data.(map[string]interface{}) if !ok { logger.Warningf("Could not assert the body: %s", err) http.Error(w, "", http.StatusInternalServerError) return } u := m["user"].(string) p := m["pass"].(string) if u == "" || p == "" { logger.Info("Authentication failed: user and password must not be empty") http.Error(w, "", http.StatusUnauthorized) return } // validate the user with the Login authentication driver user, err := a.Driver(u, p) if err != nil { logger.Infof("Authentication failed: %s", err) http.Error(w, "", http.StatusUnauthorized) return } // obfuscate the user's salt & hash user.PasswordHash = "" user.PasswordSalt = "" token, err := GetToken(&user.Role) if err != nil { logger.Warningf("Authentication failed, could not create the token: %s", err) http.Error(w, "", http.StatusInternalServerError) return } // Add token to the user struct user.Token = token j, err := json.Marshal(user) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.Write(j) return }) }
func findStatus(client map[string]interface{}) { if len(tmpResults.Events) == 0 { client["status"] = 0 } else { var criticals, warnings int var results []string for _, e := range tmpResults.Events { m, ok := e.(map[string]interface{}) if !ok { logger.Warningf("Could not assert event interface %+v", e) continue } // skip this event if another dc if m["dc"] != client["dc"] { continue } c, ok := m["client"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert event's client interface: %+v", c) continue } // skip this event if another client if c["name"] != client["name"] || m["dc"] != client["dc"] { continue } k := m["check"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert event's check interface: %+v", k) continue } results = append(results, k["output"].(string)) status := int(k["status"].(float64)) if status == 2 { criticals++ } else if status == 1 { warnings++ } } if len(results) == 0 { client["status"] = 0 } else if criticals > 0 { client["status"] = 2 } else if warnings > 0 { client["status"] = 1 } else { client["status"] = 3 } if len(results) == 1 { client["output"] = results[0] } else if len(results) > 1 { output := fmt.Sprintf("%s and %d more...", results[0], (len(results) - 1)) client["output"] = output } } }
// BuildEvents constructs events objects for frontend consumption func (d *Daemon) buildEvents() { for _, e := range d.Data.Events { m := e.(map[string]interface{}) // build backward compatible event object for Sensu < 0.13.0 if m["id"] == nil { // build client object c := m["client"] delete(m, "client") m["client"] = map[string]interface{}{"name": c} // build check object c = m["check"] delete(m, "check") m["check"] = map[string]interface{}{"name": c, "issued": m["issued"], "output": m["output"], "status": m["status"]} // is flapping? if m["action"] == false { m["action"] = "create" } else { m["action"] = "flapping" } // remove old entries delete(m, "issued") delete(m, "output") delete(m, "status") } // we assume the event isn't acknowledged in case we can't assert the following values m["acknowledged"] = false // get client name c, ok := m["client"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert event's client interface from %+v", c) continue } clientName, ok := c["name"].(string) if !ok { logger.Warningf("Could not assert event's client name from %+v", c) continue } // get check name k, ok := m["check"].(map[string]interface{}) if !ok { logger.Warningf("Could not assert event's check interface from %+v", k) continue } checkName, ok := k["name"].(string) if !ok { logger.Warningf("Could not assert event's check name from %+v", k) continue } // get dc name dcName, ok := m["dc"].(string) if !ok { logger.Warningf("Could not assert event's datacenter name from %+v", m) continue } // determine if the event is acknowledged m["acknowledged"] = IsAcknowledged(clientName, checkName, dcName, d.Data.Stashes) // detertermine if the client is acknowledged m["client"].(map[string]interface{})["acknowledged"] = IsAcknowledged(clientName, "", dcName, d.Data.Stashes) } }
// findClientEvents searches for all events related to a particular client // and set the status and output attributes of this client based on the events found func findClientEvents(client map[string]interface{}, events *[]interface{}) map[string]interface{} { if len(*events) == 0 { client["status"] = 0 } else { var criticals, warnings int var results []string for _, e := range *events { eventMap, ok := e.(map[string]interface{}) if !ok { logger.Warningf("Could not convert the event to a map: %+v", eventMap) continue } // skip this event if the check attribute does not exist if eventMap["check"] == nil { continue } // skip this event if the datacenter isn't the right one if eventMap["dc"] == nil || eventMap["dc"] != client["dc"] { continue } clientMap, ok := eventMap["client"].(map[string]interface{}) if !ok { logger.Warningf("Could not convert the event's client to a map: %+v", eventMap) continue } // skip this event if the client isn't the right one if clientMap["name"] == nil || clientMap["name"] != client["name"] { continue } // convert the check to a structure for easier handling var check structs.GenericCheck err := mapstructure.Decode(eventMap["check"], &check) if err != nil { logger.Warningf("Could not convert the event's check to a generic check structure: %s", err) continue } if check.Status == 2 { criticals++ } else if check.Status == 1 { warnings++ } results = append(results, check.Output) } if len(results) == 0 { client["status"] = 0 } else if criticals > 0 { client["status"] = 2 } else if warnings > 0 { client["status"] = 1 } else { client["status"] = 3 } if len(results) == 1 { client["output"] = results[0] } else if len(results) > 1 { output := fmt.Sprintf("%s and %d more...", results[0], (len(results) - 1)) client["output"] = output } } return client }