-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.go
130 lines (104 loc) · 3.74 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"context"
"crypto/tls"
"fmt"
"net/http"
"os"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
webhook "github.com/uswitch/vault-webhook/pkg/client/clientset/versioned"
kingpin "gopkg.in/alecthomas/kingpin.v2"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
)
var (
vaultAddr string
vaultCaPath string
gatewayAddr string
loginPath string
secretPathFormat string
sidecarImage string
serverAddress string
)
func main() {
kingpin.Flag("vault-address", "URL of vault").Required().StringVar(&vaultAddr)
kingpin.Flag("vault-ca-path", "Path to the CA cert for vault").StringVar(&vaultCaPath)
kingpin.Flag("login-path", "Kubernetes auth login path for vault").Required().StringVar(&loginPath)
kingpin.Flag("sidecar-image", "Vault-creds sidecar image to use").Required().StringVar(&sidecarImage)
kingpin.Flag("gateway-address", "URL of Push Gateway").StringVar(&gatewayAddr)
kingpin.Flag("secret-path-format", "The format for the path used for reading database credentials, where the first %s is the database name and the second %s is the role").Default("%s/creds/%s").StringVar(&secretPathFormat)
kingpin.Flag("server-address", "The address the webhook server will listen on.").Default(":8443").StringVar(&serverAddress)
kingpin.Parse()
log.SetOutput(os.Stderr)
ctx := context.Background()
// load certs
kpr, err := NewKeypairReloader("/etc/webhook/certs/cert.pem", "/etc/webhook/certs/key.pem")
if err != nil {
log.Errorf("Failed to load key pair: %v", err)
}
config, err := rest.InClusterConfig()
if err != nil {
log.Fatalf("error creating kube client config: %s", err)
}
client, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatalf("error creating kube client: %s", err)
}
webhookClient, err := webhook.NewForConfig(config)
if err != nil {
log.Fatalf("error creating webhook client: %s", err)
}
watcher := NewListWatch(webhookClient)
srv := http.Server{Addr: serverAddress}
// this will check if there are new certs before every tls handshake
t := &tls.Config{GetCertificate: kpr.GetCertificateFunc()}
srv.TLSConfig = t
whsvr := webHookServer{
server: &srv,
client: client,
bindings: watcher,
ctx: ctx,
}
cont := ctrl.SetupSignalHandler()
ctx, cancel := context.WithCancel(cont)
defer cancel()
mux := http.NewServeMux()
mux.HandleFunc("/mutate", whsvr.serve)
promhandler := promhttp.InstrumentMetricHandler(prometheus.DefaultRegisterer, mux)
whsvr.server.Handler = promhandler
healthMux := http.NewServeMux()
healthMux.Handle("/metrics", promhttp.Handler())
healthMux.HandleFunc("/healthz", whsvr.checkHealth)
healthServer := &http.Server{
Addr: fmt.Sprintf(":8080"),
Handler: healthMux,
}
watcher.Run(ctx)
log.Info("Waiting for informer caches to sync")
if ok := watcher.controller.HasSynced(); !ok {
log.Fatal("failed to wait for caches to sync")
}
log.Info("starting server")
// start webhook server in new rountine
go func() {
if err := whsvr.server.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
log.Fatalf("Failed to listen and serve webhook server: %v", err)
}
}()
go func() {
if err := healthServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("Failed to listen and serve health server: %v", err)
}
}()
// listening OS shutdown singal
<-cont.Done()
log.Infof("Got OS shutdown signal, shutting down webhook server gracefully...")
shutDownCTX, shutDownCancel := context.WithTimeout(context.Background(), 20*time.Second)
defer shutDownCancel()
whsvr.server.Shutdown(shutDownCTX)
healthServer.Shutdown(shutDownCTX)
}