Skip to content

Commit

Permalink
Bugfix: Fix health and ready endpoint checker configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
fschade committed Oct 17, 2024
1 parent 08b3362 commit 7ad0afa
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 155 deletions.
13 changes: 13 additions & 0 deletions changelog/unreleased/fix-health-and-ready-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Bugfix: Fix health and ready endpoints

We added new checks to the `/readyz` and `/healthz` endpoints to ensure that the services are ready and healthy.
This change ensures that the endpoints return the correct status codes, which is needed to stabilize the k8s deployments.

https://github.com/owncloud/ocis/pull/10163
https://github.com/owncloud/ocis/pull/10301
https://github.com/owncloud/ocis/pull/10302
https://github.com/owncloud/ocis/pull/10303
https://github.com/owncloud/ocis/pull/10308
https://github.com/owncloud/ocis/pull/10323
https://github.com/owncloud/ocis/pull/10163
https://github.com/owncloud/ocis/issues/10316
20 changes: 2 additions & 18 deletions ocis-pkg/handlers/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,9 @@ import (
// check is a function that performs a check.
type checker func(ctx context.Context) error

// checks is a map of check names to check functions.
type checkers map[string]func(ctx context.Context) error

// CheckHandlerConfiguration defines the configuration for the CheckHandler.
type CheckHandlerConfiguration struct {
checks checkers
checks map[string]checker
logger log.Logger
limit int
statusFailed int
Expand All @@ -30,7 +27,7 @@ type CheckHandlerConfiguration struct {
// NewCheckHandlerConfiguration initializes a new CheckHandlerConfiguration.
func NewCheckHandlerConfiguration() CheckHandlerConfiguration {
return CheckHandlerConfiguration{
checks: make(checkers),
checks: make(map[string]checker),

limit: -1,
statusFailed: http.StatusInternalServerError,
Expand All @@ -56,15 +53,6 @@ func (c CheckHandlerConfiguration) WithCheck(name string, check checker) CheckHa
return c
}

// WithChecks adds multiple checks to the CheckHandlerConfiguration.
func (c CheckHandlerConfiguration) WithChecks(checks checkers) CheckHandlerConfiguration {
for name, check := range checks {
c.checks = c.WithCheck(name, check).checks
}

return c
}

// WithLimit limits the number of active goroutines for the checks to at most n
func (c CheckHandlerConfiguration) WithLimit(n int) CheckHandlerConfiguration {
c.limit = n
Expand Down Expand Up @@ -96,10 +84,6 @@ func NewCheckHandler(c CheckHandlerConfiguration) *CheckHandler {
}
}

func (h *CheckHandler) Checks() map[string]func(ctx context.Context) error {
return maps.Clone(h.conf.checks)
}

func (h *CheckHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
g, ctx := errgroup.WithContext(r.Context())
g.SetLimit(h.conf.limit)
Expand Down
18 changes: 9 additions & 9 deletions ocis-pkg/handlers/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,18 @@ import (
)

func TestCheckHandlerConfiguration(t *testing.T) {
nopCheck := func(_ context.Context) error { return nil }
nopCheckCounter := 0
nopCheck := func(_ context.Context) error { nopCheckCounter++; return nil }
handlerConfiguration := handlers.NewCheckHandlerConfiguration().WithCheck("check-1", nopCheck)

t.Run("add check", func(t *testing.T) {
inheritedHandlerConfiguration := handlerConfiguration.WithCheck("check-2", nopCheck)
require.Equal(t, 1, len(handlers.NewCheckHandler(handlerConfiguration).Checks()))
require.Equal(t, 2, len(handlers.NewCheckHandler(inheritedHandlerConfiguration).Checks()))
})
localCounter := 0
handlers.NewCheckHandler(handlerConfiguration).ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil))
require.Equal(t, 1, nopCheckCounter)

t.Run("add checks", func(t *testing.T) {
inheritedHandlerConfiguration := handlerConfiguration.WithChecks(map[string]func(ctx context.Context) error{"check-2": nopCheck, "check-3": nopCheck})
require.Equal(t, 1, len(handlers.NewCheckHandler(handlerConfiguration).Checks()))
require.Equal(t, 3, len(handlers.NewCheckHandler(inheritedHandlerConfiguration).Checks()))
handlers.NewCheckHandler(handlerConfiguration.WithCheck("check-2", func(_ context.Context) error { localCounter++; return nil })).ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil))
require.Equal(t, 2, nopCheckCounter)
require.Equal(t, 1, localCounter)
})

t.Run("checks are unique", func(t *testing.T) {
Expand All @@ -40,6 +39,7 @@ func TestCheckHandlerConfiguration(t *testing.T) {
}()

handlerConfiguration.WithCheck("check-1", nopCheck)
require.Equal(t, 3, nopCheckCounter)
})
}

Expand Down
18 changes: 14 additions & 4 deletions ocis-pkg/service/debug/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
graphMiddleware "github.com/owncloud/ocis/v2/services/graph/pkg/middleware"
)

var notImplementedEndpoint = func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }

// NewService initializes a new debug service.
func NewService(opts ...Option) *http.Server {
dopts := newOptions(opts...)
Expand All @@ -29,12 +31,20 @@ func NewService(opts ...Option) *http.Server {
promhttp.Handler(),
))

if dopts.Health != nil {
mux.Handle("/healthz", dopts.Health)
{ // healthiness check
var h http.Handler = http.HandlerFunc(notImplementedEndpoint)
if dopts.Health != nil {
h = dopts.Health
}
mux.Handle("/healthz", h)
}

if dopts.Ready != nil {
mux.Handle("/readyz", dopts.Ready)
{ // readiness check
var h http.Handler = http.HandlerFunc(notImplementedEndpoint)
if dopts.Ready != nil {
h = dopts.Ready
}
mux.Handle("/readyz", h)
}

if dopts.ConfigDump != nil {
Expand Down
20 changes: 7 additions & 13 deletions services/activitylog/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,12 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

healthHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("http reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
)
healthHandlerConfiguration := handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("http reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr))

readyHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
WithChecks(healthHandler.Checks()),
)
readyHandlerConfiguration := healthHandlerConfiguration.
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster))

return debug.NewService(
debug.Logger(options.Logger),
Expand All @@ -34,7 +28,7 @@ func Server(opts ...Option) (*http.Server, error) {
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(healthHandler),
debug.Ready(readyHandler),
debug.Health(handlers.NewCheckHandler(healthHandlerConfiguration)),
debug.Ready(handlers.NewCheckHandler(readyHandlerConfiguration)),
), nil
}
17 changes: 4 additions & 13 deletions services/audit/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,9 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

checkHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger),
)

readyHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
WithChecks(checkHandler.Checks()),
)
readyHandlerConfiguration := handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster))

return debug.NewService(
debug.Logger(options.Logger),
Expand All @@ -33,7 +25,6 @@ func Server(opts ...Option) (*http.Server, error) {
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(checkHandler),
debug.Ready(readyHandler),
debug.Ready(handlers.NewCheckHandler(readyHandlerConfiguration)),
), nil
}
17 changes: 4 additions & 13 deletions services/clientlog/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,9 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

checkHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger),
)

readyHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
WithChecks(checkHandler.Checks()),
)
readyHandlerConfiguration := handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster))

return debug.NewService(
debug.Logger(options.Logger),
Expand All @@ -33,7 +25,6 @@ func Server(opts ...Option) (*http.Server, error) {
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(checkHandler),
debug.Ready(readyHandler),
debug.Ready(handlers.NewCheckHandler(readyHandlerConfiguration)),
), nil
}
20 changes: 7 additions & 13 deletions services/eventhistory/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,12 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

checkHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("grpc reachability", checks.NewGRPCCheck(options.Config.GRPC.Addr)),
)
healthHandlerConfiguration := handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("grpc reachability", checks.NewGRPCCheck(options.Config.GRPC.Addr))

readyHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
WithChecks(checkHandler.Checks()),
)
readyHandlerConfiguration := healthHandlerConfiguration.
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster))

return debug.NewService(
debug.Logger(options.Logger),
Expand All @@ -34,7 +28,7 @@ func Server(opts ...Option) (*http.Server, error) {
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(checkHandler),
debug.Ready(readyHandler),
debug.Health(handlers.NewCheckHandler(healthHandlerConfiguration)),
debug.Ready(handlers.NewCheckHandler(readyHandlerConfiguration)),
), nil
}
20 changes: 7 additions & 13 deletions services/idp/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,12 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

healthHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("http reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr)),
)
healthHandlerConfiguration := handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("http reachability", checks.NewHTTPCheck(options.Config.HTTP.Addr))

readinessHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("ldap-check", checks.NewTCPCheck(options.Config.Ldap.URI)).
WithChecks(healthHandler.Checks()),
)
readyHandlerConfiguration := healthHandlerConfiguration.
WithCheck("ldap-check", checks.NewTCPCheck(options.Config.Ldap.URI))

return debug.NewService(
debug.Logger(options.Logger),
Expand All @@ -34,7 +28,7 @@ func Server(opts ...Option) (*http.Server, error) {
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(healthHandler),
debug.Ready(readinessHandler),
debug.Health(handlers.NewCheckHandler(healthHandlerConfiguration)),
debug.Ready(handlers.NewCheckHandler(readyHandlerConfiguration)),
), nil
}
19 changes: 5 additions & 14 deletions services/notifications/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,10 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

checkHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger),
)

readyHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Notifications.Events.Cluster)).
WithCheck("smtp-check", checks.NewTCPCheck(options.Config.Notifications.SMTP.Host+":"+strconv.Itoa(options.Config.Notifications.SMTP.Port))).
WithChecks(checkHandler.Checks()),
)
readyHandlerConfiguration := handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Notifications.Events.Cluster)).
WithCheck("smtp-check", checks.NewTCPCheck(options.Config.Notifications.SMTP.Host+":"+strconv.Itoa(options.Config.Notifications.SMTP.Port)))

return debug.NewService(
debug.Logger(options.Logger),
Expand All @@ -35,7 +27,6 @@ func Server(opts ...Option) (*http.Server, error) {
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(checkHandler),
debug.Ready(readyHandler),
debug.Ready(handlers.NewCheckHandler(readyHandlerConfiguration)),
), nil
}
32 changes: 13 additions & 19 deletions services/search/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,18 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

checkHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("grpc reachability", checks.NewGRPCCheck(options.Config.GRPC.Addr)),
)
healthHandlerConfiguration := handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("grpc reachability", checks.NewGRPCCheck(options.Config.GRPC.Addr))

readyHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
WithCheck("tika-check", func(ctx context.Context) error {
if options.Config.Extractor.Type == "tika" {
return checks.NewTCPCheck(options.Config.Extractor.Tika.TikaURL)(ctx)
}
return nil
}).
WithChecks(checkHandler.Checks()),
)
readyHandlerConfiguration := healthHandlerConfiguration.
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
WithCheck("tika-check", func(ctx context.Context) error {
if options.Config.Extractor.Type == "tika" {
return checks.NewTCPCheck(options.Config.Extractor.Tika.TikaURL)(ctx)
}
return nil
})

return debug.NewService(
debug.Logger(options.Logger),
Expand All @@ -41,7 +35,7 @@ func Server(opts ...Option) (*http.Server, error) {
debug.Token(options.Config.Debug.Token),
debug.Pprof(options.Config.Debug.Pprof),
debug.Zpages(options.Config.Debug.Zpages),
debug.Health(checkHandler),
debug.Ready(readyHandler),
debug.Health(handlers.NewCheckHandler(healthHandlerConfiguration)),
debug.Ready(handlers.NewCheckHandler(readyHandlerConfiguration)),
), nil
}
Loading

0 comments on commit 7ad0afa

Please sign in to comment.