Skip to content

Commit c0b0ac5

Browse files
committed
Add webhook singleton command
Signed-off-by: Jian Qiu <[email protected]>
1 parent d9fea16 commit c0b0ac5

File tree

10 files changed

+210
-163
lines changed

10 files changed

+210
-163
lines changed

cmd/registration-operator/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func newNucleusCommand() *cobra.Command {
4848

4949
cmd.AddCommand(hub.NewHubOperatorCmd())
5050
cmd.AddCommand(hub.NewHubManagerCmd())
51+
cmd.AddCommand(hub.NewWebhookCmd())
5152
cmd.AddCommand(spoke.NewKlusterletOperatorCmd())
5253
cmd.AddCommand(spoke.NewKlusterletAgentCmd())
5354

pkg/cmd/hub/operator.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/spf13/cobra"
77
"k8s.io/utils/clock"
8+
ctrl "sigs.k8s.io/controller-runtime"
89

910
commonoptions "open-cluster-management.io/ocm/pkg/common/options"
1011
"open-cluster-management.io/ocm/pkg/operator/operators/clustermanager"
@@ -47,3 +48,24 @@ func NewHubManagerCmd() *cobra.Command {
4748
opts.AddFlags(flags)
4849
return cmd
4950
}
51+
52+
func NewWebhookCmd() *cobra.Command {
53+
webhookOptions := commonoptions.NewWebhookOptions()
54+
opts := hub.NewWebhookOptions()
55+
cmd := &cobra.Command{
56+
Use: "webhook-server",
57+
Short: "Start the registration webhook server",
58+
RunE: func(c *cobra.Command, args []string) error {
59+
if err := opts.SetupWebhookServer(webhookOptions); err != nil {
60+
return err
61+
}
62+
return webhookOptions.RunWebhookServer(ctrl.SetupSignalHandler())
63+
},
64+
}
65+
66+
flags := cmd.Flags()
67+
opts.AddFlags(flags)
68+
webhookOptions.AddFlags(flags)
69+
70+
return cmd
71+
}

pkg/cmd/webhook/registration.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,29 @@ package webhook
22

33
import (
44
"github.com/spf13/cobra"
5+
ctrl "sigs.k8s.io/controller-runtime"
56

7+
commonoptions "open-cluster-management.io/ocm/pkg/common/options"
68
"open-cluster-management.io/ocm/pkg/registration/webhook"
79
)
810

911
func NewRegistrationWebhook() *cobra.Command {
10-
ops := webhook.NewOptions()
12+
webhookOptions := commonoptions.NewWebhookOptions()
13+
opts := webhook.NewOptions()
1114
cmd := &cobra.Command{
1215
Use: "webhook-server",
1316
Short: "Start the registration webhook server",
1417
RunE: func(c *cobra.Command, args []string) error {
15-
err := ops.RunWebhookServer()
16-
return err
18+
if err := opts.SetupWebhookServer(webhookOptions); err != nil {
19+
return err
20+
}
21+
return webhookOptions.RunWebhookServer(ctrl.SetupSignalHandler())
1722
},
1823
}
1924

2025
flags := cmd.Flags()
21-
ops.AddFlags(flags)
26+
opts.AddFlags(flags)
27+
webhookOptions.AddFlags(flags)
2228

2329
return cmd
2430
}

pkg/cmd/webhook/work.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,30 @@ package webhook
22

33
import (
44
"github.com/spf13/cobra"
5+
ctrl "sigs.k8s.io/controller-runtime"
56

7+
commonoptions "open-cluster-management.io/ocm/pkg/common/options"
68
_ "open-cluster-management.io/ocm/pkg/features"
79
"open-cluster-management.io/ocm/pkg/work/webhook"
810
)
911

1012
func NewWorkWebhook() *cobra.Command {
13+
webhookOptions := commonoptions.NewWebhookOptions()
1114
ops := webhook.NewOptions()
1215
cmd := &cobra.Command{
1316
Use: "webhook-server",
1417
Short: "Start the work webhook server",
1518
RunE: func(c *cobra.Command, args []string) error {
16-
err := ops.RunWebhookServer()
17-
return err
19+
if err := ops.SetupWebhookServer(webhookOptions); err != nil {
20+
return err
21+
}
22+
return webhookOptions.RunWebhookServer(ctrl.SetupSignalHandler())
1823
},
1924
}
2025

2126
flags := cmd.Flags()
2227
ops.AddFlags(flags)
28+
webhookOptions.AddFlags(flags)
2329

2430
return cmd
2531
}

pkg/common/options/webhook.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package options
2+
3+
import (
4+
"context"
5+
"crypto/tls"
6+
7+
"github.com/spf13/pflag"
8+
"k8s.io/apimachinery/pkg/runtime"
9+
_ "k8s.io/client-go/plugin/pkg/client/auth" // Import all auth plugins (e.g. Azure, GCP, OIDC, etc.) to ensure exec-entrypoint and run can make use of them.
10+
"k8s.io/klog/v2"
11+
ctrl "sigs.k8s.io/controller-runtime"
12+
"sigs.k8s.io/controller-runtime/pkg/healthz"
13+
"sigs.k8s.io/controller-runtime/pkg/webhook"
14+
)
15+
16+
type WebhookOptions struct {
17+
Port int
18+
CertDir string
19+
scheme *runtime.Scheme
20+
webhooks []WebhookInitializer
21+
}
22+
23+
func NewWebhookOptions() *WebhookOptions {
24+
return &WebhookOptions{
25+
Port: 9443,
26+
scheme: runtime.NewScheme(),
27+
}
28+
}
29+
30+
func (c *WebhookOptions) AddFlags(fs *pflag.FlagSet) {
31+
fs.IntVar(&c.Port, "port", c.Port,
32+
"Port is the port that the webhook server serves at.")
33+
fs.StringVar(&c.CertDir, "certdir", c.CertDir,
34+
"CertDir is the directory that contains the server key and certificate. If not set, "+
35+
"webhook server would look up the server key and certificate in {TempDir}/k8s-webhook-server/serving-certs")
36+
}
37+
38+
type WebhookInitializer interface {
39+
Init(mgr ctrl.Manager) error
40+
}
41+
42+
func (c *WebhookOptions) InstallWebhook(webhooks ...WebhookInitializer) {
43+
c.webhooks = append(c.webhooks, webhooks...)
44+
}
45+
46+
func (c *WebhookOptions) InstallScheme(fns ...func(s *runtime.Scheme) error) error {
47+
for _, f := range fns {
48+
if err := f(c.scheme); err != nil {
49+
return err
50+
}
51+
}
52+
return nil
53+
}
54+
55+
func (c *WebhookOptions) RunWebhookServer(ctx context.Context) error {
56+
logger := klog.LoggerWithName(klog.FromContext(ctx), "Webhook Server")
57+
// This line prevents controller-runtime from complaining about log.SetLogger never being called
58+
ctrl.SetLogger(logger)
59+
60+
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
61+
Scheme: c.scheme,
62+
HealthProbeBindAddress: ":8000",
63+
WebhookServer: webhook.NewServer(webhook.Options{
64+
Port: c.Port,
65+
CertDir: c.CertDir,
66+
TLSOpts: []func(config *tls.Config){
67+
func(config *tls.Config) {
68+
config.MinVersion = tls.VersionTLS12
69+
},
70+
},
71+
}),
72+
})
73+
if err != nil {
74+
logger.Error(err, "unable to start manager")
75+
return err
76+
}
77+
78+
// add healthz/readyz check handler
79+
if err := mgr.AddHealthzCheck("healthz-ping", healthz.Ping); err != nil {
80+
logger.Error(err, "unable to add healthz check handler")
81+
return err
82+
}
83+
84+
if err := mgr.AddReadyzCheck("readyz-ping", healthz.Ping); err != nil {
85+
logger.Error(err, "unable to add readyz check handler")
86+
return err
87+
}
88+
89+
for _, webhookInitializer := range c.webhooks {
90+
if err := webhookInitializer.Init(mgr); err != nil {
91+
logger.Error(err, "unable to initilize webhook server")
92+
return err
93+
}
94+
}
95+
96+
logger.Info("starting manager")
97+
if err := mgr.Start(ctx); err != nil {
98+
logger.Error(err, "problem running manager")
99+
return err
100+
}
101+
return nil
102+
}

pkg/registration/webhook/option.go

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,15 @@
11
package webhook
22

3-
import "github.com/spf13/pflag"
3+
import (
4+
"github.com/spf13/pflag"
5+
)
46

57
// Config contains the server (the webhook) cert and key.
6-
type Options struct {
7-
Port int
8-
CertDir string
9-
}
8+
type Options struct{}
109

1110
// NewOptions constructs a new set of default options for webhook.
1211
func NewOptions() *Options {
13-
return &Options{
14-
Port: 9443,
15-
}
12+
return &Options{}
1613
}
1714

18-
func (c *Options) AddFlags(fs *pflag.FlagSet) {
19-
fs.IntVar(&c.Port, "port", c.Port,
20-
"Port is the port that the webhook server serves at.")
21-
fs.StringVar(&c.CertDir, "certdir", c.CertDir,
22-
"CertDir is the directory that contains the server key and certificate. If not set, "+
23-
"webhook server would look up the server key and certificate in {TempDir}/k8s-webhook-server/serving-certs")
24-
}
15+
func (c *Options) AddFlags(_ *pflag.FlagSet) {}

pkg/registration/webhook/start.go

Lines changed: 10 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,26 @@
11
package webhook
22

33
import (
4-
"context"
5-
"crypto/tls"
6-
7-
"k8s.io/apimachinery/pkg/runtime"
8-
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
94
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
10-
_ "k8s.io/client-go/plugin/pkg/client/auth" // Import all auth plugins (e.g. Azure, GCP, OIDC, etc.) to ensure exec-entrypoint and run can make use of them.
11-
"k8s.io/klog/v2"
12-
ctrl "sigs.k8s.io/controller-runtime"
13-
"sigs.k8s.io/controller-runtime/pkg/healthz"
14-
"sigs.k8s.io/controller-runtime/pkg/webhook"
155

166
clusterv1 "open-cluster-management.io/api/cluster/v1"
177

8+
commonoptions "open-cluster-management.io/ocm/pkg/common/options"
189
internalv1 "open-cluster-management.io/ocm/pkg/registration/webhook/v1"
1910
internalv1beta2 "open-cluster-management.io/ocm/pkg/registration/webhook/v1beta2"
2011
)
2112

22-
var (
23-
scheme = runtime.NewScheme()
24-
)
25-
26-
func init() {
27-
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
28-
utilruntime.Must(clusterv1.Install(scheme))
29-
utilruntime.Must(internalv1beta2.Install(scheme))
30-
}
31-
32-
func (c *Options) RunWebhookServer() error {
33-
logger := klog.LoggerWithName(klog.FromContext(context.Background()), "Webhook Server")
34-
// This line prevents controller-runtime from complaining about log.SetLogger never being called
35-
ctrl.SetLogger(logger)
36-
37-
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
38-
Scheme: scheme,
39-
HealthProbeBindAddress: ":8000",
40-
WebhookServer: webhook.NewServer(webhook.Options{
41-
Port: c.Port,
42-
CertDir: c.CertDir,
43-
TLSOpts: []func(config *tls.Config){
44-
func(config *tls.Config) {
45-
config.MinVersion = tls.VersionTLS12
46-
},
47-
},
48-
}),
49-
})
50-
if err != nil {
51-
logger.Error(err, "unable to start manager")
13+
func (c *Options) SetupWebhookServer(opts *commonoptions.WebhookOptions) error {
14+
if err := opts.InstallScheme(
15+
clientgoscheme.AddToScheme,
16+
clusterv1.Install,
17+
internalv1beta2.Install,
18+
); err != nil {
5219
return err
5320
}
21+
opts.InstallWebhook(
22+
&internalv1.ManagedClusterWebhook{},
23+
&internalv1beta2.ManagedClusterSetBindingWebhook{})
5424

55-
// add healthz/readyz check handler
56-
if err := mgr.AddHealthzCheck("healthz-ping", healthz.Ping); err != nil {
57-
logger.Error(err, "unable to add healthz check handler")
58-
return err
59-
}
60-
61-
if err := mgr.AddReadyzCheck("readyz-ping", healthz.Ping); err != nil {
62-
logger.Error(err, "unable to add readyz check handler")
63-
return err
64-
}
65-
66-
if err = (&internalv1.ManagedClusterWebhook{}).Init(mgr); err != nil {
67-
logger.Error(err, "unable to create ManagedCluster webhook")
68-
return err
69-
}
70-
if err = (&internalv1beta2.ManagedClusterSetBindingWebhook{}).Init(mgr); err != nil {
71-
logger.Error(err, "unable to create ManagedClusterSetBinding webhook", "version", "v1beta2")
72-
return err
73-
}
74-
75-
logger.Info("starting manager")
76-
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
77-
logger.Error(err, "problem running manager")
78-
return err
79-
}
8025
return nil
8126
}

pkg/singleton/hub/webhook.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package hub
2+
3+
import (
4+
"github.com/spf13/pflag"
5+
6+
commonoptions "open-cluster-management.io/ocm/pkg/common/options"
7+
registrationwebhook "open-cluster-management.io/ocm/pkg/registration/webhook"
8+
workwebhook "open-cluster-management.io/ocm/pkg/work/webhook"
9+
)
10+
11+
// Config contains the server (the webhook) cert and key.
12+
type WebhookOptions struct {
13+
registrationWebhookOptions *registrationwebhook.Options
14+
workWebhookOptions *workwebhook.Options
15+
}
16+
17+
// NewWebhookOptions constructs a new set of default options for webhook.
18+
func NewWebhookOptions() *WebhookOptions {
19+
return &WebhookOptions{
20+
registrationWebhookOptions: registrationwebhook.NewOptions(),
21+
workWebhookOptions: workwebhook.NewOptions(),
22+
}
23+
}
24+
25+
func (c *WebhookOptions) AddFlags(fs *pflag.FlagSet) {
26+
c.workWebhookOptions.AddFlags(fs)
27+
c.registrationWebhookOptions.AddFlags(fs)
28+
}
29+
30+
func (c *WebhookOptions) SetupWebhookServer(opts *commonoptions.WebhookOptions) error {
31+
if err := c.registrationWebhookOptions.SetupWebhookServer(opts); err != nil {
32+
return err
33+
}
34+
if err := c.workWebhookOptions.SetupWebhookServer(opts); err != nil {
35+
return err
36+
}
37+
38+
return nil
39+
}

0 commit comments

Comments
 (0)