Skip to content
This repository has been archived by the owner on Jan 7, 2020. It is now read-only.

Commit

Permalink
Add the /datacenters/:name endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
palourde committed Mar 23, 2017
1 parent 240a184 commit 0ed1264
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 15 deletions.
19 changes: 13 additions & 6 deletions uchiwa/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,36 +80,43 @@ func (d *Daemon) fetchData() {
// fetch sensu data from the datacenter
stashes, err := datacenter.GetStashes()
if err != nil {
logger.Debug(err)
logger.Warningf("Connection failed to the datacenter %s", datacenter.Name)
continue
}
silenced, err := datacenter.GetSilenced()
if err != nil {
logger.Debug(err)
logger.Warningf("Impossible to retrieve silenced entries from the "+
"datacenter %s. Silencing might not be possible, please update Sensu", datacenter.Name)
}
checks, err := datacenter.GetChecks()
if err != nil {
logger.Debug(err)
logger.Warningf("Connection failed to the datacenter %s", datacenter.Name)
continue
}
clients, err := datacenter.GetClients()
if err != nil {
logger.Debug(err)
logger.Warningf("Connection failed to the datacenter %s", datacenter.Name)
continue
}
events, err := datacenter.GetEvents()
if err != nil {
logger.Debug(err)
logger.Warningf("Connection failed to the datacenter %s", datacenter.Name)
continue
}
info, err := datacenter.GetInfo()
if err != nil {
logger.Debug(err)
logger.Warningf("Connection failed to the datacenter %s", datacenter.Name)
continue
}
aggregates, err := datacenter.GetAggregates()
if err != nil {
logger.Debug(err)
logger.Warningf("Connection failed to the datacenter %s", datacenter.Name)
continue
}
Expand Down Expand Up @@ -155,12 +162,12 @@ func (d *Daemon) fetchData() {

// 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["silenced"] = len(silenced)
dc.Stats["stashes"] = len(stashes)
dc.Metrics["aggregates"] = len(aggregates)
dc.Metrics["checks"] = len(checks)
dc.Metrics["clients"] = len(clients)
dc.Metrics["events"] = len(events)
dc.Metrics["silenced"] = len(silenced)
dc.Metrics["stashes"] = len(stashes)
d.Data.Dc = append(d.Data.Dc, dc)
}
}
Expand Down
6 changes: 3 additions & 3 deletions uchiwa/daemon/datacenters.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import "github.com/sensu/uchiwa/uchiwa/structs"

func (d *Daemon) buildDatacenter(name *string, info *structs.Info) *structs.Datacenter {
datacenter := structs.Datacenter{
Name: *name,
Info: *info,
Stats: make(map[string]int, 5),
Name: *name,
Info: *info,
Metrics: make(map[string]int, 5),
}

return &datacenter
Expand Down
17 changes: 17 additions & 0 deletions uchiwa/datacenter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package uchiwa

import (
"fmt"

"github.com/sensu/uchiwa/uchiwa/structs"
)

func (u *Uchiwa) Datacenter(name string) (*structs.Datacenter, error) {
for _, dc := range u.Data.Dc {
if dc.Name == name {
return dc, nil
}
}

return nil, fmt.Errorf("")
}
42 changes: 42 additions & 0 deletions uchiwa/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,47 @@ func (u *Uchiwa) configHandler(w http.ResponseWriter, r *http.Request) {
}
}

// datacentersHandler serves the /datacenters/:name endpoint
func (u *Uchiwa) datacenterHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" && r.Method != "HEAD" {
http.Error(w, "", http.StatusBadRequest)
return
}

resources := strings.Split(r.URL.Path, "/")
if len(resources) < 3 || resources[2] == "" {
http.Error(w, "", http.StatusBadRequest)
return
}

name := resources[2]

token := authentication.GetJWTFromContext(r)
unauthorized := Filters.GetRequest(name, token)
if unauthorized {
http.Error(w, fmt.Sprint(""), http.StatusNotFound)
return
}

// Create header
w.Header().Add("Accept-Charset", "utf-8")
w.Header().Add("Content-Type", "application/json")

datacenter, err := u.Datacenter(name)
if err != nil {
http.Error(w, fmt.Sprint(""), http.StatusNotFound)
return
}

encoder := json.NewEncoder(w)
if err := encoder.Encode(datacenter); err != nil {
http.Error(w, fmt.Sprintf("Cannot encode response data: %v", err), http.StatusInternalServerError)
return
}

return
}

// datacentersHandler serves the /datacenters endpoint
func (u *Uchiwa) datacentersHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" && r.Method != "HEAD" {
Expand Down Expand Up @@ -1173,6 +1214,7 @@ func (u *Uchiwa) WebServer(publicPath *string, auth authentication.Config) {
http.Handle("/clients/", auth.Authenticate(Authorization.Handler(http.HandlerFunc(u.clientHandler))))
http.Handle("/config", auth.Authenticate(Authorization.Handler(http.HandlerFunc(u.configHandler))))
http.Handle("/datacenters", auth.Authenticate(Authorization.Handler(http.HandlerFunc(u.datacentersHandler))))
http.Handle("/datacenters/", auth.Authenticate(Authorization.Handler(http.HandlerFunc(u.datacenterHandler))))
http.Handle("/events", auth.Authenticate(Authorization.Handler(http.HandlerFunc(u.eventsHandler))))
http.Handle("/events/", auth.Authenticate(Authorization.Handler(http.HandlerFunc(u.eventHandler))))
http.Handle("/logout", auth.Authenticate(Authorization.Handler(http.HandlerFunc(u.logoutHandler))))
Expand Down
22 changes: 16 additions & 6 deletions uchiwa/structs/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ type Data struct {

// Datacenter is a structure for holding the information about a datacenter
type Datacenter struct {
Name string `json:"name"`
Info Info `json:"info"`
Stats map[string]int `json:"stats"`
Name string `json:"name"`
Info Info `json:"info"`
Metrics map[string]int `json:"metrics"`
}

// Generic is a structure for holding a generic element
Expand Down Expand Up @@ -93,9 +93,19 @@ type SensuHealth struct {

// Info is a structure for holding the /info API information
type Info struct {
Redis Redis `json:"redis"`
Sensu Sensu `json:"sensu"`
Transport transport `json:"transport"`
Redis Redis `json:"redis"`
Sensu Sensu `json:"sensu"`
Servers []InfoServer `json:"servers"`
Transport transport `json:"transport"`
}

type InfoServer struct {
ID string `json:"id"`
Hostname string `json:"hostname"`
Address string `json:"address"`
IsLeader bool `json:"is_leader"`
Metrics map[string]map[string]float32 `json:"metrics"`
Timestamp int `json:"timestamp"`
}

// Redis is a structure for holding the redis status
Expand Down

0 comments on commit 0ed1264

Please sign in to comment.