Merge pull request #1919 from arthurgavazza/feat/add-authless-healthcheck

feat: add health endpoint
This commit is contained in:
Hector Sanjuan 2023-06-14 21:54:06 +02:00 committed by GitHub
commit ef435f6054
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 91 additions and 4 deletions

View File

@ -300,9 +300,9 @@ func (api *API) authHandler(h http.Handler, lggr *logging.ZapEventLogger) http.H
} }
wrap := func(w http.ResponseWriter, r *http.Request) { wrap := func(w http.ResponseWriter, r *http.Request) {
// We let CORS preflight requests pass through the next // We let CORS preflight and Health requests pass through to
// handler. // the next handler.
if r.Method == http.MethodOptions { if r.Method == http.MethodOptions || (r.Method == http.MethodGet && r.URL.Path == "/health") {
h.ServeHTTP(w, r) h.ServeHTTP(w, r)
return return
} }
@ -853,3 +853,8 @@ func (api *API) Headers() map[string][]string {
func (api *API) SetKeepAlivesEnabled(b bool) { func (api *API) SetKeepAlivesEnabled(b bool) {
api.server.SetKeepAlivesEnabled(b) api.server.SetKeepAlivesEnabled(b)
} }
func (api *API) HealthHandler(w http.ResponseWriter, r *http.Request){
api.SendResponse(w,http.StatusNoContent,nil,nil)
}

View File

@ -22,9 +22,9 @@ import (
"go.uber.org/multierr" "go.uber.org/multierr"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
rpc "github.com/libp2p/go-libp2p-gorpc"
"github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/host"
peer "github.com/libp2p/go-libp2p/core/peer" peer "github.com/libp2p/go-libp2p/core/peer"
rpc "github.com/libp2p/go-libp2p-gorpc"
) )
var ( var (
@ -178,6 +178,12 @@ func (api *API) routes(c *rpc.Client) []common.Route {
Pattern: "/token", Pattern: "/token",
HandlerFunc: api.GenerateTokenHandler, HandlerFunc: api.GenerateTokenHandler,
}, },
{
Name: "Health",
Method: "GET",
Pattern: "/health",
HandlerFunc: api.HealthHandler,
},
} }
} }

View File

@ -251,3 +251,19 @@ func TestAPIRemovePinEndpoint(t *testing.T) {
test.BothEndpoints(t, tf) test.BothEndpoints(t, tf)
} }
func TestHealthEndpoint(t *testing.T) {
ctx := context.Background()
svcapi := testAPI(t)
defer svcapi.Shutdown(ctx)
tf := func(t *testing.T, url test.URLFunc) {
errResp := api.Error{}
test.MakeGet(t, svcapi, url(svcapi)+"/health", &errResp)
if errResp.Code != 0 || errResp.Message != "" {
t.Error("expected no errors")
}
}
test.BothEndpoints(t, tf)
}

View File

@ -122,6 +122,9 @@ type Client interface {
// returns collected CIDs. If local is true, it would garbage collect // returns collected CIDs. If local is true, it would garbage collect
// only on contacted peer, otherwise on all peers' IPFS daemons. // only on contacted peer, otherwise on all peers' IPFS daemons.
RepoGC(ctx context.Context, local bool) (api.GlobalRepoGC, error) RepoGC(ctx context.Context, local bool) (api.GlobalRepoGC, error)
// Health returns no content when everything is ok, and an error otherwise
Health(ctx context.Context) (error)
} }
// Config allows to configure the parameters to connect // Config allows to configure the parameters to connect

View File

@ -5,8 +5,10 @@ import (
"sync/atomic" "sync/atomic"
"github.com/ipfs-cluster/ipfs-cluster/api" "github.com/ipfs-cluster/ipfs-cluster/api"
files "github.com/ipfs/boxo/files" files "github.com/ipfs/boxo/files"
shell "github.com/ipfs/go-ipfs-api" shell "github.com/ipfs/go-ipfs-api"
peer "github.com/libp2p/go-libp2p/core/peer" peer "github.com/libp2p/go-libp2p/core/peer"
) )
@ -553,3 +555,12 @@ func (lc *loadBalancingClient) IPFS(ctx context.Context) *shell.Shell {
return s return s
} }
func (lc *loadBalancingClient) Health(ctx context.Context) (error) {
call := func(c Client) error {
err := c.Health(ctx)
return err
}
err := lc.retry(0, call)
return err
}

View File

@ -697,3 +697,10 @@ func (c *defaultClient) AddMultiFile(
) )
return err return err
} }
func (c *defaultClient) Health(ctx context.Context) (error) {
ctx, span := trace.StartSpan(ctx, "client/Health")
defer span.End()
err := c.do(ctx, "GET", "/health", nil, nil, nil)
return err
}

View File

@ -903,3 +903,19 @@ func TestRepoGC(t *testing.T) {
testClients(t, api, testF) testClients(t, api, testF)
} }
func TestHealth(t *testing.T) {
ctx := context.Background()
api := testAPI(t)
defer shutdown(api)
testF := func(t *testing.T, c Client) {
err := c.Health(ctx)
if err != nil {
t.Log(err)
t.Error("expected no errors")
}
}
testClients(t, api, testF)
}

View File

@ -204,6 +204,12 @@ func (api *API) routes(c *rpc.Client) []common.Route {
Pattern: "/token", Pattern: "/token",
HandlerFunc: api.GenerateTokenHandler, HandlerFunc: api.GenerateTokenHandler,
}, },
{
Name: "Health",
Method: "GET",
Pattern: "/health",
HandlerFunc: api.HealthHandler,
},
} }
} }

View File

@ -844,3 +844,20 @@ func TestAPIIPFSGCEndpoint(t *testing.T) {
test.BothEndpoints(t, tf) test.BothEndpoints(t, tf)
} }
func TestHealthEndpoint(t *testing.T) {
ctx := context.Background()
rest := testAPI(t)
defer rest.Shutdown(ctx)
tf := func(t *testing.T, url test.URLFunc) {
errResp := api.Error{}
test.MakeGet(t, rest, url(rest)+"/health", &errResp)
if errResp.Code != 0 || errResp.Message != "" {
t.Error("expected no errors")
}
}
test.BothEndpoints(t, tf)
}