Skip to content

Commit

Permalink
add admitPod
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyuqing (C) authored and wangyuqing4 committed Aug 5, 2019
1 parent 41fad21 commit 069593a
Show file tree
Hide file tree
Showing 21 changed files with 661 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package configure
package options

import (
"flag"
"fmt"

"github.com/golang/glog"

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

const (
defaultSchedulerName = "volcano"
)

// Config admission-controller server config.
type Config struct {
Master string
Expand All @@ -44,6 +49,7 @@ type Config struct {
PrintVersion bool
AdmissionServiceName string
AdmissionServiceNamespace string
SchedulerName string
}

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

const (
Expand All @@ -84,6 +91,10 @@ const (
ValidateHookName = "validatejob.volcano.sh"
// MutateHookName Default name for webhooks in MutatingWebhookConfiguration
MutateHookName = "mutatejob.volcano.sh"
// ValidatePodConfigName ValidatingWebhookPodConfiguration name format
ValidatePodConfigName = "%s-validate-pod"
// ValidatePodHookName Default name for webhooks in ValidatingWebhookPodConfiguration
ValidatePodHookName = "validatepod.volcano.sh"
)

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

// Prepare validate pods
path = "/pods"
PodValidateHooks := v1beta1.ValidatingWebhookConfiguration{
ObjectMeta: metav1.ObjectMeta{
Name: useGeneratedNameIfRequired("",
fmt.Sprintf(ValidatePodConfigName, c.AdmissionServiceName)),
},
Webhooks: []v1beta1.Webhook{{
Name: useGeneratedNameIfRequired("", ValidatePodHookName),
Rules: []v1beta1.RuleWithOperations{
{
Operations: []v1beta1.OperationType{v1beta1.Create},
Rule: v1beta1.Rule{
APIGroups: []string{""},
APIVersions: []string{"v1"},
Resources: []string{"pods"},
},
},
},
ClientConfig: v1beta1.WebhookClientConfig{
Service: &v1beta1.ServiceReference{
Name: c.AdmissionServiceName,
Namespace: c.AdmissionServiceNamespace,
Path: &path,
},
CABundle: cabundle,
},
FailurePolicy: &ignorePolicy,
}},
}

if err := registerValidateWebhook(clienset.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations(),
[]v1beta1.ValidatingWebhookConfiguration{PodValidateHooks}); err != nil {
return err
}

return nil

}
Expand Down
55 changes: 55 additions & 0 deletions cmd/admission/app/options/options_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
Copyright 2019 The Volcano Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package options

import (
"reflect"
"testing"

"github.com/spf13/pflag"
)

func TestAddFlags(t *testing.T) {
fs := pflag.NewFlagSet("addflagstest", pflag.ContinueOnError)
s := NewConfig()
s.AddFlags()

args := []string{
"--port=443",
"--webhook-namespace=default",
"--webhook-service-name=admission-service",
}
fs.Parse(args)

// This is a snapshot of expected options parsed by args.
expected := &Config{
Port: 443,
AdmissionServiceNamespace: "default",
AdmissionServiceName: "admission-service",
SchedulerName: defaultSchedulerName,
}

if !reflect.DeepEqual(expected, s) {
t.Errorf("Got different run options than expected.\nGot: %+v\nExpected: %+v\n", s, expected)
}

err := s.CheckPortOrDie()
if err != nil {
t.Errorf("expected nil but got %v\n", err)
}

}
72 changes: 4 additions & 68 deletions cmd/admission/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,13 @@ package app

import (
"crypto/tls"
"encoding/json"
"io/ioutil"
"net/http"

"github.com/golang/glog"
"volcano.sh/volcano/pkg/client/clientset/versioned"

"k8s.io/api/admission/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"

appConf "volcano.sh/volcano/cmd/admission/app/configure"
admissioncontroller "volcano.sh/volcano/pkg/admission"
)

const (
//CONTENTTYPE http content-type
CONTENTTYPE = "Content-Type"

//APPLICATIONJSON json content
APPLICATIONJSON = "application/json"
appConf "volcano.sh/volcano/cmd/admission/app/options"
"volcano.sh/volcano/pkg/client/clientset/versioned"
)

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

//GetKubeBatchClient get a clientset for kubebatch
func GetKubeBatchClient(restConfig *restclient.Config) *versioned.Clientset {
// GetVolcanoClient get a clientset for volcano
func GetVolcanoClient(restConfig *restclient.Config) *versioned.Clientset {
clientset, err := versioned.NewForConfig(restConfig)
if err != nil {
glog.Fatal(err)
Expand Down Expand Up @@ -89,52 +74,3 @@ func ConfigTLS(config *appConf.Config, restConfig *restclient.Config) *tls.Confi
glog.Fatal("tls: failed to find any tls config data")
return &tls.Config{}
}

//Serve the http request
func Serve(w http.ResponseWriter, r *http.Request, admit admissioncontroller.AdmitFunc) {
var body []byte
if r.Body != nil {
if data, err := ioutil.ReadAll(r.Body); err == nil {
body = data
}
}

// verify the content type is accurate
contentType := r.Header.Get(CONTENTTYPE)
if contentType != APPLICATIONJSON {
glog.Errorf("contentType=%s, expect application/json", contentType)
return
}

var reviewResponse *v1beta1.AdmissionResponse
ar := v1beta1.AdmissionReview{}
deserializer := admissioncontroller.Codecs.UniversalDeserializer()
if _, _, err := deserializer.Decode(body, nil, &ar); err != nil {
reviewResponse = admissioncontroller.ToAdmissionResponse(err)
} else {
reviewResponse = admit(ar)
}
glog.V(3).Infof("sending response: %v", reviewResponse)

response := createResponse(reviewResponse, &ar)
resp, err := json.Marshal(response)
if err != nil {
glog.Error(err)
}
if _, err := w.Write(resp); err != nil {
glog.Error(err)
}
}

func createResponse(reviewResponse *v1beta1.AdmissionResponse, ar *v1beta1.AdmissionReview) v1beta1.AdmissionReview {
response := v1beta1.AdmissionReview{}
if reviewResponse != nil {
response.Response = reviewResponse
response.Response.UID = ar.Request.UID
}
// reset the Object and OldObject, they are not needed in a response.
ar.Request.Object = runtime.RawExtension{}
ar.Request.OldObject = runtime.RawExtension{}

return response
}
23 changes: 18 additions & 5 deletions cmd/admission/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,29 @@ package main

import (
"flag"
"github.com/golang/glog"
"io/ioutil"
"net/http"
"os"
"os/signal"
"strconv"
"syscall"

"github.com/golang/glog"

"k8s.io/client-go/tools/clientcmd"

"volcano.sh/volcano/cmd/admission/app"
appConf "volcano.sh/volcano/cmd/admission/app/configure"
appConf "volcano.sh/volcano/cmd/admission/app/options"
admissioncontroller "volcano.sh/volcano/pkg/admission"
"volcano.sh/volcano/pkg/version"
)

func serveJobs(w http.ResponseWriter, r *http.Request) {
app.Serve(w, r, admissioncontroller.AdmitJobs)
admissioncontroller.Serve(w, r, admissioncontroller.AdmitJobs)
}

func serveMutateJobs(w http.ResponseWriter, r *http.Request) {
app.Serve(w, r, admissioncontroller.MutateJobs)
admissioncontroller.Serve(w, r, admissioncontroller.MutateJobs)
}

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

admissioncontroller.KubeBatchClientSet = app.GetKubeBatchClient(restConfig)
admissioncontroller.VolcanoClientSet = app.GetVolcanoClient(restConfig)

servePods(config)

caBundle, err := ioutil.ReadFile(config.CaCertFile)
if err != nil {
Expand Down Expand Up @@ -101,3 +104,13 @@ func main() {
return
}
}

func servePods(config *appConf.Config) {
admController := &admissioncontroller.Controller{
VcClients: admissioncontroller.VolcanoClientSet,
SchedulerName: config.SchedulerName,
}
http.HandleFunc(admissioncontroller.AdmitPodPath, admController.ServerPods)

return
}
44 changes: 0 additions & 44 deletions hack/e2e-admission-config.yaml

This file was deleted.

3 changes: 3 additions & 0 deletions installer/helm/chart/volcano/templates/admission.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get"]
- apiGroups: ["scheduling.incubator.k8s.io", "scheduling.sigs.dev"]
resources: ["podgroups"]
verbs: ["get", "list", "watch"]

---
kind: ClusterRoleBinding
Expand Down
3 changes: 3 additions & 0 deletions installer/volcano-development.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get"]
- apiGroups: ["scheduling.incubator.k8s.io", "scheduling.sigs.dev"]
resources: ["podgroups"]
verbs: ["get", "list", "watch"]

---
kind: ClusterRoleBinding
Expand Down
Loading

0 comments on commit 069593a

Please sign in to comment.