Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add admitPod #370

Merged
merged 1 commit into from
Aug 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why donot you keep consistent with L54-55?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because pods need client and parameter。


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
17 changes: 15 additions & 2 deletions pkg/admission/admission_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,31 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"

"volcano.sh/volcano/pkg/apis/batch/v1alpha1"
vcver "volcano.sh/volcano/pkg/client/clientset/versioned"
)

const (
//AdmitJobPath is the pattern for the jobs admission
// AdmitJobPath is the pattern for the jobs admission
AdmitJobPath = "/jobs"
//MutateJobPath is the pattern for the mutating jobs
// MutateJobPath is the pattern for the mutating jobs
MutateJobPath = "/mutating-jobs"
// AdmitPodPath is the pattern for the pods admission
AdmitPodPath = "/pods"
// CONTENTTYPE http content-type
CONTENTTYPE = "Content-Type"
// APPLICATIONJSON json content
APPLICATIONJSON = "application/json"
)

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

// Controller the Admission Controller type
type Controller struct {
VcClients vcver.Interface
SchedulerName string
}

var scheme = runtime.NewScheme()

//Codecs is for retrieving serializers for the supported wire formats
Expand Down
10 changes: 5 additions & 5 deletions pkg/admission/admit_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"strings"

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

"k8s.io/api/admission/v1beta1"
"k8s.io/api/core/v1"
Expand All @@ -33,11 +32,12 @@ import (
k8scorevalid "k8s.io/kubernetes/pkg/apis/core/validation"

"volcano.sh/volcano/pkg/apis/batch/v1alpha1"
"volcano.sh/volcano/pkg/client/clientset/versioned"
"volcano.sh/volcano/pkg/controllers/job/plugins"
)

// KubeBatchClientSet is volcano clientset
var KubeBatchClientSet versioned.Interface
// VolcanoClientSet is volcano clientset
var VolcanoClientSet versioned.Interface

// AdmitJobs is to admit jobs and return response
func AdmitJobs(ar v1beta1.AdmissionReview) *v1beta1.AdmissionResponse {
Expand Down Expand Up @@ -151,9 +151,9 @@ func validateJob(job v1alpha1.Job, reviewResponse *v1beta1.AdmissionResponse) st
}

// Check whether Queue already present or not
if _, err := KubeBatchClientSet.SchedulingV1alpha2().Queues().Get(job.Spec.Queue, metav1.GetOptions{}); err != nil {
if _, err := VolcanoClientSet.SchedulingV1alpha2().Queues().Get(job.Spec.Queue, metav1.GetOptions{}); err != nil {
// TODO: deprecate v1alpha1
if _, err := KubeBatchClientSet.SchedulingV1alpha1().Queues().Get(job.Spec.Queue, metav1.GetOptions{}); err != nil {
if _, err := VolcanoClientSet.SchedulingV1alpha1().Queues().Get(job.Spec.Queue, metav1.GetOptions{}); err != nil {
msg = msg + fmt.Sprintf(" unable to find job queue: %v", err)
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/admission/admit_job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -957,10 +957,10 @@ func TestValidateExecution(t *testing.T) {
},
}
// create fake volcano clientset
KubeBatchClientSet = fakeclient.NewSimpleClientset()
VolcanoClientSet = fakeclient.NewSimpleClientset()

//create default queue
_, err := KubeBatchClientSet.SchedulingV1alpha2().Queues().Create(&defaultqueue)
_, err := VolcanoClientSet.SchedulingV1alpha2().Queues().Create(&defaultqueue)
if err != nil {
t.Error("Queue Creation Failed")
}
Expand Down
Loading