mirror of
https://github.com/marcel-dempers/docker-development-youtube-series.git
synced 2025-06-06 17:01:30 +00:00
169 lines
4.1 KiB
Go
169 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
"log"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
|
|
|
"os"
|
|
"fmt"
|
|
"path/filepath"
|
|
"k8s.io/client-go/kubernetes"
|
|
rest "k8s.io/client-go/rest"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
"k8s.io/client-go/util/homedir"
|
|
|
|
"flag"
|
|
"strconv"
|
|
"io/ioutil"
|
|
|
|
"k8s.io/api/admission/v1beta1"
|
|
"errors"
|
|
|
|
apiv1 "k8s.io/api/core/v1"
|
|
"encoding/json"
|
|
)
|
|
|
|
type ServerParameters struct {
|
|
port int // webhook server port
|
|
certFile string // path to the x509 certificate for https
|
|
keyFile string // path to the x509 private key matching `CertFile`
|
|
}
|
|
|
|
type patchOperation struct {
|
|
Op string `json:"op"`
|
|
Path string `json:"path"`
|
|
Value interface{} `json:"value,omitempty"`
|
|
}
|
|
|
|
var parameters ServerParameters
|
|
|
|
var (
|
|
universalDeserializer = serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer()
|
|
)
|
|
|
|
var config *rest.Config
|
|
var clientSet *kubernetes.Clientset
|
|
|
|
func main() {
|
|
|
|
useKubeConfig := os.Getenv("USE_KUBECONFIG")
|
|
kubeConfigFilePath := os.Getenv("KUBECONFIG")
|
|
|
|
flag.IntVar(¶meters.port, "port", 8443, "Webhook server port.")
|
|
flag.StringVar(¶meters.certFile, "tlsCertFile", "/etc/webhook/certs/tls.crt", "File containing the x509 Certificate for HTTPS.")
|
|
flag.StringVar(¶meters.keyFile, "tlsKeyFile", "/etc/webhook/certs/tls.key", "File containing the x509 private key to --tlsCertFile.")
|
|
flag.Parse()
|
|
|
|
if len(useKubeConfig) == 0 {
|
|
// default to service account in cluster token
|
|
c, err := rest.InClusterConfig()
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
config = c
|
|
} else {
|
|
//load from a kube config
|
|
var kubeconfig string
|
|
|
|
if kubeConfigFilePath == "" {
|
|
if home := homedir.HomeDir(); home != "" {
|
|
kubeconfig = filepath.Join(home, ".kube", "config")
|
|
}
|
|
} else {
|
|
kubeconfig = kubeConfigFilePath
|
|
}
|
|
|
|
fmt.Println("kubeconfig: " + kubeconfig)
|
|
|
|
c, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
config = c
|
|
}
|
|
|
|
cs, err := kubernetes.NewForConfig(config)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
clientSet = cs
|
|
|
|
test()
|
|
http.HandleFunc("/", HandleRoot)
|
|
http.HandleFunc("/mutate", HandleMutate)
|
|
log.Fatal(http.ListenAndServeTLS(":" + strconv.Itoa(parameters.port), parameters.certFile, parameters.keyFile, nil))
|
|
}
|
|
|
|
func HandleRoot(w http.ResponseWriter, r *http.Request){
|
|
w.Write([]byte("HandleRoot!"))
|
|
}
|
|
|
|
func HandleMutate(w http.ResponseWriter, r *http.Request){
|
|
|
|
body, err := ioutil.ReadAll(r.Body)
|
|
err = ioutil.WriteFile("/tmp/request", body, 0644)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
var admissionReviewReq v1beta1.AdmissionReview
|
|
|
|
if _, _, err := universalDeserializer.Decode(body, nil, &admissionReviewReq); err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
fmt.Errorf("could not deserialize request: %v", err)
|
|
} else if admissionReviewReq.Request == nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
errors.New("malformed admission review: request is nil")
|
|
}
|
|
|
|
fmt.Printf("Type: %v \t Event: %v \t Name: %v \n",
|
|
admissionReviewReq.Request.Kind,
|
|
admissionReviewReq.Request.Operation,
|
|
admissionReviewReq.Request.Name,
|
|
)
|
|
|
|
var pod apiv1.Pod
|
|
|
|
err = json.Unmarshal(admissionReviewReq.Request.Object.Raw, &pod)
|
|
|
|
if err != nil {
|
|
fmt.Errorf("could not unmarshal pod on admission request: %v", err)
|
|
}
|
|
|
|
var patches []patchOperation
|
|
|
|
labels := pod.ObjectMeta.Labels
|
|
labels["example-webhook"] = "it-worked"
|
|
|
|
patches = append(patches, patchOperation{
|
|
Op: "add",
|
|
Path: "/metadata/labels",
|
|
Value: labels,
|
|
})
|
|
|
|
patchBytes, err := json.Marshal(patches)
|
|
|
|
if err != nil {
|
|
fmt.Errorf("could not marshal JSON patch: %v", err)
|
|
}
|
|
|
|
|
|
admissionReviewResponse := v1beta1.AdmissionReview{
|
|
Response: &v1beta1.AdmissionResponse{
|
|
UID: admissionReviewReq.Request.UID,
|
|
Allowed: true,
|
|
},
|
|
}
|
|
|
|
admissionReviewResponse.Response.Patch = patchBytes
|
|
|
|
bytes, err := json.Marshal(&admissionReviewResponse)
|
|
if err != nil {
|
|
fmt.Errorf("marshaling response: %v", err)
|
|
}
|
|
|
|
w.Write(bytes)
|
|
|
|
} |