Enable ability to flip configuration of allownomutate
This commit is contained in:
parent
80ef925ff4
commit
8094816911
@ -37,7 +37,7 @@ func strictTransport(w http.ResponseWriter) {
|
||||
w.Header().Add("Strict-Transport-Security", "max-age=63072000")
|
||||
}
|
||||
|
||||
func httpServer(cfg *config.Config) {
|
||||
func httpServer() {
|
||||
var serverCertificate tls.Certificate
|
||||
if config.DefaultConfig().WebServerCertificate == "" || cfg.WebServerKey == "" {
|
||||
log.Printf("[INFO] No webserver certificate configured, automatically generating self signed certificate.")
|
||||
@ -73,11 +73,7 @@ func httpServer(cfg *config.Config) {
|
||||
|
||||
ah := &admissionHandler{
|
||||
decoder: serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer(),
|
||||
config: cfg,
|
||||
}
|
||||
|
||||
wh := &webHandler{
|
||||
config: cfg,
|
||||
config: &cfg,
|
||||
}
|
||||
|
||||
// pod admission
|
||||
@ -87,18 +83,14 @@ func httpServer(cfg *config.Config) {
|
||||
// pod mutation
|
||||
path.HandleFunc("/api/v1/mutate/pod", ah.ahServe(operations.PodsMutation()))
|
||||
// web root
|
||||
path.HandleFunc("/", wh.webServe())
|
||||
path.HandleFunc("/", webServe())
|
||||
|
||||
if err := connection.ListenAndServeTLS("", ""); err != nil {
|
||||
log.Fatalf("[ERROR] %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
type webHandler struct {
|
||||
config *config.Config
|
||||
}
|
||||
|
||||
func (h *webHandler) webServe() http.HandlerFunc {
|
||||
func webServe() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
httpAccessLog(r)
|
||||
crossSiteOrigin(w)
|
||||
@ -112,7 +104,7 @@ func (h *webHandler) webServe() http.HandlerFunc {
|
||||
case r.URL.Path == "/healthcheck":
|
||||
tmpltHealthCheck(w)
|
||||
case r.URL.Path == "/":
|
||||
tmpltWebRoot(w, r.URL.Query(), *h.config)
|
||||
tmpltWebRoot(w, r.URL.Query())
|
||||
default:
|
||||
msg := fmt.Sprintf("Unable to locate requested path: '%s'", r.URL.Path)
|
||||
log.Printf("[DEBUG] %s", msg)
|
||||
@ -170,7 +162,7 @@ func (h *admissionHandler) ahServe(hook operations.Hook) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
result, err := hook.Execute(review.Request, h.config)
|
||||
result, err := hook.Execute(review.Request, &cfg)
|
||||
if err != nil {
|
||||
msg := err.Error()
|
||||
log.Printf("[ERROR] Internal Server Error: %s", msg)
|
||||
|
@ -7,8 +7,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"mutating-webhook/internal/config"
|
||||
)
|
||||
|
||||
const cT string = "Content-Type"
|
||||
@ -56,7 +54,7 @@ func tmpltHealthCheck(w http.ResponseWriter) {
|
||||
w.Write(output) //nolint:errcheck
|
||||
}
|
||||
|
||||
func tmpltWebRoot(w http.ResponseWriter, urlPrams url.Values, cfg config.Config) {
|
||||
func tmpltWebRoot(w http.ResponseWriter, urlPrams url.Values) {
|
||||
o := struct {
|
||||
Application string `json:"application" yaml:"application"`
|
||||
Description string `json:"description" yaml:"description"`
|
||||
|
@ -10,6 +10,9 @@ import (
|
||||
"mutating-webhook/internal/config"
|
||||
)
|
||||
|
||||
// global configuration
|
||||
var cfg config.Config
|
||||
|
||||
func forever() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
@ -24,9 +27,9 @@ func main() {
|
||||
}()
|
||||
|
||||
// initialize application configuration
|
||||
cfg := config.Init()
|
||||
cfg = config.Init()
|
||||
|
||||
go httpServer(cfg)
|
||||
go httpServer()
|
||||
|
||||
forever()
|
||||
}
|
||||
|
@ -41,8 +41,8 @@ type Config struct {
|
||||
}
|
||||
|
||||
// DefaultConfig initializes the config variable for use with a prepared set of defaults.
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
func DefaultConfig() Config {
|
||||
return Config{
|
||||
Log: &logutils.LevelFilter{
|
||||
Levels: []logutils.LogLevel{"TRACE", "DEBUG", "INFO", "WARNING", "ERROR"},
|
||||
Writer: os.Stderr,
|
||||
@ -50,7 +50,7 @@ func DefaultConfig() *Config {
|
||||
}
|
||||
}
|
||||
|
||||
func (cfg *Config) setLogLevel() {
|
||||
func setLogLevel(cfg Config) {
|
||||
switch {
|
||||
case cfg.LogLevel <= 20:
|
||||
cfg.Log.SetMinLevel(logutils.LogLevel("ERROR"))
|
||||
@ -66,7 +66,7 @@ func (cfg *Config) setLogLevel() {
|
||||
log.SetOutput(cfg.Log)
|
||||
}
|
||||
|
||||
func (cfg *Config) printRunningConfig(cfgInfo []StructInfo) {
|
||||
func printRunningConfig(cfg *Config, cfgInfo []StructInfo) {
|
||||
log.Printf("[DEBUG] Current Running Configuration Values:")
|
||||
for _, info := range cfgInfo {
|
||||
switch info.Type.String() {
|
||||
|
@ -19,10 +19,10 @@ func getOSEnv(env, def string) string {
|
||||
// Init initializes the application configuration by reading default values from the struct's tags
|
||||
// and environment variables. Tags processed by this process are as follows:
|
||||
// `ignored:"true" env:"ENVIRONMENT_VARIABLE" default:"default value"`
|
||||
func Init() *Config {
|
||||
func Init() Config {
|
||||
cfg := DefaultConfig()
|
||||
|
||||
cfgInfo, err := getStructInfo(cfg)
|
||||
cfgInfo, err := getStructInfo(&cfg)
|
||||
if err != nil {
|
||||
log.Fatalf("[FATAL] %v", err)
|
||||
}
|
||||
@ -34,7 +34,7 @@ func Init() *Config {
|
||||
if info.DefaultValue != nil {
|
||||
dv = info.DefaultValue.(string)
|
||||
}
|
||||
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*string)
|
||||
p := reflect.ValueOf(&cfg).Elem().FieldByName(info.Name).Addr().Interface().(*string)
|
||||
flag.StringVar(p, info.Name, dv, "("+info.Key+")")
|
||||
|
||||
case "bool":
|
||||
@ -42,7 +42,7 @@ func Init() *Config {
|
||||
if info.DefaultValue != nil {
|
||||
dv = info.DefaultValue.(bool)
|
||||
}
|
||||
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*bool)
|
||||
p := reflect.ValueOf(&cfg).Elem().FieldByName(info.Name).Addr().Interface().(*bool)
|
||||
flag.BoolVar(p, info.Name, dv, "("+info.Key+")")
|
||||
|
||||
case "int":
|
||||
@ -50,14 +50,14 @@ func Init() *Config {
|
||||
if info.DefaultValue != nil {
|
||||
dv = int(info.DefaultValue.(int64))
|
||||
}
|
||||
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*int)
|
||||
p := reflect.ValueOf(&cfg).Elem().FieldByName(info.Name).Addr().Interface().(*int)
|
||||
flag.IntVar(p, info.Name, dv, "("+info.Key+")")
|
||||
}
|
||||
}
|
||||
flag.Parse()
|
||||
|
||||
// set logging level
|
||||
cfg.setLogLevel()
|
||||
setLogLevel(cfg)
|
||||
|
||||
// timezone & format configuration
|
||||
cfg.TZoneUTC, _ = time.LoadLocation("UTC")
|
||||
@ -71,7 +71,7 @@ func Init() *Config {
|
||||
time.Now().Format(cfg.TimeFormat)
|
||||
|
||||
// print running config
|
||||
cfg.printRunningConfig(cfgInfo)
|
||||
printRunningConfig(&cfg, cfgInfo)
|
||||
|
||||
// read config file
|
||||
configFileData, err := getConfigFileData(cfg.ConfigFile)
|
||||
|
@ -1,24 +1,24 @@
|
||||
package operations
|
||||
|
||||
import (
|
||||
"mutating-webhook/internal/config"
|
||||
|
||||
admission "k8s.io/api/admission/v1"
|
||||
|
||||
"mutating-webhook/internal/config"
|
||||
)
|
||||
|
||||
func DeploymentsValidation() Hook {
|
||||
return Hook{
|
||||
// default allow
|
||||
Create: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Create: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
Delete: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Delete: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
Update: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Update: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
Connect: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Connect: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ package operations
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"mutating-webhook/internal/config"
|
||||
|
||||
admission "k8s.io/api/admission/v1"
|
||||
|
||||
"mutating-webhook/internal/config"
|
||||
)
|
||||
|
||||
// Result contains the result of an admission request
|
||||
@ -18,7 +18,7 @@ type Result struct {
|
||||
}
|
||||
|
||||
// AdmitFunc defines how to process an admission request
|
||||
type AdmitFunc func(request *admission.AdmissionRequest, cfg config.Config) (*Result, error)
|
||||
type AdmitFunc func(request *admission.AdmissionRequest, cfg *config.Config) (*Result, error)
|
||||
|
||||
// Hook represents the set of functions for each operation in an admission webhook.
|
||||
type Hook struct {
|
||||
@ -32,19 +32,19 @@ type Hook struct {
|
||||
func (h *Hook) Execute(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
switch r.Operation {
|
||||
case admission.Create:
|
||||
return wrapperExecution(h.Create, r, *cfg)
|
||||
return wrapperExecution(h.Create, r, cfg)
|
||||
case admission.Update:
|
||||
return wrapperExecution(h.Update, r, *cfg)
|
||||
return wrapperExecution(h.Update, r, cfg)
|
||||
case admission.Delete:
|
||||
return wrapperExecution(h.Delete, r, *cfg)
|
||||
return wrapperExecution(h.Delete, r, cfg)
|
||||
case admission.Connect:
|
||||
return wrapperExecution(h.Connect, r, *cfg)
|
||||
return wrapperExecution(h.Connect, r, cfg)
|
||||
}
|
||||
|
||||
return &Result{Msg: fmt.Sprintf("Invalid operation: %s", r.Operation)}, nil
|
||||
}
|
||||
|
||||
func wrapperExecution(fn AdmitFunc, r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
func wrapperExecution(fn AdmitFunc, r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
if fn == nil {
|
||||
return nil, fmt.Errorf("operation %s is not registered", r.Operation)
|
||||
}
|
||||
|
@ -3,30 +3,30 @@ package operations
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"mutating-webhook/internal/config"
|
||||
|
||||
admission "k8s.io/api/admission/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
|
||||
"mutating-webhook/internal/config"
|
||||
)
|
||||
|
||||
func PodsMutation() Hook {
|
||||
return Hook{
|
||||
Create: podMutationCreate(),
|
||||
// default allow
|
||||
Delete: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Delete: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
Update: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Update: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
Connect: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Connect: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func podMutationCreate() AdmitFunc {
|
||||
return func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
return func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
var operations []PatchOperation
|
||||
pod, err := parsePod(r.Object.Raw)
|
||||
if err != nil {
|
||||
|
@ -4,31 +4,31 @@ import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"mutating-webhook/internal/config"
|
||||
|
||||
admission "k8s.io/api/admission/v1"
|
||||
|
||||
"mutating-webhook/internal/config"
|
||||
)
|
||||
|
||||
func PodsValidation() Hook {
|
||||
return Hook{
|
||||
// default allow
|
||||
Create: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Create: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
Delete: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Delete: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
Update: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Update: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
Connect: func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
Connect: func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
return &Result{Allowed: true}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func podValidationCreate() AdmitFunc {
|
||||
return func(r *admission.AdmissionRequest, cfg config.Config) (*Result, error) {
|
||||
return func(r *admission.AdmissionRequest, cfg *config.Config) (*Result, error) {
|
||||
pod, err := parsePod(r.Object.Raw)
|
||||
if err != nil {
|
||||
return &Result{Msg: err.Error()}, nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user