1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00
kyverno/cmd/cleanup-controller/server.go

134 lines
3.7 KiB
Go
Raw Normal View History

package main
import (
"context"
"crypto/tls"
"net/http"
"time"
"github.com/go-logr/logr"
"github.com/julienschmidt/httprouter"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/controllers/cleanup"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/webhooks"
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
admissionv1 "k8s.io/api/admission/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
)
type Server interface {
// Run TLS server in separate thread and returns control immediately
Run(<-chan struct{})
// Stop TLS server and returns control after the server is shut down
Stop(context.Context)
}
type server struct {
server *http.Server
}
type (
TlsProvider = func() ([]byte, []byte, error)
ValidationHandler = func(context.Context, logr.Logger, *admissionv1.AdmissionRequest, time.Time) *admissionv1.AdmissionResponse
CleanupHandler = func(context.Context, logr.Logger, string, time.Time, config.Configuration) error
)
type Probes interface {
IsReady() bool
IsLive() bool
}
// NewServer creates new instance of server accordingly to given configuration
func NewServer(
tlsProvider TlsProvider,
validationHandler ValidationHandler,
cleanupHandler CleanupHandler,
metricsConfig metrics.MetricsConfigManager,
debugModeOpts webhooks.DebugModeOptions,
probes Probes,
cfg config.Configuration,
) Server {
policyLogger := logging.WithName("cleanup-policy")
cleanupLogger := logging.WithName("cleanup")
cleanupHandlerFunc := func(w http.ResponseWriter, r *http.Request) {
policy := r.URL.Query().Get("policy")
logger := cleanupLogger.WithValues("policy", policy)
err := cleanupHandler(r.Context(), logger, policy, time.Now(), cfg)
if err == nil {
w.WriteHeader(http.StatusOK)
} else {
if apierrors.IsNotFound(err) {
w.WriteHeader(http.StatusNotFound)
} else {
w.WriteHeader(http.StatusInternalServerError)
}
}
}
mux := httprouter.New()
mux.HandlerFunc(
"POST",
config.CleanupValidatingWebhookServicePath,
handlers.FromAdmissionFunc("VALIDATE", validationHandler).
WithDump(debugModeOpts.DumpPayload).
WithSubResourceFilter().
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookValidating).
WithAdmission(policyLogger.WithName("validate")).
ToHandlerFunc(),
)
mux.HandlerFunc(
"GET",
cleanup.CleanupServicePath,
handlers.HttpHandler(cleanupHandlerFunc).
WithMetrics(policyLogger).
WithTrace("CLEANUP").
ToHandlerFunc(),
)
mux.HandlerFunc("GET", config.LivenessServicePath, handlers.Probe(probes.IsLive))
mux.HandlerFunc("GET", config.ReadinessServicePath, handlers.Probe(probes.IsReady))
return &server{
server: &http.Server{
Addr: ":9443",
TLSConfig: &tls.Config{
GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
certPem, keyPem, err := tlsProvider()
if err != nil {
return nil, err
}
pair, err := tls.X509KeyPair(certPem, keyPem)
if err != nil {
return nil, err
}
return &pair, nil
},
MinVersion: tls.VersionTLS12,
},
Handler: mux,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
ReadHeaderTimeout: 30 * time.Second,
IdleTimeout: 5 * time.Minute,
ErrorLog: logging.StdLogger(logging.WithName("server"), ""),
},
}
}
func (s *server) Run(stopCh <-chan struct{}) {
go func() {
if err := s.server.ListenAndServeTLS("", ""); err != nil {
logging.Error(err, "failed to start server")
}
}()
}
func (s *server) Stop(ctx context.Context) {
err := s.server.Shutdown(ctx)
if err != nil {
err = s.server.Close()
if err != nil {
logging.Error(err, "failed to start server")
}
}
}