Skip to content

Commit 5dd4321

Browse files
webhook: add conversion webhook for cephconnection
Signed-off-by: Niraj Yadav <niryadav@redhat.com>
1 parent ec0f8c6 commit 5dd4321

27 files changed

+523
-7
lines changed

PROJECT

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,9 @@ resources:
6060
kind: CephConnection
6161
path: github.com/ceph/ceph-csi-operator/api/csi/v1beta1
6262
version: v1beta1
63+
webhooks:
64+
conversion: true
65+
spoke:
66+
- v1alpha1
67+
webhookVersion: v1
6368
version: "3"
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
Copyright 2024.
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 v1alpha1
18+
19+
import (
20+
"errors"
21+
"log"
22+
23+
"sigs.k8s.io/controller-runtime/pkg/conversion"
24+
25+
csiv1beta1 "github.com/ceph/ceph-csi-operator/api/csi/v1beta1"
26+
)
27+
28+
// ConvertTo converts this CephConnection (v1alpha1) to the Hub version (v1beta1).
29+
func (src *CephConnection) ConvertTo(dstRaw conversion.Hub) error {
30+
dst, ok := dstRaw.(*csiv1beta1.CephConnection)
31+
if !ok {
32+
return errors.New("convertto: failed to cast to v1beta1 CephConnection")
33+
}
34+
35+
log.Printf("ConvertTo: Converting CephConnection from Spoke version v1alpha1 to Hub version v1beta1;"+
36+
"source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name)
37+
38+
dst.ObjectMeta = src.ObjectMeta
39+
40+
dst.Spec.Monitors = src.Spec.Monitors
41+
dst.Spec.RbdMirrorDaemonCount = src.Spec.RbdMirrorDaemonCount
42+
dst.Spec.ReadAffinity = (*csiv1beta1.ReadAffinitySpec)(src.Spec.ReadAffinity)
43+
44+
return nil
45+
}
46+
47+
// ConvertFrom converts the Hub version (v1beta1) to this CephConnection (v1alpha1).
48+
func (dst *CephConnection) ConvertFrom(srcRaw conversion.Hub) error {
49+
src, ok := srcRaw.(*csiv1beta1.CephConnection)
50+
if !ok {
51+
return errors.New("convertfrom: failed to cast to v1beta1 CephConnection")
52+
53+
}
54+
55+
log.Printf("ConvertFrom: Converting CephConnection from Hub version v1beta1 to Spoke version v1alpha1;"+
56+
"source: %s/%s, target: %s/%s", src.Namespace, src.Name, dst.Namespace, dst.Name)
57+
58+
dst.ObjectMeta = src.ObjectMeta
59+
60+
dst.Spec.Monitors = src.Spec.Monitors
61+
dst.Spec.RbdMirrorDaemonCount = src.Spec.RbdMirrorDaemonCount
62+
dst.Spec.ReadAffinity = (*ReadAffinitySpec)(src.Spec.ReadAffinity)
63+
64+
return nil
65+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
Copyright 2024.
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 v1beta1
18+
19+
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
20+
21+
// Hub marks this type as a conversion hub.
22+
func (*CephConnection) Hub() {}

api/csi/v1beta1/cephconnection_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type CephConnectionStatus struct {
4646
}
4747

4848
// +kubebuilder:object:root=true
49+
// +kubebuilder:conversion:hub
4950
// +kubebuilder:storageversion
5051
// +kubebuilder:subresource:status
5152

api/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.23.0
55
require (
66
k8s.io/api v0.32.1
77
k8s.io/apimachinery v0.32.1
8+
sigs.k8s.io/controller-runtime v0.20.3
89
)
910

1011
require (

api/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
8787
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
8888
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
8989
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
90+
sigs.k8s.io/controller-runtime v0.20.3 h1:I6Ln8JfQjHH7JbtCD2HCYHoIzajoRxPNuvhvcDbZgkI=
91+
sigs.k8s.io/controller-runtime v0.20.3/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY=
9092
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
9193
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
9294
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=

cmd/main.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ import (
3838
"sigs.k8s.io/controller-runtime/pkg/log/zap"
3939
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
4040
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
41+
"sigs.k8s.io/controller-runtime/pkg/webhook"
4142

4243
csiv1alpha1 "github.com/ceph/ceph-csi-operator/api/csi/v1alpha1"
4344
csiv1beta1 "github.com/ceph/ceph-csi-operator/api/csi/v1beta1"
4445
controller "github.com/ceph/ceph-csi-operator/internal/controller/csi"
4546
"github.com/ceph/ceph-csi-operator/internal/utils"
47+
webhookcsiv1beta1 "github.com/ceph/ceph-csi-operator/internal/webhook/csi/v1beta1"
4648
//+kubebuilder:scaffold:imports
4749
)
4850

@@ -62,6 +64,7 @@ func init() {
6264
func main() {
6365
var metricsAddr string
6466
var metricsCertPath, metricsCertName, metricsCertKey string
67+
var webhookCertPath, webhookCertName, webhookCertKey string
6568
var enableLeaderElection bool
6669
var enableHTTP2 bool
6770
var probeAddr string
@@ -79,6 +82,9 @@ func main() {
7982
"The directory that contains the metrics server certificate.")
8083
flag.StringVar(&metricsCertName, "metrics-cert-name", "tls.crt", "The name of the metrics server certificate file.")
8184
flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.")
85+
flag.StringVar(&webhookCertPath, "webhook-cert-path", "", "The directory that contains the webhook certificate.")
86+
flag.StringVar(&webhookCertName, "webhook-cert-name", "tls.crt", "The name of the webhook certificate file.")
87+
flag.StringVar(&webhookCertKey, "webhook-cert-key", "tls.key", "The name of the webhook key file.")
8288
flag.BoolVar(&enableHTTP2, "enable-http2", false,
8389
"If set, HTTP/2 will be enabled for the metrics")
8490

@@ -104,7 +110,34 @@ func main() {
104110
tlsOpts = append(tlsOpts, disableHTTP2)
105111
}
106112
// Create watchers for metrics certificates
107-
var metricsCertWatcher *certwatcher.CertWatcher
113+
var metricsCertWatcher, webhookCertWatcher *certwatcher.CertWatcher
114+
115+
// Initial webhook TLS options
116+
webhookTLSOpts := tlsOpts
117+
118+
if len(webhookCertPath) > 0 {
119+
setupLog.Info("Initializing webhook certificate watcher using provided certificates",
120+
"webhook-cert-path", webhookCertPath, "webhook-cert-name", webhookCertName, "webhook-cert-key", webhookCertKey)
121+
122+
var err error
123+
webhookCertWatcher, err = certwatcher.New(
124+
filepath.Join(webhookCertPath, webhookCertName),
125+
filepath.Join(webhookCertPath, webhookCertKey),
126+
)
127+
if err != nil {
128+
setupLog.Error(err, "Failed to initialize webhook certificate watcher")
129+
os.Exit(1)
130+
}
131+
132+
webhookTLSOpts = append(webhookTLSOpts, func(config *tls.Config) {
133+
config.GetCertificate = webhookCertWatcher.GetCertificate
134+
})
135+
}
136+
137+
webhookServer := webhook.NewServer(webhook.Options{
138+
TLSOpts: webhookTLSOpts,
139+
})
140+
108141
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
109142
// More info:
110143
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.20.0/pkg/metrics/server
@@ -169,6 +202,7 @@ func main() {
169202
}
170203
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
171204
Scheme: scheme,
205+
WebhookServer: webhookServer,
172206
Metrics: metricsServerOptions,
173207
HealthProbeBindAddress: probeAddr,
174208
LeaderElection: enableLeaderElection,
@@ -212,6 +246,13 @@ func main() {
212246
setupLog.Error(err, "unable to create controller", "controller", "ClientProfileMapping")
213247
os.Exit(1)
214248
}
249+
// nolint:goconst
250+
if os.Getenv("ENABLE_WEBHOOKS") != "false" {
251+
if err = webhookcsiv1beta1.SetupCephConnectionWebhookWithManager(mgr); err != nil {
252+
setupLog.Error(err, "unable to create webhook", "webhook", "CephConnection")
253+
os.Exit(1)
254+
}
255+
}
215256
//+kubebuilder:scaffold:builder
216257

217258
if metricsCertWatcher != nil {
@@ -222,6 +263,14 @@ func main() {
222263
}
223264
}
224265

266+
if webhookCertWatcher != nil {
267+
setupLog.Info("Adding webhook certificate watcher to manager")
268+
if err := mgr.Add(webhookCertWatcher); err != nil {
269+
setupLog.Error(err, "unable to add webhook certificate watcher to manager")
270+
os.Exit(1)
271+
}
272+
}
273+
225274
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
226275
setupLog.Error(err, "unable to set up health check")
227276
os.Exit(1)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# The following manifests contain a self-signed issuer CR and a metrics certificate CR.
2+
# More document can be found at https://docs.cert-manager.io
3+
apiVersion: cert-manager.io/v1
4+
kind: Certificate
5+
metadata:
6+
labels:
7+
app.kubernetes.io/name: ceph-csi-operator
8+
app.kubernetes.io/managed-by: kustomize
9+
name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml
10+
namespace: system
11+
spec:
12+
dnsNames:
13+
# SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
14+
# replacements in the config/default/kustomization.yaml file.
15+
- SERVICE_NAME.SERVICE_NAMESPACE.svc
16+
- SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
17+
issuerRef:
18+
kind: Issuer
19+
name: selfsigned-issuer
20+
secretName: metrics-server-cert
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# The following manifests contain a self-signed issuer CR and a certificate CR.
2+
# More document can be found at https://docs.cert-manager.io
3+
apiVersion: cert-manager.io/v1
4+
kind: Certificate
5+
metadata:
6+
labels:
7+
app.kubernetes.io/name: ceph-csi-operator
8+
app.kubernetes.io/managed-by: kustomize
9+
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
10+
namespace: system
11+
spec:
12+
# SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
13+
# replacements in the config/default/kustomization.yaml file.
14+
dnsNames:
15+
- SERVICE_NAME.SERVICE_NAMESPACE.svc
16+
- SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
17+
issuerRef:
18+
kind: Issuer
19+
name: selfsigned-issuer
20+
secretName: webhook-server-cert

config/certmanager/issuer.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# The following manifest contains a self-signed issuer CR.
2+
# More information can be found at https://docs.cert-manager.io
3+
# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes.
4+
apiVersion: cert-manager.io/v1
5+
kind: Issuer
6+
metadata:
7+
labels:
8+
app.kubernetes.io/name: ceph-csi-operator
9+
app.kubernetes.io/managed-by: kustomize
10+
name: selfsigned-issuer
11+
namespace: system
12+
spec:
13+
selfSigned: {}

0 commit comments

Comments
 (0)