@@ -17,99 +17,83 @@ package main
1717
1818import (
1919 "context"
20- goflag "flag"
21- "net"
22- "net/http"
23- "os"
24- "strconv"
20+ "flag"
2521
26- flag "github.com/spf13/pflag"
2722 appsv1 "k8s.io/api/apps/v1"
2823 batchv1 "k8s.io/api/batch/v1"
2924 corev1 "k8s.io/api/core/v1"
3025 "k8s.io/apimachinery/pkg/runtime/schema"
31- "k8s.io/klog/v2"
32- ctrl "sigs.k8s.io/controller-runtime"
33- "sigs.k8s.io/controller-runtime/pkg/healthz"
34- "sigs.k8s.io/controller-runtime/pkg/log/zap"
35-
36- "github.com/sigstore/cosign/pkg/cosign/kubernetes/webhook"
26+ duckv1 "knative.dev/pkg/apis/duck/v1"
27+ "knative.dev/pkg/configmap"
28+ "knative.dev/pkg/controller"
29+ "knative.dev/pkg/injection/sharedmain"
30+ "knative.dev/pkg/signals"
31+ "knative.dev/pkg/webhook"
32+ "knative.dev/pkg/webhook/certificates"
33+ "knative.dev/pkg/webhook/resourcesemantics"
34+ "knative.dev/pkg/webhook/resourcesemantics/validation"
35+
36+ cwebhook "github.com/sigstore/cosign/pkg/cosign/kubernetes/webhook"
3737)
3838
39- func main () {
40- ctrl .SetLogger (zap .New (func (o * zap.Options ) {
41- o .Development = true
42- }))
43-
44- var (
45- metricsAddr = net .ParseIP ("127.0.0.1" )
46- metricsPort uint16 = 8080
39+ var secretName = flag .String ("secret-name" , "" , "The name of the secret in the webhook's namespace that holds the public key for verification." )
4740
48- bindAddr = net .ParseIP ("0.0.0.0" )
49- bindPort uint16 = 8443
41+ // webhookName holds the name of the validating webhook to set up with the
42+ // types we are watching. If this changes, you must also change:
43+ // ./config/500-webhook-configuration.yaml
44+ const webhookName = "cosigned.sigstore.dev"
5045
51- tlsCertDirectory string
52- secretKeyRef string
53- )
54-
55- klog .InitFlags (goflag .CommandLine )
56- flags := flag .NewFlagSet ("main" , flag .ExitOnError )
57- flags .AddGoFlagSet (goflag .CommandLine )
58- flags .StringVar (& secretKeyRef , "secret-key-ref" , "" , "The secret that includes pub/private key pair" )
59- flags .IPVar (& metricsAddr , "metrics-address" , metricsAddr , "The address the metric endpoint binds to." )
60- flags .Uint16Var (& metricsPort , "metrics-port" , metricsPort , "The port the metric endpoint binds to." )
61- flags .IPVar (& bindAddr , "bind-address" , bindAddr , "" +
62- "The IP address on which to listen for the --secure-port port." )
63- flags .Uint16Var (& bindPort , "secure-port" , bindPort , "The port on which to serve HTTPS." )
64- flags .StringVar (& tlsCertDirectory , "tls-cert-dir" , tlsCertDirectory , "The directory where the TLS certs are located." )
65-
66- err := flags .Parse (os .Args [1 :])
67- if err != nil {
68- klog .Error (err )
69- os .Exit (1 )
46+ func main () {
47+ opts := webhook.Options {
48+ ServiceName : "webhook" ,
49+ Port : 8443 ,
50+ SecretName : "webhook-certs" ,
7051 }
52+ ctx := webhook .WithOptions (signals .NewContext (), opts )
7153
72- cosignedValidationFuncs := map [schema.GroupVersionKind ]webhook.ValidationFunc {
73- corev1 .SchemeGroupVersion .WithKind ("Pod" ): webhook .ValidateSignedResources ,
74- batchv1 .SchemeGroupVersion .WithKind ("Job" ): webhook .ValidateSignedResources ,
75- appsv1 .SchemeGroupVersion .WithKind ("Deployment" ): webhook .ValidateSignedResources ,
76- appsv1 .SchemeGroupVersion .WithKind ("StatefulSet" ): webhook .ValidateSignedResources ,
77- appsv1 .SchemeGroupVersion .WithKind ("ReplicateSet" ): webhook .ValidateSignedResources ,
78- appsv1 .SchemeGroupVersion .WithKind ("DaemonSet" ): webhook .ValidateSignedResources ,
79- }
54+ // Allow folks to configure the port the webhook serves on.
55+ flag .IntVar (& opts .Port , "secure-port" , opts .Port , "The port on which to serve HTTPS." )
8056
81- cosignedValidationHook := webhook .NewFuncAdmissionValidator (webhook .Scheme , cosignedValidationFuncs , secretKeyRef )
57+ // This calls flag.Parse()
58+ sharedmain .MainWithContext (ctx , "cosigned" ,
59+ certificates .NewController ,
60+ NewValidatingAdmissionController ,
61+ )
62+ }
8263
83- opts := ctrl.Options {
84- Scheme : webhook .Scheme ,
85- MetricsBindAddress : net .JoinHostPort (metricsAddr .String (), strconv .Itoa (int (metricsPort ))),
86- Host : bindAddr .String (),
87- Port : int (bindPort ),
88- CertDir : tlsCertDirectory ,
89- }
64+ func NewValidatingAdmissionController (ctx context.Context , cmw configmap.Watcher ) * controller.Impl {
65+ validator := cwebhook .NewValidator (ctx , * secretName )
9066
91- mgr , err := ctrl .NewManager (ctrl .GetConfigOrDie (), opts )
92- if err != nil {
93- klog .Error (err , "Failed to create manager" )
94- os .Exit (1 )
95- }
67+ return validation .NewAdmissionController (ctx ,
68+ // Name of the resource webhook.
69+ webhookName ,
9670
97- // Get the controller manager webhook server .
98- webhookServer := mgr . GetWebhookServer ()
71+ // The path on which to serve the webhook .
72+ "/validations" ,
9973
100- // Register the webhooks in the server.
101- webhookServer .Register ("/validations" , cosignedValidationHook )
74+ // The resources to validate.
75+ map [schema.GroupVersionKind ]resourcesemantics.GenericCRD {
76+ corev1 .SchemeGroupVersion .WithKind ("Pod" ): & duckv1.Pod {},
10277
103- // Add healthz and readyz handlers to webhook server. The controller-runtime AddHealthzCheck/AddReadyzCheck methods
104- // are served via separate http server - better to serve these from the same webhook http server.
105- webhookServer .WebhookMux .Handle ("/readyz/" , http .StripPrefix ("/readyz/" , & healthz.Handler {}))
106- webhookServer .WebhookMux .Handle ("/healthz/" , http .StripPrefix ("/healthz/" , & healthz.Handler {}))
78+ appsv1 .SchemeGroupVersion .WithKind ("ReplicaSet" ): & duckv1.WithPod {},
79+ appsv1 .SchemeGroupVersion .WithKind ("Deployment" ): & duckv1.WithPod {},
80+ appsv1 .SchemeGroupVersion .WithKind ("StatefulSet" ): & duckv1.WithPod {},
81+ appsv1 .SchemeGroupVersion .WithKind ("DaemonSet" ): & duckv1.WithPod {},
82+ batchv1 .SchemeGroupVersion .WithKind ("Job" ): & duckv1.WithPod {},
83+ },
10784
108- klog .Info ("Starting the webhook..." )
85+ // A function that infuses the context passed to Validate/SetDefaults with custom metadata.
86+ func (ctx context.Context ) context.Context {
87+ ctx = duckv1 .WithPodValidator (ctx , validator .ValidatePod )
88+ ctx = duckv1 .WithPodSpecValidator (ctx , validator .ValidatePodSpecable )
89+ return ctx
90+ },
10991
110- // Start the server by starting a previously-set-up manager
111- if err := mgr .Start (context .Background ()); err != nil {
112- klog .Error (err )
113- os .Exit (1 )
114- }
92+ // Whether to disallow unknown fields.
93+ // We pass false because we're using partial schemas.
94+ false ,
95+
96+ // Extra validating callbacks to be applied to resources.
97+ nil ,
98+ )
11599}
0 commit comments