Skip to content

Commit

Permalink
Added cluster/leader endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
aantono authored and traefiker committed Mar 22, 2018
1 parent 0fa0c22 commit 9699dc2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
32 changes: 32 additions & 0 deletions cluster/leadership.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@ package cluster

import (
"context"
"net/http"
"time"

"github.com/cenk/backoff"
"github.com/containous/mux"
"github.com/containous/traefik/log"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
"github.com/docker/leadership"
"github.com/unrolled/render"
)

var templatesRenderer = render.New(render.Options{
Directory: "nowhere",
})

// Leadership allows leadership election using a KV store
type Leadership struct {
*safe.Pool
Expand Down Expand Up @@ -98,7 +105,32 @@ func (l *Leadership) onElection(elected bool) {
}
}

type leaderResponse struct {
Leader bool `json:"leader"`
}

func (l *Leadership) getLeaderHandler(response http.ResponseWriter, request *http.Request) {
leader := &leaderResponse{Leader: l.IsLeader()}

status := http.StatusOK
if !leader.Leader {
// Set status to be `429`, as this will typically cause load balancers to stop sending requests to the instance without removing them from rotation.
status = http.StatusTooManyRequests
}

err := templatesRenderer.JSON(response, status, leader)
if err != nil {
log.Error(err)
}
}

// IsLeader returns true if current node is leader
func (l *Leadership) IsLeader() bool {
return l.leader.Get().(bool)
}

// AddRoutes add dashboard routes on a router
func (l *Leadership) AddRoutes(router *mux.Router) {
// Expose cluster leader
router.Methods(http.MethodGet).Path("/api/cluster/leader").HandlerFunc(l.getLeaderHandler)
}
20 changes: 20 additions & 0 deletions docs/configuration/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ For more customization, see [entry points](/configuration/entrypoints/) document
| Path | Method | Description |
|-----------------------------------------------------------------|------------------|-------------------------------------------|
| `/` | `GET` | Provides a simple HTML frontend of Træfik |
| `/cluster/leader` | `GET` | JSON leader true/false response |
| `/health` | `GET` | JSON health metrics |
| `/api` | `GET` | Configuration for all providers |
| `/api/providers` | `GET` | Providers |
Expand Down Expand Up @@ -222,6 +223,25 @@ curl -s "http://localhost:8080/api" | jq .
}
```

### Cluster Leadership

```shell
curl -s "http://localhost:8080/cluster/leader" | jq .
```
```shell
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=UTF-8
< Date: xxx
< Content-Length: 15
```
If the given node is not a cluster leader, an HTTP status of `429-Too-Many-Requests` will be returned.
```json
{
// current leadership status of the queried node
"leader": true
}
```

### Health

```shell
Expand Down
3 changes: 3 additions & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,9 @@ func (s *Server) addInternalRoutes(entryPointName string, router *mux.Router) {

if s.globalConfiguration.API != nil && s.globalConfiguration.API.EntryPoint == entryPointName {
s.globalConfiguration.API.AddRoutes(router)
if s.leadership != nil {
s.leadership.AddRoutes(router)
}
}
}

Expand Down

0 comments on commit 9699dc2

Please sign in to comment.