Skip to content

Commit d4dfe59

Browse files
committed
Add admission webhook
This PR adds the admission webhook for verifying snapshot API objects and also seting the default snapshot class if it is not specified by the users
1 parent a89a71b commit d4dfe59

File tree

4 files changed

+552
-1
lines changed

4 files changed

+552
-1
lines changed

cmd/csi-snapshotter/main.go

+32-1
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ import (
2020
"context"
2121
"flag"
2222
"fmt"
23+
"net/http"
2324
"os"
2425
"os/signal"
2526
"time"
2627

2728
"github.com/golang/glog"
29+
"github.com/pkg/errors"
2830
"k8s.io/client-go/kubernetes"
2931
"k8s.io/client-go/kubernetes/scheme"
3032
"k8s.io/client-go/rest"
@@ -36,6 +38,7 @@ import (
3638
clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
3739
snapshotscheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme"
3840
informers "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions"
41+
"github.com/kubernetes-csi/external-snapshotter/pkg/webhook"
3942
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
4043
)
4144

@@ -62,7 +65,9 @@ var (
6265
)
6366

6467
var (
65-
version = "unknown"
68+
version = "unknown"
69+
serviceName = flag.String("service-name", "snapshot-admission-webhook-svc", "The name of the admission webhook service.")
70+
serviceNamespace = flag.String("service-namespace", "default", "The namespace of the admission webhook service.")
6671
)
6772

6873
func main() {
@@ -156,6 +161,11 @@ func main() {
156161
os.Exit(1)
157162
}
158163

164+
if err := webhook.CreateConfiguration(kubeClient, *serviceName, *serviceNamespace); err != nil {
165+
glog.Error("Failed to create configuration for Webhook, %v", err)
166+
os.Exit(1)
167+
}
168+
159169
glog.V(2).Infof("Start NewCSISnapshotController with snapshotter [%s] kubeconfig [%s] connectionTimeout [%+v] csiAddress [%s] createSnapshotContentRetryCount [%d] createSnapshotContentInterval [%+v] resyncPeriod [%+v] snapshotNamePrefix [%s] snapshotNameUUIDLength [%d]", *snapshotter, *kubeconfig, *connectionTimeout, *csiAddress, createSnapshotContentRetryCount, *createSnapshotContentInterval, *resyncPeriod, *snapshotNamePrefix, snapshotNameUUIDLength)
160170

161171
ctrl := controller.NewCSISnapshotController(
@@ -177,6 +187,7 @@ func main() {
177187
// run...
178188
stopCh := make(chan struct{})
179189
factory.Start(stopCh)
190+
go startWebhooksHTTPs(kubeClient, snapClient)
180191
go ctrl.Run(threads, stopCh)
181192

182193
// ...until SIGINT
@@ -214,3 +225,23 @@ func waitForDriverReady(csiConn connection.CSIConnection, timeout time.Duration)
214225
time.Sleep(time.Second)
215226
}
216227
}
228+
229+
func startWebhooksHTTPs(kubeClientset kubernetes.Interface, snapClient clientset.Interface) error {
230+
glog.V(2).Infof("Starting Snapshot webhooks HTTPS handler")
231+
defer glog.V(2).Infof("Stopping Snapshot webhooks HTTPS handler")
232+
233+
mux := http.NewServeMux()
234+
mux.Handle("/", http.HandlerFunc(
235+
func(w http.ResponseWriter, r *http.Request) {
236+
webhook.AdmitSnapshot(w, r, kubeClientset, snapClient)
237+
}))
238+
server := &http.Server{
239+
Addr: ":443",
240+
TLSConfig: webhook.GetTLSConfig(),
241+
Handler: mux,
242+
}
243+
if err := server.ListenAndServeTLS("", ""); err != http.ErrServerClosed {
244+
return errors.Wrap(err, "start webhook HTTPS handler")
245+
}
246+
return nil
247+
}

hack/gencerts.sh

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
#!/bin/bash
3+
4+
# Copyright 2018 The Kubernetes Authors. All rights reserved.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
19+
# Generates the a CA cert, a server key, and a server cert signed by the CA.
20+
# reference: https://github.com/kubernetes/kubernetes/blob/master/plugin/pkg/admission/webhook/gencerts.sh
21+
set -e
22+
23+
CN_BASE="snapshot"
24+
CN="snapshot-admission-webhook-svc.default.svc"
25+
26+
cat > server.conf << EOF
27+
[req]
28+
req_extensions = v3_req
29+
distinguished_name = req_distinguished_name
30+
[req_distinguished_name]
31+
[ v3_req ]
32+
basicConstraints = CA:FALSE
33+
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
34+
extendedKeyUsage = clientAuth, serverAuth
35+
EOF
36+
37+
# Create a certificate authority
38+
openssl genrsa -out caKey.pem 2048
39+
openssl req -x509 -new -nodes -key caKey.pem -days 100000 -out caCert.pem -subj "/CN=${CN_BASE}_ca"
40+
41+
# Create a server certificate
42+
openssl genrsa -out serverKey.pem 2048
43+
# Note the CN is the DNS name of the service of the webhook.
44+
openssl req -new -key serverKey.pem -out server.csr -subj "/CN=${CN}" -config server.conf
45+
openssl x509 -req -in server.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out serverCert.pem -days 100000 -extensions v3_req -extfile server.conf
46+
47+
outfile=pkg/webhook/certs.go
48+
49+
cat > $outfile << EOF
50+
EOF
51+
52+
echo "// This file was generated using openssl by the gencerts.sh script" >> $outfile
53+
echo "" >> $outfile
54+
echo "package webhook" >> $outfile
55+
for file in caKey caCert serverKey serverCert; do
56+
data=$(cat ${file}.pem)
57+
echo "" >> $outfile
58+
echo "var $file = []byte(\`$data\`)" >> $outfile
59+
done
60+
61+
# Clean up after we're done.
62+
rm *.pem
63+
rm *.csr
64+
rm *.srl
65+
rm *.conf

pkg/webhook/certs.go

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright 2018 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
// This file was generated using openssl by the gencerts.sh script
15+
16+
package webhook
17+
18+
var caKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
19+
MIIEowIBAAKCAQEAuVbxVMXgIyoEPRj6XdX/uCGcz7SSrzDYsgFvWFuEtEiFWXZ7
20+
izGhM+KtgrFxwchr/J+ZIFO6tOjX+uM1LuQzjLn3MfFoJtdGANAm8Kqus8eOOXOb
21+
78/JELdGYkkrYENWIsSvcB81y3ahjgAPV4X74ZjPVuGjd2EVRgFtOfYOaGYzehdh
22+
Ih47CxjMKYPZ5T3F6MptY1YYxEBfCGl7PuEkRUd8jnqubYCbnN8Tch1LOVrNPgc2
23+
M5KY4/P1xiftFJU4KhWvqceicYc2/0le3Hu29m5L2lFDK2OF2gcIpbmF1LPeuzol
24+
u7XzRqteSU9/BOGNGgHF0808jgIMU39DQGyuXwIDAQABAoIBAFVFMvMVtvF2u0yA
25+
2W+irWxByqulIHeJuajsEBZOxNdNJkzqvhxkUQ5WFA41JWlKlKQ9qW2+GABzwCql
26+
ripMw4rTZG+N6aU1Fff5zHCdlpMQFNdJ4UyMBK20JKXDlDlNwattYmnrcgySH/H9
27+
BRH3itNYQsxuM48RE4CJ1377PdW5pplj8urMJ6vaQ5FdBnxFpThMlyuqSezk/GqA
28+
iXAB0VHt2JvkSe8XXIzVtkKR6FnfaGT5dH020/Ia4w07zY4l6rBvSN2iaW8a9trc
29+
MsZug9At+I+/WVBDS97PRrmEREECPJJB78E9F+nPxEToYTns5zrKz8m3N3LX0CcK
30+
ZQV6w8ECgYEA64rdB/5wwBxjHY+YqmaxezQXS1TT8Z3hkHw10BPeabYSzmiCDzwh
31+
2lQztiA2mBhTsyOG82uz/BFQEEB+6d6cf77BJuh4pk7w4Mg+UYoHoBfIr7zC2rfS
32+
RUC1uRSvgYWTf/MPKPKzSJpEVaVV8IBn+ibpwKFURMFhIdL/C+Qe1ZsCgYEAyW/Z
33+
/1s/BGhXrqNsPVbqAyIKJXNcaJDzNNfktY43w9U9sUIMrW2J2trjK6qJ5Itlfro9
34+
NXquchd0pYm+ysAqF8vmN4vB/FN0QcnvBSYoM2iDtc8+C/G6cjt9adiJQTDYh1yF
35+
/I3xz+d/bynyTgoYKc7fsMyHflYcK4N3wmYnmI0CgYEArTYG6NQBkiTN9nUcrWKr
36+
bZCW+Ly+x1V1BM1yvTt/OXm9RrCvxAhSVL3K8UmrHBn3oyqjGOrBBsKsf+cN7WnY
37+
6FActkIKRzKSDJr0yP2aMe6LlEBZgoHfTTIS8LH3hmX2XAcfxNsFYIShb+IP2rZy
38+
wBBRoWiCEbWrejYxfEsbKbUCgYB8HEFJlzO1iIB1plUbWgCm24M63eASwTRH27kb
39+
r7tmGm1/WH2tIS9tu616CwIY4VYwhZkO6T6wJwmEsODv1QRaUxPOJ3rm95hKrJtr
40+
Jb5hJkT4cO7+tvo0RbkYzQSMOQdAJ16aY+6YNT8MA+E5+fg3UjH6oZnd2jpTCRZx
41+
nTVKRQKBgEXRMBHJv6xzF0vfdsNTftgX5vfOyHRFuGzL04a0evv6Zj8izPJ2rOwy
42+
tbFfCvmMiNqBANTR9YxM9fDv2Aq7qWUSJ2IqVS6nXw0EDj3TXH+Pur2LfQPACKtD
43+
1Oe+4t0kmon2We6o9hNM9nR3EjFA0zDauKwRBSrjrlGaf4tTsc/6
44+
-----END RSA PRIVATE KEY-----`)
45+
46+
var caCert = []byte(`-----BEGIN CERTIFICATE-----
47+
MIIDBDCCAeygAwIBAgIJAPLPw2bFlYqUMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV
48+
BAMMC3NuYXBzaG90X2NhMCAXDTE4MDkyNzIwNTIzNloYDzIyOTIwNzEyMjA1MjM2
49+
WjAWMRQwEgYDVQQDDAtzbmFwc2hvdF9jYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
50+
ADCCAQoCggEBALlW8VTF4CMqBD0Y+l3V/7ghnM+0kq8w2LIBb1hbhLRIhVl2e4sx
51+
oTPirYKxccHIa/yfmSBTurTo1/rjNS7kM4y59zHxaCbXRgDQJvCqrrPHjjlzm+/P
52+
yRC3RmJJK2BDViLEr3AfNct2oY4AD1eF++GYz1bho3dhFUYBbTn2DmhmM3oXYSIe
53+
OwsYzCmD2eU9xejKbWNWGMRAXwhpez7hJEVHfI56rm2Am5zfE3IdSzlazT4HNjOS
54+
mOPz9cYn7RSVOCoVr6nHonGHNv9JXtx7tvZuS9pRQytjhdoHCKW5hdSz3rs6Jbu1
55+
80arXklPfwThjRoBxdPNPI4CDFN/Q0Bsrl8CAwEAAaNTMFEwHQYDVR0OBBYEFFGw
56+
D7vzl/nFIQ8h5rcqc6LsOVY5MB8GA1UdIwQYMBaAFFGwD7vzl/nFIQ8h5rcqc6Ls
57+
OVY5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEVO/V0PFB9E
58+
wujSbOYCIbx+51yDUoC8hxT1r1Kcx3u08MDgUoDX+Rxg/Ok7XbqweCvR0drbSKAA
59+
kLE96CVL98gonTK8xq/wr6ajEu4Zkq2gG+uTDnk09Rw3tQDlu5a8y2xx3tkPwXZQ
60+
mJlOKfRQJT16scQYJI2vYlfD02sIAz82+Y6tJTe8X4HviSPx4l65V1gP1Cv0IRQN
61+
FmZf7z8vxhvuO2bc4kEfD2ROtn8JR6IohFkqbsgLblZleFlsjnoS+wZr/hg4OGKN
62+
Ra00JO66qaNYwwueeKU4Qvfo/HiWXwRivsCmNkkuzneovYI9WAnspQXg6szMMKxj
63+
g1O6iPylFcU=
64+
-----END CERTIFICATE-----`)
65+
66+
var serverKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
67+
MIIEpAIBAAKCAQEA2VeAQeGNCBfuCQaqQIEspJFQNnal47TytS5LDgH5RccoRkIs
68+
kCsecdPEZeLqHnuDEMg9M6DPWjl4VHkPnBCUkCVVGjvhb1c4A5LI++zKIZkhvUvY
69+
zpsS6emQs+Ji+86I83EgxpjBXzEgD0NffOfaDbLdLFA+B0R7jOyaIquvvMPXcca7
70+
z1EDbN0zuUPmPHBa9LRLs4TlEbn8gGpL+ajSyBqrsL5qP92VUq8wcFpUXJ50xocD
71+
B5tZc8ESmIiYjIVXaFvIZu1RAIG2Sj68HOpbU61T/Ftdc3y4kB8+9rTUFaTvSVvD
72+
ShW3sUqFULD6qv+vg+GzRAWGM+sUjhvx0VZrzQIDAQABAoIBADNG56Wjd0ifjLNo
73+
dSZ+02+IMSqIV58fg9unLmIBqTQDRsc8uZLR+X7VfZKkNKQ4c7Wz6GyT1hftUyxq
74+
23nwl3xism9cDVXdeAOvz+dP+Ghw3nrwuBgWkiHJzzABi2TpV3pICHmSdJzm1C+F
75+
r7OiZ9mvh2r7C4dfat7Wu47OfsnD42ziS9p3R6hcvugPoaAy23IwAgmR8LwoOXGy
76+
ZiAkb/d30G0MNt3lFbeZKHL16ibRxPjCRnDrfI++4/iJhuxBVv0BebYEjvajAFby
77+
G/bQNfXSghpYAywnCMoTqUVCV8ZALbw+okGrcxThcI7ZKghVGcYeK9/n5+tg7+r9
78+
I1Q3J2kCgYEA8ZW3xhRr3XwuJCUFBs5yB0ibjV31w5slvSBrhd78gGLij8DRRynt
79+
U/rro0Vk0rw3VzKJvk9rohR0YbQBDIrtfVNWzkJOZJXDDwmb6b8ooUcADl5ui9Ul
80+
NvgwzQtq/p/nDfPNbwzMN4XiwfnQ/+yq0J98+RvEM6bDlYOT6wma8hsCgYEA5k92
81+
oDfyIGqI3Cx1jFnRwxTo5A6yW73B0XkIFOe8P2PMhntjt7rpE3gq3VVfDbemVSI5
82+
WXY5wh0daOFkWzNbuvudHxslWQrZSyG71ycEcAHfxWuwqOLiGn4x3/CXzIJsyR8L
83+
jkhApZ2J6YwotxFk9kh/DW+vOpbPKUdPZbGruDcCgYEA3f4T90LAs6/uvmv+KHkA
84+
M003EzpqIaqpjRcDduqm4Fr9kdc+98PBP9BtQ4T61uL5f3kDNgvI/hEJuNYtuJbZ
85+
ELbKJ5KqcqdjrKfJy4tLDJgvpwSDVJ8yKUb7oQ+C7COHsDx+ZDNAXSz8Z/7lXKbf
86+
eAF2V3p6WnQ9eWCFRg93gE0CgYBNGR7aBcB9T4yfQBbdtBe/WZmY9r6IbZ6bdAvb
87+
i7P9+He4MUgxclWiGeEnlPOsEOWSrFFMfIJbVAnLWWCSE0BK+P4hMqIvC62wNAvA
88+
u6QFpur1GNbbwo/0VHh3wf/fC25FaaohqFhT2MgZMb1Tg3Qr6hr2MYQUdfXFmMSg
89+
g3i7wwKBgQCPv2YxHynKq/N6Ns8OUAAGatIc8BG07EBT79T8UPiGi7Ova3jIoQLp
90+
UkiSKdtPaYDnjUG/a4MkVbNATNh48rveW/U5BumLMMFQtHK44vOQFX9fGS/zLKkZ
91+
yt8uo1eX6Uo3QGuXaLFKgu0sXRRzBtZBu/6AUzTNA5gKz9qIBKkfeA==
92+
-----END RSA PRIVATE KEY-----`)
93+
94+
var serverCert = []byte(`-----BEGIN CERTIFICATE-----
95+
MIIDCTCCAfGgAwIBAgIJAMT8cU6Xrf9/MA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV
96+
BAMMC3NuYXBzaG90X2NhMCAXDTE4MDkyNzIwNTIzN1oYDzIyOTIwNzEyMjA1MjM3
97+
WjA1MTMwMQYDVQQDDCpzbmFwc2hvdC1hZG1pc3Npb24td2ViaG9vay1zdmMuZGVm
98+
YXVsdC5zdmMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZV4BB4Y0I
99+
F+4JBqpAgSykkVA2dqXjtPK1LksOAflFxyhGQiyQKx5x08Rl4uoee4MQyD0zoM9a
100+
OXhUeQ+cEJSQJVUaO+FvVzgDksj77MohmSG9S9jOmxLp6ZCz4mL7zojzcSDGmMFf
101+
MSAPQ19859oNst0sUD4HRHuM7Joiq6+8w9dxxrvPUQNs3TO5Q+Y8cFr0tEuzhOUR
102+
ufyAakv5qNLIGquwvmo/3ZVSrzBwWlRcnnTGhwMHm1lzwRKYiJiMhVdoW8hm7VEA
103+
gbZKPrwc6ltTrVP8W11zfLiQHz72tNQVpO9JW8NKFbexSoVQsPqq/6+D4bNEBYYz
104+
6xSOG/HRVmvNAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1Ud
105+
JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEADQw8
106+
fw/RgOTtx9QVxUYMVD55VtdX/xctaAllTnE3A2T03/o73pdLs8owaPd0CbUFZO4m
107+
0AgaSzOamd3HHTY9TBxtddGh1wU+yxWMB+XhffAQwHpxIZ/BVMhu3pf5024D7S6k
108+
5dskfY/011+JmCi28Rfwb86mlwluR4fOczSTW22815aZv8LXxsCrwzbft86pa+dQ
109+
b6lzWsT6H+BE92xBCpgrZyMBCSs0hXfDQV7f0lVJcD+Z3bJkDPO/8yue2IyluUx+
110+
Eovpt5wY4AhiorLD5xw5jY4cFLooDLOyV8VGJ56GuAUVpvYKivD92k5whTl7fSAR
111+
xsubPWWjGPtNl9vpyQ==
112+
-----END CERTIFICATE-----`)

0 commit comments

Comments
 (0)