@@ -18,17 +18,122 @@ package app
1818
1919import (
2020 "crypto/tls"
21+ "fmt"
22+ "io/ioutil"
23+ "net/http"
24+ "os"
25+ "os/signal"
26+ "strconv"
27+ "syscall"
2128
2229 "k8s.io/client-go/kubernetes"
2330 "k8s.io/client-go/rest"
31+ "k8s.io/client-go/tools/clientcmd"
2432 "k8s.io/klog"
2533
2634 "volcano.sh/volcano/cmd/admission/app/options"
35+ "volcano.sh/volcano/pkg/admission/router"
2736 "volcano.sh/volcano/pkg/client/clientset/versioned"
37+ "volcano.sh/volcano/pkg/version"
2838)
2939
40+ // Run start the service of admission controller.
41+ func Run (config * options.Config ) error {
42+ if config .PrintVersion {
43+ version .PrintVersionAndExit ()
44+ return nil
45+ }
46+
47+ restConfig , err := clientcmd .BuildConfigFromFlags (config .Master , config .Kubeconfig )
48+ if err != nil {
49+ return fmt .Errorf ("unable to build k8s config: %v" , err )
50+ }
51+
52+ caBundle , err := ioutil .ReadFile (config .CaCertFile )
53+ if err != nil {
54+ return fmt .Errorf ("unable to read cacert file: %v" , err )
55+ }
56+
57+ vClient := getVolcanoClient (restConfig )
58+ router .ForEachAdmission (func (service * router.AdmissionService ) {
59+ if service .Config != nil {
60+ service .Config .VolcanoClient = vClient
61+ service .Config .SchedulerName = config .SchedulerName
62+ }
63+
64+ klog .V (3 ).Infof ("Registered '%s' as webhook." , service .Path )
65+ http .HandleFunc (service .Path , service .Handler )
66+
67+ clientConfig := v1beta1.WebhookClientConfig {
68+ CABundle : cabundle ,
69+ }
70+
71+ if c .WebhookURL != "" {
72+ url := c .WebhookURL + service .Path
73+ clientConfig .URL = & url
74+ }
75+
76+ if c .AdmissionServiceName != "" && c .AdmissionServiceNamespace != "" {
77+ clientConfig .Service = & v1beta1.ServiceReference {
78+ Name : c .AdmissionServiceName ,
79+ Namespace : c .AdmissionServiceNamespace ,
80+ Path : & service .Path ,
81+ }
82+ }
83+
84+
85+ if service .MutatingConfig != nil {
86+ service .MutatingConfig .ClientConfig = clientConfig
87+
88+ klog .V (3 ).Infof ("Registered mutating webhook for path <%s>." , service .Path )
89+ }
90+
91+ if service .ValidatingConfig != nil {
92+ service .ValidatingConfig .ClientConfig = clientConfig
93+
94+ klog .V (3 ).Infof ("Registered validating webhook for path <%s>." , service .Path )
95+ }
96+ })
97+
98+
99+ err = options .RegisterWebhooks (config , getClient (restConfig ), caBundle )
100+ if err != nil {
101+ return fmt .Errorf ("unable to register webhook configs: %v" , err )
102+ }
103+
104+ klog .V (3 ).Info ("Registered all webhooks to the api-server." )
105+
106+ webhookServeError := make (chan struct {})
107+ stopChannel := make (chan os.Signal )
108+ signal .Notify (stopChannel , syscall .SIGTERM , syscall .SIGINT )
109+
110+ server := & http.Server {
111+ Addr : ":" + strconv .Itoa (config .Port ),
112+ TLSConfig : configTLS (config , restConfig ),
113+ }
114+ go func () {
115+ err = server .ListenAndServeTLS ("" , "" )
116+ if err != nil && err != http .ErrServerClosed {
117+ klog .Fatalf ("ListenAndServeTLS for admission webhook failed: %v" , err )
118+ close (webhookServeError )
119+ }
120+
121+ klog .Info ("Volcano Webhook manager started." )
122+ }()
123+
124+ select {
125+ case <- stopChannel :
126+ if err := server .Close (); err != nil {
127+ return fmt .Errorf ("close admission server failed: %v" , err )
128+ }
129+ return nil
130+ case <- webhookServeError :
131+ return fmt .Errorf ("unknown webhook server error" )
132+ }
133+ }
134+
30135// GetClient Get a clientset with restConfig.
31- func GetClient (restConfig * rest.Config ) * kubernetes.Clientset {
136+ func getClient (restConfig * rest.Config ) * kubernetes.Clientset {
32137 clientset , err := kubernetes .NewForConfig (restConfig )
33138 if err != nil {
34139 klog .Fatal (err )
@@ -37,18 +142,18 @@ func GetClient(restConfig *rest.Config) *kubernetes.Clientset {
37142}
38143
39144// GetVolcanoClient get a clientset for volcano
40- func GetVolcanoClient (restConfig * rest.Config ) * versioned.Clientset {
145+ func getVolcanoClient (restConfig * rest.Config ) * versioned.Clientset {
41146 clientset , err := versioned .NewForConfig (restConfig )
42147 if err != nil {
43148 klog .Fatal (err )
44149 }
45150 return clientset
46151}
47152
48- // ConfigTLS is a helper function that generate tls certificates from directly defined tls config or kubeconfig
153+ // configTLS is a helper function that generate tls certificates from directly defined tls config or kubeconfig
49154// These are passed in as command line for cluster certification. If tls config is passed in, we use the directly
50155// defined tls config, else use that defined in kubeconfig
51- func ConfigTLS (config * options.Config , restConfig * rest.Config ) * tls.Config {
156+ func configTLS (config * options.Config , restConfig * rest.Config ) * tls.Config {
52157 if len (config .CertFile ) != 0 && len (config .KeyFile ) != 0 {
53158 sCert , err := tls .LoadX509KeyPair (config .CertFile , config .KeyFile )
54159 if err != nil {
0 commit comments