Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: Fix health and ready endpoint checker configurations #10333

Merged
merged 1 commit into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions changelog/unreleased/fix-health-and-ready-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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/pull/10333
https://github.com/owncloud/ocis/issues/10316
https://github.com/owncloud/ocis/issues/10281
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
25 changes: 18 additions & 7 deletions ocis-pkg/service/debug/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,26 @@ import (
"go.opentelemetry.io/contrib/zpages"

"github.com/owncloud/ocis/v2/ocis-pkg/cors"
"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/ocis-pkg/middleware"
graphMiddleware "github.com/owncloud/ocis/v2/services/graph/pkg/middleware"
)

var handleProbe = func(mux *http.ServeMux, pattern string, h http.Handler, name string, logger log.Logger) {
if h == nil {
h = handlers.NewCheckHandler(handlers.NewCheckHandlerConfiguration())
logger.Info().
Str("service", name).
Str("endpoint", pattern).
Msg("no probe provided, reverting to default (OK)")
}

mux.Handle(pattern, h)
}

//var probeHandler = 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,13 +45,8 @@ func NewService(opts ...Option) *http.Server {
promhttp.Handler(),
))

if dopts.Health != nil {
mux.Handle("/healthz", dopts.Health)
}

if dopts.Ready != nil {
mux.Handle("/readyz", dopts.Ready)
}
handleProbe(mux, "/healthz", dopts.Health, dopts.Name, dopts.Logger) // healthiness check
handleProbe(mux, "/readyz", dopts.Ready, dopts.Name, dopts.Logger) // readiness check

if dopts.ConfigDump != nil {
mux.Handle("/config", dopts.ConfigDump)
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
}
39 changes: 16 additions & 23 deletions services/antivirus/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,21 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

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

readyHandler := handlers.NewCheckHandler(
handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
WithCheck("antivirus reachability", func(ctx context.Context) error {
cfg := options.Config
switch cfg.Scanner.Type {
default:
return errors.New("no antivirus configured")
case "clamav":
return clamd.NewClamd(cfg.Scanner.ClamAV.Socket).Ping()
case "icap":
return checks.NewTCPCheck(cfg.Scanner.ICAP.URL)(ctx)
}
}),
)
readyHandlerConfiguration := handlers.NewCheckHandlerConfiguration().
WithLogger(options.Logger).
WithLogger(options.Logger).
WithCheck("nats reachability", checks.NewNatsCheck(options.Config.Events.Cluster)).
WithCheck("antivirus reachability", func(ctx context.Context) error {
cfg := options.Config
switch cfg.Scanner.Type {
default:
return errors.New("no antivirus configured")
case "clamav":
return clamd.NewClamd(cfg.Scanner.ClamAV.Socket).Ping()
case "icap":
return checks.NewTCPCheck(cfg.Scanner.ICAP.URL)(ctx)
}
})

return debug.NewService(
debug.Logger(options.Logger),
Expand All @@ -47,7 +41,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(healthHandler),
debug.Ready(readyHandler),
debug.Ready(handlers.NewCheckHandler(readyHandlerConfiguration)),
), nil
}
8 changes: 0 additions & 8 deletions services/app-provider/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package debug
import (
"net/http"

"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
)
Expand All @@ -12,11 +11,6 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

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

return debug.NewService(
debug.Logger(options.Logger),
debug.Name(options.Config.Service.Name),
Expand All @@ -25,8 +19,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(checkHandler),
//debug.CorsAllowedOrigins(options.Config.HTTP.CORS.AllowedOrigins),
//debug.CorsAllowedMethods(options.Config.HTTP.CORS.AllowedMethods),
//debug.CorsAllowedHeaders(options.Config.HTTP.CORS.AllowedHeaders),
Expand Down
8 changes: 0 additions & 8 deletions services/app-registry/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package debug
import (
"net/http"

"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
)
Expand All @@ -12,11 +11,6 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

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

return debug.NewService(
debug.Logger(options.Logger),
debug.Name(options.Config.Service.Name),
Expand All @@ -25,8 +19,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(checkHandler),
//debug.CorsAllowedOrigins(options.Config.HTTP.CORS.AllowedOrigins),
//debug.CorsAllowedMethods(options.Config.HTTP.CORS.AllowedMethods),
//debug.CorsAllowedHeaders(options.Config.HTTP.CORS.AllowedHeaders),
Expand Down
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
}
8 changes: 0 additions & 8 deletions services/auth-app/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package debug
import (
"net/http"

"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
)
Expand All @@ -12,11 +11,6 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

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

return debug.NewService(
debug.Logger(options.Logger),
debug.Name(options.Config.Service.Name),
Expand All @@ -25,8 +19,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(checkHandler),
//debug.CorsAllowedOrigins(options.Config.HTTP.CORS.AllowedOrigins),
//debug.CorsAllowedMethods(options.Config.HTTP.CORS.AllowedMethods),
//debug.CorsAllowedHeaders(options.Config.HTTP.CORS.AllowedHeaders),
Expand Down
8 changes: 0 additions & 8 deletions services/auth-basic/pkg/server/debug/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package debug
import (
"net/http"

"github.com/owncloud/ocis/v2/ocis-pkg/handlers"
"github.com/owncloud/ocis/v2/ocis-pkg/service/debug"
"github.com/owncloud/ocis/v2/ocis-pkg/version"
)
Expand All @@ -12,11 +11,6 @@ import (
func Server(opts ...Option) (*http.Server, error) {
options := newOptions(opts...)

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

return debug.NewService(
debug.Logger(options.Logger),
debug.Name(options.Config.Service.Name),
Expand All @@ -25,8 +19,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(checkHandler),
//debug.CorsAllowedOrigins(options.Config.HTTP.CORS.AllowedOrigins),
//debug.CorsAllowedMethods(options.Config.HTTP.CORS.AllowedMethods),
//debug.CorsAllowedHeaders(options.Config.HTTP.CORS.AllowedHeaders),
Expand Down
Loading