update vendor

Signed-off-by: Roland.Ma <rolandma@yunify.com>
This commit is contained in:
Roland.Ma
2021-08-11 07:10:14 +00:00
parent a18f72b565
commit ea8f47c73a
2901 changed files with 269317 additions and 43103 deletions

View File

@@ -28,26 +28,34 @@ import (
"path/filepath"
"strconv"
"sync"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"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/certwatcher"
"sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics"
)
// DefaultPort is the default port that the webhook server serves.
var DefaultPort = 443
var DefaultPort = 9443
// Server is an admission webhook server that can serve traffic and
// generates related k8s resources for deploying.
//
// TLS is required for a webhook to be accessed by kubernetes, so
// you must provide a CertName and KeyName or have valid cert/key
// at the default locations (tls.crt and tls.key). If you do not
// want to configure TLS (i.e for testing purposes) run an
// admission.StandaloneWebhook in your own server.
type Server struct {
// Host is the address that the server will listen on.
// Defaults to "" - all addresses.
Host string
// Port is the port number that the server will serve.
// It will be defaulted to 443 if unspecified.
// It will be defaulted to 9443 if unspecified.
Port int
// CertDir is the directory that contains the server key and certificate. The
@@ -64,6 +72,10 @@ type Server struct {
// Defaults to "", which means server does not verify client's certificate.
ClientCAName string
// TLSVersion is the minimum version of TLS supported. Accepts
// "", "1.0", "1.1", "1.2" and "1.3" only ("" is equivalent to "1.0" for backwards compatibility)
TLSMinVersion string
// WebhookMux is the multiplexer that handles different webhooks.
WebhookMux *http.ServeMux
@@ -77,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
}
@@ -118,13 +134,12 @@ func (s *Server) Register(path string, hook http.Handler) {
defer s.mu.Unlock()
s.defaultingOnce.Do(s.setDefaults)
_, found := s.webhooks[path]
if found {
if _, found := s.webhooks[path]; found {
panic(fmt.Errorf("can't register duplicate path: %v", path))
}
// TODO(directxman12): call setfields if we've already started the server
s.webhooks[path] = hook
s.WebhookMux.Handle(path, instrumentedHook(path, hook))
s.WebhookMux.Handle(path, metrics.InstrumentedHook(path, hook))
regLog := log.WithValues("path", path)
regLog.Info("registering webhook")
@@ -149,30 +164,49 @@ func (s *Server) Register(path string, hook http.Handler) {
}
}
// instrumentedHook adds some instrumentation on top of the given webhook.
func instrumentedHook(path string, hookRaw http.Handler) http.Handler {
lbl := prometheus.Labels{"webhook": path}
// StartStandalone runs a webhook server without
// a controller manager.
func (s *Server) StartStandalone(ctx context.Context, scheme *runtime.Scheme) error {
// Use the Kubernetes client-go scheme if none is specified
if scheme == nil {
scheme = kscheme.Scheme
}
lat := metrics.RequestLatency.MustCurryWith(lbl)
cnt := metrics.RequestTotal.MustCurryWith(lbl)
gge := metrics.RequestInFlight.With(lbl)
if err := s.InjectFunc(func(i interface{}) error {
if _, err := inject.SchemeInto(scheme, i); err != nil {
return err
}
return nil
}); err != nil {
return err
}
// Initialize the most likely HTTP status codes.
cnt.WithLabelValues("200")
cnt.WithLabelValues("500")
return s.Start(ctx)
}
return promhttp.InstrumentHandlerDuration(
lat,
promhttp.InstrumentHandlerCounter(
cnt,
promhttp.InstrumentHandlerInFlight(gge, hookRaw),
),
)
// tlsVersion converts from human-readable TLS version (for example "1.1")
// to the values accepted by tls.Config (for example 0x301).
func tlsVersion(version string) (uint16, error) {
switch version {
// default is previous behaviour
case "":
return tls.VersionTLS10, nil
case "1.0":
return tls.VersionTLS10, nil
case "1.1":
return tls.VersionTLS11, nil
case "1.2":
return tls.VersionTLS12, nil
case "1.3":
return tls.VersionTLS13, nil
default:
return 0, fmt.Errorf("invalid TLSMinVersion %v: expects 1.0, 1.1, 1.2, 1.3 or empty", version)
}
}
// Start runs the server.
// It will install the webhook related resources depend on the server configuration.
func (s *Server) Start(stop <-chan struct{}) error {
func (s *Server) Start(ctx context.Context) error {
s.defaultingOnce.Do(s.setDefaults)
baseHookLog := log.WithName("webhooks")
@@ -187,14 +221,20 @@ func (s *Server) Start(stop <-chan struct{}) error {
}
go func() {
if err := certWatcher.Start(stop); err != nil {
if err := certWatcher.Start(ctx); err != nil {
log.Error(err, "certificate watcher error")
}
}()
cfg := &tls.Config{
tlsMinVersion, err := tlsVersion(s.TLSMinVersion)
if err != nil {
return err
}
cfg := &tls.Config{ //nolint:gosec
NextProtos: []string{"h2"},
GetCertificate: certWatcher.GetCertificate,
MinVersion: tlsMinVersion,
}
// load CA to verify client certificate
@@ -214,7 +254,7 @@ func (s *Server) Start(stop <-chan struct{}) error {
cfg.ClientAuth = tls.RequireAndVerifyClientCert
}
listener, err := tls.Listen("tcp", net.JoinHostPort(s.Host, strconv.Itoa(int(s.Port))), cfg)
listener, err := tls.Listen("tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port)), cfg)
if err != nil {
return err
}
@@ -227,7 +267,7 @@ func (s *Server) Start(stop <-chan struct{}) error {
idleConnsClosed := make(chan struct{})
go func() {
<-stop
<-ctx.Done()
log.Info("shutting down webhook server")
// TODO: use a context with reasonable timeout
@@ -238,8 +278,10 @@ func (s *Server) Start(stop <-chan struct{}) error {
close(idleConnsClosed)
}()
err = srv.Serve(listener)
if err != nil && err != http.ErrServerClosed {
s.mu.Lock()
s.started = true
s.mu.Unlock()
if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
return err
}
@@ -247,6 +289,27 @@ func (s *Server) Start(stop <-chan struct{}) 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