Skip to content

Commit

Permalink
Merge pull request #1598 from sbueringer/pr-cherry-pick-enable-webhoo…
Browse files Browse the repository at this point in the history
…k-started-readiness-check

✨   make it possible to monitor if the webhook server has been started
  • Loading branch information
k8s-ci-robot committed Jul 20, 2021
2 parents 985e819 + 9bdc080 commit d5fde10
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
30 changes: 30 additions & 0 deletions pkg/webhook/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ import (
"path/filepath"
"strconv"
"sync"
"time"

"k8s.io/apimachinery/pkg/runtime"
kscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
"sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics"
)
Expand Down Expand Up @@ -87,6 +89,10 @@ type Server struct {
// defaultingOnce ensures that the default fields are only ever set once.
defaultingOnce sync.Once

// started is set to true immediately before the server is started
// and thus can be used to check if the server has been started
started bool

// mu protects access to the webhook map & setFields for Start, Register, etc
mu sync.Mutex
}
Expand Down Expand Up @@ -272,6 +278,9 @@ func (s *Server) Start(ctx context.Context) error {
close(idleConnsClosed)
}()

s.mu.Lock()
s.started = true
s.mu.Unlock()
if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
return err
}
Expand All @@ -280,6 +289,27 @@ func (s *Server) Start(ctx context.Context) error {
return nil
}

// StartedChecker returns an healthz.Checker which is healthy after the
// server has been started.
func (s *Server) StartedChecker() healthz.Checker {
return func(req *http.Request) error {
s.mu.Lock()
defer s.mu.Unlock()

if !s.started {
return fmt.Errorf("webhook server has not been started yet")
}

conn, err := net.DialTimeout("tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port)), 10*time.Second)
if err != nil {
return fmt.Errorf("webhook server is not reachable: %v", err)
}
conn.Close()

return nil
}
}

// InjectFunc injects the field setter into the server.
func (s *Server) InjectFunc(f inject.Func) error {
s.setFields = f
Expand Down
4 changes: 4 additions & 0 deletions pkg/webhook/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ var _ = Describe("Webhook Server", func() {
It("should serve a webhook on the requested path", func() {
server.Register("/somepath", &testHandler{})

Expect(server.StartedChecker()(nil)).ToNot(Succeed())

doneCh := startServer()

Eventually(func() ([]byte, error) {
Expand All @@ -137,6 +139,8 @@ var _ = Describe("Webhook Server", func() {
return ioutil.ReadAll(resp.Body)
}).Should(Equal([]byte("gadzooks!")))

Expect(server.StartedChecker()(nil)).To(Succeed())

ctxCancel()
Eventually(doneCh, "4s").Should(BeClosed())
})
Expand Down

0 comments on commit d5fde10

Please sign in to comment.