Skip to content
This repository was archived by the owner on Dec 2, 2025. It is now read-only.

Commit 3847045

Browse files
authored
Merge pull request #72 from zongzw/zong-webhook-standalone
Reimplement webhook as a standalone program.
2 parents d7fb9e5 + 7fe0353 commit 3847045

File tree

5 files changed

+531
-28
lines changed

5 files changed

+531
-28
lines changed

cmd/webhook/main.go

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
Copyright 2023.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"flag"
21+
"fmt"
22+
"os"
23+
"strings"
24+
25+
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
26+
// to ensure that exec-entrypoint and run can make use of them.
27+
28+
"github.com/google/uuid"
29+
"github.com/prometheus/client_golang/prometheus"
30+
"github.com/prometheus/client_golang/prometheus/promhttp"
31+
_ "k8s.io/client-go/plugin/pkg/client/auth"
32+
33+
"k8s.io/apimachinery/pkg/runtime"
34+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
35+
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
36+
ctrl "sigs.k8s.io/controller-runtime"
37+
"sigs.k8s.io/controller-runtime/pkg/healthz"
38+
"sigs.k8s.io/controller-runtime/pkg/log/zap"
39+
"sigs.k8s.io/controller-runtime/pkg/manager"
40+
41+
// "github.com/f5devcentral/bigip-kubernetes-gateway/internal/pkg"
42+
"github.com/f5devcentral/bigip-kubernetes-gateway/internal/webhooks"
43+
f5_bigip "github.com/f5devcentral/f5-bigip-rest-go/bigip"
44+
"github.com/f5devcentral/f5-bigip-rest-go/utils"
45+
46+
//+kubebuilder:scaffold:imports
47+
48+
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
49+
)
50+
51+
var (
52+
scheme = runtime.NewScheme()
53+
setupLog = ctrl.Log.WithName("setup")
54+
stopCh = make(chan struct{})
55+
cmdflags = webhooks.CmdFlags{}
56+
)
57+
58+
func init() {
59+
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
60+
utilruntime.Must(gatewayv1beta1.AddToScheme(scheme))
61+
}
62+
63+
// 530 kubebuilder init --domain f5.com --repo f5.com/bigip-k8s-gateway
64+
// 531 kubebuilder create api --group gateways --version v1 --kind Adc
65+
66+
func main() {
67+
var (
68+
metricsAddr string
69+
enableLeaderElection bool
70+
probeAddr string
71+
controllerName string
72+
)
73+
74+
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
75+
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
76+
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
77+
"Enable leader election for controller manager. "+
78+
"Enabling this will ensure there is only one active controller manager.")
79+
80+
flag.StringVar(&cmdflags.CertDir, "certificate-directory", "/certificate-directory", "Directory that contains tls.crt and tls.key for webook https server.")
81+
flag.StringVar(&controllerName, "controller-name", "f5.io/gateway-controller-name", "This controller name.")
82+
flag.StringVar(&cmdflags.LogLevel, "log-level", utils.LogLevel_Type_INFO, "The log level, valid values: trace, debug, info, warn, error")
83+
flag.StringVar(&cmdflags.Validates, "validates", "", fmt.Sprintf("The items to validate synchronizingly, on operations "+
84+
"concating multiple values with ',', valid values: %s", strings.Join(webhooks.SupportedValidatingKeys(), ",")))
85+
86+
opts := zap.Options{
87+
Development: true,
88+
}
89+
opts.BindFlags(flag.CommandLine)
90+
flag.Parse()
91+
92+
if err := webhooks.ValidateGivenKeys(strings.Split(cmdflags.Validates, ",")); err != nil {
93+
setupLog.Error(err, "--validates fault")
94+
os.Exit(1)
95+
} else {
96+
webhooks.TurnOnValidatingFor(strings.Split(cmdflags.Validates, ","))
97+
}
98+
99+
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
100+
var err error
101+
webhooks.WebhookManager, err = ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
102+
Scheme: scheme,
103+
MetricsBindAddress: metricsAddr,
104+
Port: 9443,
105+
CertDir: cmdflags.CertDir,
106+
HealthProbeBindAddress: probeAddr,
107+
LeaderElection: enableLeaderElection,
108+
LeaderElectionID: "303cfed9.f5.com",
109+
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
110+
// when the Manager ends. This requires the binary to immediately end when the
111+
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
112+
// speeds up voluntary leader transitions as the new leader don't have to wait
113+
// LeaseDuration time first.
114+
//
115+
// In the default scaffold provided, the program ends immediately after
116+
// the manager stops, so would be fine to enable this option. However,
117+
// if you are doing or is intended to do any operation such as perform cleanups
118+
// after the manager stops then its usage might be unsafe.
119+
// LeaderElectionReleaseOnCancel: true,
120+
})
121+
if err != nil {
122+
setupLog.Error(err, "unable to start manager: "+err.Error())
123+
os.Exit(1)
124+
}
125+
126+
prometheus.MustRegister(utils.FunctionDurationTimeCostCount)
127+
prometheus.MustRegister(utils.FunctionDurationTimeCostTotal)
128+
prometheus.MustRegister(f5_bigip.BIGIPiControlTimeCostCount)
129+
prometheus.MustRegister(f5_bigip.BIGIPiControlTimeCostTotal)
130+
webhooks.WebhookManager.AddMetricsExtraHandler("/stats/", promhttp.Handler())
131+
setupWebhooks(webhooks.WebhookManager)
132+
133+
if err := webhooks.WebhookManager.AddHealthzCheck("healthz", healthz.Ping); err != nil {
134+
setupLog.Error(err, "unable to set up health check")
135+
os.Exit(1)
136+
}
137+
if err := webhooks.WebhookManager.AddReadyzCheck("readyz", healthz.Ping); err != nil {
138+
setupLog.Error(err, "unable to set up ready check")
139+
os.Exit(1)
140+
}
141+
142+
defer close(stopCh)
143+
setupLog.Info("starting manager")
144+
if err := webhooks.WebhookManager.Start(ctrl.SetupSignalHandler()); err != nil {
145+
setupLog.Error(err, "problem running manager")
146+
os.Exit(1)
147+
}
148+
}
149+
150+
func setupWebhooks(mgr manager.Manager) {
151+
slog := utils.NewLog().WithLevel(cmdflags.LogLevel).WithRequestID(uuid.NewString())
152+
153+
if err := (&webhooks.GatewayClassWebhook{Logger: slog}).
154+
SetupWebhookWithManager(mgr); err != nil {
155+
setupLog.Error(err, "unable to create webhook", "webhook", "gatewayclass")
156+
os.Exit(1)
157+
}
158+
159+
if err := (&webhooks.GatewayWebhook{
160+
Logger: slog,
161+
}).SetupWebhookWithManager(mgr); err != nil {
162+
setupLog.Error(err, "unable to create webhook", "webhook", "gateway")
163+
os.Exit(1)
164+
}
165+
166+
if err := (&webhooks.HTTPRouteWebhook{Logger: slog}).
167+
SetupWebhookWithManager(mgr); err != nil {
168+
setupLog.Error(err, "unable to create webhook", "webhook", "httproute")
169+
os.Exit(1)
170+
}
171+
172+
if err := (&webhooks.ReferenceGrantWebhook{Logger: slog}).
173+
SetupWebhookWithManager(mgr); err != nil {
174+
setupLog.Error(err, "unable to create webhook", "webhook", "referencegrant")
175+
os.Exit(1)
176+
}
177+
}

internal/webhooks/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package webhooks
2+
3+
type CmdFlags struct {
4+
CertDir string
5+
Validates string
6+
DeployMethod string
7+
LogLevel string
8+
}

internal/webhooks/vars.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package webhooks
2+
3+
import "sigs.k8s.io/controller-runtime/pkg/manager"
4+
5+
var (
6+
validateMap = map[string]bool{
7+
VK_gateway_gatewayClassName: false,
8+
VK_gateway_listeners_tls_certificateRefs: false,
9+
VK_httproute_parentRefs: false,
10+
VK_httproute_rules_backendRefs: false,
11+
}
12+
)
13+
14+
const (
15+
VK_gateway_gatewayClassName = "gateway.gatewayClassName"
16+
VK_gateway_listeners_tls_certificateRefs = "gateway.listeners.tls.certificateRefs"
17+
VK_httproute_parentRefs = "httproute.parentRefs"
18+
VK_httproute_rules_backendRefs = "httproute.rules.backendRefs"
19+
)
20+
21+
var (
22+
WebhookManager manager.Manager
23+
)

0 commit comments

Comments
 (0)