Skip to content

Commit 5837d70

Browse files
wangyuqing (C)wangyuqing4
wangyuqing (C)
authored andcommitted
add admitPod
1 parent 41fad21 commit 5837d70

20 files changed

+658
-150
lines changed

cmd/admission/app/configure/configure.go cmd/admission/app/options/options.go

+48-1
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package configure
17+
package options
1818

1919
import (
2020
"flag"
2121
"fmt"
22+
2223
"github.com/golang/glog"
2324

2425
"k8s.io/api/admissionregistration/v1beta1"
@@ -29,6 +30,10 @@ import (
2930
admissionregistrationv1beta1client "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1"
3031
)
3132

33+
const (
34+
defaultSchedulerName = "volcano"
35+
)
36+
3237
// Config admission-controller server config.
3338
type Config struct {
3439
Master string
@@ -44,6 +49,7 @@ type Config struct {
4449
PrintVersion bool
4550
AdmissionServiceName string
4651
AdmissionServiceNamespace string
52+
SchedulerName string
4753
}
4854

4955
// NewConfig create new config
@@ -73,6 +79,7 @@ func (c *Config) AddFlags() {
7379
flag.BoolVar(&c.PrintVersion, "version", false, "Show version and quit")
7480
flag.StringVar(&c.AdmissionServiceNamespace, "webhook-namespace", "default", "The namespace of this webhook")
7581
flag.StringVar(&c.AdmissionServiceName, "webhook-service-name", "admission-service", "The name of this admission service")
82+
flag.StringVar(&c.SchedulerName, "scheduler-name", defaultSchedulerName, "Volcano will handle pods whose .spec.SchedulerName is same as scheduler-name")
7683
}
7784

7885
const (
@@ -84,6 +91,10 @@ const (
8491
ValidateHookName = "validatejob.volcano.sh"
8592
// MutateHookName Default name for webhooks in MutatingWebhookConfiguration
8693
MutateHookName = "mutatejob.volcano.sh"
94+
// ValidatePodConfigName ValidatingWebhookPodConfiguration name format
95+
ValidatePodConfigName = "%s-validate-pod"
96+
// ValidatePodHookName Default name for webhooks in ValidatingWebhookPodConfiguration
97+
ValidatePodHookName = "validatepod.volcano.sh"
8798
)
8899

89100
// CheckPortOrDie check valid port range
@@ -177,6 +188,42 @@ func RegisterWebhooks(c *Config, clienset *kubernetes.Clientset, cabundle []byte
177188
return err
178189
}
179190

191+
// Prepare validate pods
192+
path = "/pods"
193+
PodValidateHooks := v1beta1.ValidatingWebhookConfiguration{
194+
ObjectMeta: metav1.ObjectMeta{
195+
Name: useGeneratedNameIfRequired("",
196+
fmt.Sprintf(ValidatePodConfigName, c.AdmissionServiceName)),
197+
},
198+
Webhooks: []v1beta1.Webhook{{
199+
Name: useGeneratedNameIfRequired("", ValidatePodHookName),
200+
Rules: []v1beta1.RuleWithOperations{
201+
{
202+
Operations: []v1beta1.OperationType{v1beta1.Create},
203+
Rule: v1beta1.Rule{
204+
APIGroups: []string{""},
205+
APIVersions: []string{"v1"},
206+
Resources: []string{"pods"},
207+
},
208+
},
209+
},
210+
ClientConfig: v1beta1.WebhookClientConfig{
211+
Service: &v1beta1.ServiceReference{
212+
Name: c.AdmissionServiceName,
213+
Namespace: c.AdmissionServiceNamespace,
214+
Path: &path,
215+
},
216+
CABundle: cabundle,
217+
},
218+
FailurePolicy: &ignorePolicy,
219+
}},
220+
}
221+
222+
if err := registerValidateWebhook(clienset.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations(),
223+
[]v1beta1.ValidatingWebhookConfiguration{PodValidateHooks}); err != nil {
224+
return err
225+
}
226+
180227
return nil
181228

182229
}
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Copyright 2019 The Volcano Authors.
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 options
18+
19+
import (
20+
"reflect"
21+
"testing"
22+
23+
"github.com/spf13/pflag"
24+
)
25+
26+
func TestAddFlags(t *testing.T) {
27+
fs := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError)
28+
s := NewConfig()
29+
s.AddFlags()
30+
31+
args := []string{
32+
"--port=443",
33+
"--webhook-namespace=default",
34+
"--webhook-service-name=admission-service",
35+
}
36+
fs.Parse(args)
37+
38+
// This is a snapshot of expected options parsed by args.
39+
expected := &Config{
40+
Port: 443,
41+
AdmissionServiceNamespace: "default",
42+
AdmissionServiceName: "admission-service",
43+
SchedulerName: defaultSchedulerName,
44+
}
45+
46+
if !reflect.DeepEqual(expected, s) {
47+
t.Errorf("Got different run options than expected.\nGot: %+v\nExpected: %+v\n", s, expected)
48+
}
49+
50+
err := s.CheckPortOrDie()
51+
if err != nil {
52+
t.Errorf("expected nil but got %v\n", err)
53+
}
54+
55+
}

cmd/admission/app/server.go

+4-68
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,13 @@ package app
1818

1919
import (
2020
"crypto/tls"
21-
"encoding/json"
22-
"io/ioutil"
23-
"net/http"
2421

2522
"github.com/golang/glog"
26-
"volcano.sh/volcano/pkg/client/clientset/versioned"
2723

28-
"k8s.io/api/admission/v1beta1"
29-
"k8s.io/apimachinery/pkg/runtime"
3024
"k8s.io/client-go/kubernetes"
3125
restclient "k8s.io/client-go/rest"
32-
33-
appConf "volcano.sh/volcano/cmd/admission/app/configure"
34-
admissioncontroller "volcano.sh/volcano/pkg/admission"
35-
)
36-
37-
const (
38-
//CONTENTTYPE http content-type
39-
CONTENTTYPE = "Content-Type"
40-
41-
//APPLICATIONJSON json content
42-
APPLICATIONJSON = "application/json"
26+
appConf "volcano.sh/volcano/cmd/admission/app/options"
27+
"volcano.sh/volcano/pkg/client/clientset/versioned"
4328
)
4429

4530
// GetClient Get a clientset with restConfig.
@@ -51,8 +36,8 @@ func GetClient(restConfig *restclient.Config) *kubernetes.Clientset {
5136
return clientset
5237
}
5338

54-
//GetKubeBatchClient get a clientset for kubebatch
55-
func GetKubeBatchClient(restConfig *restclient.Config) *versioned.Clientset {
39+
// GetVolcanoClient get a clientset for volcano
40+
func GetVolcanoClient(restConfig *restclient.Config) *versioned.Clientset {
5641
clientset, err := versioned.NewForConfig(restConfig)
5742
if err != nil {
5843
glog.Fatal(err)
@@ -89,52 +74,3 @@ func ConfigTLS(config *appConf.Config, restConfig *restclient.Config) *tls.Confi
8974
glog.Fatal("tls: failed to find any tls config data")
9075
return &tls.Config{}
9176
}
92-
93-
//Serve the http request
94-
func Serve(w http.ResponseWriter, r *http.Request, admit admissioncontroller.AdmitFunc) {
95-
var body []byte
96-
if r.Body != nil {
97-
if data, err := ioutil.ReadAll(r.Body); err == nil {
98-
body = data
99-
}
100-
}
101-
102-
// verify the content type is accurate
103-
contentType := r.Header.Get(CONTENTTYPE)
104-
if contentType != APPLICATIONJSON {
105-
glog.Errorf("contentType=%s, expect application/json", contentType)
106-
return
107-
}
108-
109-
var reviewResponse *v1beta1.AdmissionResponse
110-
ar := v1beta1.AdmissionReview{}
111-
deserializer := admissioncontroller.Codecs.UniversalDeserializer()
112-
if _, _, err := deserializer.Decode(body, nil, &ar); err != nil {
113-
reviewResponse = admissioncontroller.ToAdmissionResponse(err)
114-
} else {
115-
reviewResponse = admit(ar)
116-
}
117-
glog.V(3).Infof("sending response: %v", reviewResponse)
118-
119-
response := createResponse(reviewResponse, &ar)
120-
resp, err := json.Marshal(response)
121-
if err != nil {
122-
glog.Error(err)
123-
}
124-
if _, err := w.Write(resp); err != nil {
125-
glog.Error(err)
126-
}
127-
}
128-
129-
func createResponse(reviewResponse *v1beta1.AdmissionResponse, ar *v1beta1.AdmissionReview) v1beta1.AdmissionReview {
130-
response := v1beta1.AdmissionReview{}
131-
if reviewResponse != nil {
132-
response.Response = reviewResponse
133-
response.Response.UID = ar.Request.UID
134-
}
135-
// reset the Object and OldObject, they are not needed in a response.
136-
ar.Request.Object = runtime.RawExtension{}
137-
ar.Request.OldObject = runtime.RawExtension{}
138-
139-
return response
140-
}

cmd/admission/main.go

+18-5
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,29 @@ package main
1717

1818
import (
1919
"flag"
20-
"github.com/golang/glog"
2120
"io/ioutil"
2221
"net/http"
2322
"os"
2423
"os/signal"
2524
"strconv"
2625
"syscall"
2726

27+
"github.com/golang/glog"
28+
2829
"k8s.io/client-go/tools/clientcmd"
2930

3031
"volcano.sh/volcano/cmd/admission/app"
31-
appConf "volcano.sh/volcano/cmd/admission/app/configure"
32+
appConf "volcano.sh/volcano/cmd/admission/app/options"
3233
admissioncontroller "volcano.sh/volcano/pkg/admission"
3334
"volcano.sh/volcano/pkg/version"
3435
)
3536

3637
func serveJobs(w http.ResponseWriter, r *http.Request) {
37-
app.Serve(w, r, admissioncontroller.AdmitJobs)
38+
admissioncontroller.Serve(w, r, admissioncontroller.AdmitJobs)
3839
}
3940

4041
func serveMutateJobs(w http.ResponseWriter, r *http.Request) {
41-
app.Serve(w, r, admissioncontroller.MutateJobs)
42+
admissioncontroller.Serve(w, r, admissioncontroller.MutateJobs)
4243
}
4344

4445
func main() {
@@ -63,7 +64,9 @@ func main() {
6364
glog.Fatalf("Unable to build k8s config: %v\n", err)
6465
}
6566

66-
admissioncontroller.KubeBatchClientSet = app.GetKubeBatchClient(restConfig)
67+
admissioncontroller.VolcanoClientSet = app.GetVolcanoClient(restConfig)
68+
69+
servePods(config)
6770

6871
caBundle, err := ioutil.ReadFile(config.CaCertFile)
6972
if err != nil {
@@ -101,3 +104,13 @@ func main() {
101104
return
102105
}
103106
}
107+
108+
func servePods(config *appConf.Config) {
109+
admController := &admissioncontroller.Controller{
110+
VcClients: admissioncontroller.VolcanoClientSet,
111+
SchedulerName: config.SchedulerName,
112+
}
113+
http.HandleFunc(admissioncontroller.AdmitPodPath, admController.ServerPods)
114+
115+
return
116+
}

hack/e2e-admission-config.yaml

-44
This file was deleted.

installer/helm/chart/volcano/templates/admission.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ rules:
3232
- apiGroups: [""]
3333
resources: ["services"]
3434
verbs: ["get"]
35+
- apiGroups: ["scheduling.incubator.k8s.io", "scheduling.sigs.dev"]
36+
resources: ["podgroups"]
37+
verbs: ["get", "list", "watch"]
3538

3639
---
3740
kind: ClusterRoleBinding

pkg/admission/admission_controller.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,31 @@ import (
3131
"k8s.io/apimachinery/pkg/util/validation/field"
3232

3333
"volcano.sh/volcano/pkg/apis/batch/v1alpha1"
34+
vcver "volcano.sh/volcano/pkg/client/clientset/versioned"
3435
)
3536

3637
const (
37-
//AdmitJobPath is the pattern for the jobs admission
38+
// AdmitJobPath is the pattern for the jobs admission
3839
AdmitJobPath = "/jobs"
39-
//MutateJobPath is the pattern for the mutating jobs
40+
// MutateJobPath is the pattern for the mutating jobs
4041
MutateJobPath = "/mutating-jobs"
42+
// AdmitPodPath is the pattern for the pods admission
43+
AdmitPodPath = "/pods"
44+
// CONTENTTYPE http content-type
45+
CONTENTTYPE = "Content-Type"
46+
// APPLICATIONJSON json content
47+
APPLICATIONJSON = "application/json"
4148
)
4249

4350
//The AdmitFunc returns response
4451
type AdmitFunc func(v1beta1.AdmissionReview) *v1beta1.AdmissionResponse
4552

53+
// Controller the Admission Controller type
54+
type Controller struct {
55+
VcClients vcver.Interface
56+
SchedulerName string
57+
}
58+
4659
var scheme = runtime.NewScheme()
4760

4861
//Codecs is for retrieving serializers for the supported wire formats

0 commit comments

Comments
 (0)