// GetClient retrieves client history from specified DC func (u *Uchiwa) GetClient(client, dc string) (map[string]interface{}, error) { api, err := getAPI(u.Datacenters, dc) if err != nil { logger.Warning(err) return nil, err } // lock results while we gather client info u.Mu.Lock() defer u.Mu.Unlock() c, err := u.findClientInClients(&client, &dc) if err != nil { logger.Warning(err) return nil, err } h, err := api.GetClientHistory(client) if err != nil { logger.Warning(err) return nil, err } history := u.buildClientHistory(client, dc, h) // add client history to client map for easy frontend consumption c["history"] = history return c, nil }
// GetAggregate retrieves a list of issued timestamps from a specified DC func (u *Uchiwa) GetAggregate(check string, dc string) (*[]interface{}, error) { api, err := getAPI(u.Datacenters, dc) if err != nil { logger.Warning(err) return nil, err } aggregate, err := api.GetAggregate(check, 1) if err != nil { logger.Warning(err) return nil, err } return &aggregate, nil }
// GetAggregateByIssued retrieves aggregate check info from a specified DC func (u *Uchiwa) GetAggregateByIssued(check string, issued string, dc string) (*map[string]interface{}, error) { api, err := getAPI(u.Datacenters, dc) if err != nil { logger.Warning(err) return nil, err } aggregate, err := api.GetAggregateIssued(check, issued) if err != nil { logger.Warning(err) return nil, err } return &aggregate, nil }
// DeleteClient send a DELETE request to the /clients/*client* endpoint in order to delete a client func (u *Uchiwa) DeleteClient(id string, dc string) error { api, err := getAPI(u.Datacenters, dc) if err != nil { logger.Warning(err) return err } err = api.DeleteClient(id) if err != nil { logger.Warning(err) return err } return nil }
// PostStash send a POST request to the /stashes endpoint in order to create a stash func (u *Uchiwa) PostStash(data stash) error { api, err := getAPI(u.Datacenters, data.Dc) if err != nil { logger.Warning(err) return err } _, err = api.CreateStash(data) if err != nil { logger.Warning(err) return err } return nil }
// DeleteStash send a DELETE request to the /stashes/*path* endpoint in order to delete a stash func (u *Uchiwa) DeleteStash(data stash) error { api, err := getAPI(u.Datacenters, data.Dc) if err != nil { logger.Warning(err) return err } err = api.DeleteStash(data.Path) if err != nil { logger.Warning(err) return err } return nil }
// DeleteCheckResult sends a DELETE request in order to // remove the result for a given check on a given client func (u *Uchiwa) DeleteCheckResult(check, client, dc string) error { api, err := getAPI(u.Datacenters, dc) if err != nil { logger.Warning(err) return err } err = api.DeleteCheckResult(check, client) if err != nil { logger.Warning(err) return err } return nil }
// DeleteStash send a DELETE request to the /stashes/*path* endpoint in order to delete a stash func (u *Uchiwa) DeleteStash(dc, path string) error { api, err := getAPI(u.Datacenters, dc) if err != nil { logger.Warning(err) return err } err = api.DeleteStash(path) if err != nil { logger.Warning(err) return err } return nil }
// IssueCheckExecution sends a POST request to the /stashes endpoint in order to create a stash func (u *Uchiwa) IssueCheckExecution(data structs.CheckExecution) error { api, err := getAPI(u.Datacenters, data.Dc) if err != nil { logger.Warning(err) return err } _, err = api.IssueCheckExecution(data) if err != nil { logger.Warning(err) return err } return nil }
// getSlice returns the body of a GET request as []interface{} func (api *API) getSlice(endpoint string, limit int) ([]interface{}, error) { var offset int u, err := url.Parse(fmt.Sprintf("%s/%s", api.URL, endpoint)) if err != nil { return nil, fmt.Errorf("Could not parse the URL '%s': %v", u.String(), err) } // Add limit & offset parameters when required if limit != -1 { params := u.Query() params.Add("limit", strconv.Itoa(limit)) params.Add("offset", strconv.Itoa(offset)) u.RawQuery = params.Encode() } body, res, err := api.get(u.String()) if err != nil { return nil, err } list, err := helpers.GetInterfacesFromBytes(body) if err != nil { return nil, fmt.Errorf("Could not parse the JSON-encoded response body: %v", err) } // Verify if the endpoint supports pagination if limit != -1 && res.Header.Get("X-Pagination") != "" { var xPagination structs.XPagination err = json.Unmarshal([]byte(res.Header.Get("X-Pagination")), &xPagination) if err != nil { logger.Warning(err) } for len(list) < xPagination.Total { offset += limit params := u.Query() params.Set("offset", strconv.Itoa(offset)) u.RawQuery = params.Encode() body, _, err := api.get(u.String()) if err != nil { return nil, err } partialList, err := helpers.GetInterfacesFromBytes(body) if err != nil { return nil, fmt.Errorf("Could not parse the JSON-encoded response body: %v", err) } for _, e := range partialList { list = append(list, e) } } } return list, nil }
// ResolveEvent send a POST request to the /resolve endpoint in order to resolve an event func (d *Daemon) ResolveEvent(data interface{}) error { api, m, err := FindDcFromInterface(data, d.Datacenters) _, err = api.ResolveEvent(m["payload"]) if err != nil { logger.Warning(err) return err } return nil }
// loadDirectories loads a Config struct from one or multiple directories of configuration func loadDirectories(path string) *Config { conf := new(Config) var configFiles []string directories := strings.Split(strings.ToLower(path), ",") for _, directory := range directories { // Find all JSON files in the specified directories files, err := filepath.Glob(filepath.Join(directory, "*.json")) if err != nil { logger.Warning(err) continue } // Add the files found to a slice of configuration files to open for _, file := range files { configFiles = append(configFiles, file) } } // Load every configuration files and merge them together bit by bit for _, file := range configFiles { // Load the config from the file c, err := loadFile(file) if err != nil { logger.Warning(err) continue } // Apply this configuration to the existing one if err := mergo.MergeWithOverwrite(conf, c); err != nil { logger.Warning(err) continue } } // Apply the default config to the Sensu APIs for i := range conf.Sensu { if err := mergo.Merge(&conf.Sensu[i], defaultSensuConfig); err != nil { logger.Fatal(err) } } return conf }
// getData retrieves all endpoints for every datacenter func (d *Daemon) fetchData() { d.Data.Health.Sensu = make(map[string]structs.SensuHealth, len(*d.Datacenters)) for _, datacenter := range *d.Datacenters { // set default health status d.Data.Health.Sensu[datacenter.Name] = structs.SensuHealth{Output: datacenterErrorString} d.Data.Health.Uchiwa = "ok" // fetch sensu data from the datacenter stashes, err := datacenter.GetStashes() if err != nil { logger.Warning(err) continue } checks, err := datacenter.GetChecks() if err != nil { logger.Warning(err) continue } clients, err := datacenter.GetClients() if err != nil { logger.Warning(err) continue } events, err := datacenter.GetEvents() if err != nil { logger.Warning(err) continue } info, err := datacenter.Info() if err != nil { logger.Warning(err) continue } aggregates, err := datacenter.GetAggregates() if err != nil { logger.Warning(err) continue } d.Data.Health.Sensu[datacenter.Name] = structs.SensuHealth{Output: "ok"} // add fetched data into d.Data interface for _, v := range stashes { setDc(v, datacenter.Name) d.Data.Stashes = append(d.Data.Stashes, v) } for _, v := range checks { setDc(v, datacenter.Name) d.Data.Checks = append(d.Data.Checks, v) } for _, v := range clients { setDc(v, datacenter.Name) d.Data.Clients = append(d.Data.Clients, v) } for _, v := range events { setDc(v, datacenter.Name) d.Data.Events = append(d.Data.Events, v) } for _, v := range aggregates { setDc(v, datacenter.Name) d.Data.Aggregates = append(d.Data.Aggregates, v) } // build datacenter dc := d.buildDatacenter(&datacenter.Name, info) dc.Stats["aggregates"] = len(aggregates) dc.Stats["checks"] = len(checks) dc.Stats["clients"] = len(clients) dc.Stats["events"] = len(events) dc.Stats["stashes"] = len(stashes) d.Data.Dc = append(d.Data.Dc, dc) } }