first functional test
This commit is contained in:
parent
9dd4366e73
commit
3f60d34155
@ -57,7 +57,7 @@ func httpServer(cfg *config.Config) {
|
||||
WriteTimeout: time.Duration(cfg.WebServerWriteTimeout) * time.Second,
|
||||
IdleTimeout: time.Duration(cfg.WebServerIdleTimeout) * time.Second,
|
||||
TLSConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
CipherSuites: []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
@ -72,31 +72,18 @@ func httpServer(cfg *config.Config) {
|
||||
},
|
||||
}
|
||||
|
||||
ah := &admissionHandler{
|
||||
decoder: serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer(),
|
||||
}
|
||||
|
||||
// healthcheck
|
||||
path.HandleFunc("/healthcheck", func(w http.ResponseWriter, r *http.Request) {
|
||||
webHealthCheck(w, r)
|
||||
})
|
||||
path.HandleFunc("/healthcheck", webHealthCheck)
|
||||
// pod admission
|
||||
path.HandleFunc("/api/v1/admit/pod", func(w http.ResponseWriter, r *http.Request) {
|
||||
ah := &admissionHandler{
|
||||
decoder: serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer(),
|
||||
}
|
||||
ah.Serve(operations.PodsValidation())
|
||||
})
|
||||
path.HandleFunc("/api/v1/admit/pod", ah.Serve(operations.PodsValidation()))
|
||||
// deployment admission
|
||||
path.HandleFunc("/api/v1/admit/deployemnt", func(w http.ResponseWriter, r *http.Request) {
|
||||
ah := &admissionHandler{
|
||||
decoder: serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer(),
|
||||
}
|
||||
ah.Serve(operations.DeploymentsValidation())
|
||||
})
|
||||
path.HandleFunc("/api/v1/admit/deployment", ah.Serve(operations.DeploymentsValidation()))
|
||||
// pod mutation
|
||||
path.HandleFunc("/api/v1/mutate/pod", func(w http.ResponseWriter, r *http.Request) {
|
||||
ah := &admissionHandler{
|
||||
decoder: serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer(),
|
||||
}
|
||||
ah.Serve(operations.PodsMutation())
|
||||
})
|
||||
path.HandleFunc("/api/v1/mutate/pod", ah.Serve(operations.PodsMutation()))
|
||||
// web root
|
||||
path.HandleFunc("/", webRoot)
|
||||
|
||||
@ -148,7 +135,7 @@ func (h *admissionHandler) Serve(hook operations.Hook) http.HandlerFunc {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if r.Method != http.MethodPost {
|
||||
msg := "malformed admission review: request is nil"
|
||||
msg := fmt.Sprintf("incorrect method: got request type %s, expected request type %s", r.Method, http.MethodPost)
|
||||
log.Printf("[TRACE] %s", msg)
|
||||
tmpltError(w, http.StatusMethodNotAllowed, msg)
|
||||
return
|
||||
|
6
go.mod
6
go.mod
@ -4,8 +4,8 @@ go 1.19
|
||||
|
||||
require (
|
||||
github.com/hashicorp/logutils v1.0.0
|
||||
k8s.io/api v0.26.2
|
||||
k8s.io/apimachinery v0.26.2
|
||||
k8s.io/api v0.26.3
|
||||
k8s.io/apimachinery v0.26.3
|
||||
)
|
||||
|
||||
require (
|
||||
@ -20,7 +20,7 @@ require (
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
k8s.io/utils v0.0.0-20230308161112-d77c459e9343 // indirect
|
||||
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
|
12
go.sum
12
go.sum
@ -68,14 +68,14 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ=
|
||||
k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU=
|
||||
k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ=
|
||||
k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
|
||||
k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU=
|
||||
k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE=
|
||||
k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k=
|
||||
k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
|
||||
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
|
||||
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/utils v0.0.0-20230308161112-d77c459e9343 h1:m7tbIjXGcGIAtpmQr7/NAi7RsWoW3E7Zcm4jI1HicTc=
|
||||
k8s.io/utils v0.0.0-20230308161112-d77c459e9343/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 h1:xMMXJlJbsU8w3V5N2FLDQ8YgU8s1EoULdbQBcAeNJkY=
|
||||
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
|
26
internal/operations/parsers.go
Normal file
26
internal/operations/parsers.go
Normal file
@ -0,0 +1,26 @@
|
||||
package operations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
dep "k8s.io/api/apps/v1"
|
||||
pod "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func parseDeployment(object []byte) (*dep.Deployment, error) {
|
||||
var dp dep.Deployment
|
||||
if err := json.Unmarshal(object, &dp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &dp, nil
|
||||
}
|
||||
|
||||
func parsePod(object []byte) (*pod.Pod, error) {
|
||||
var pod pod.Pod
|
||||
if err := json.Unmarshal(object, &pod); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pod, nil
|
||||
}
|
@ -1,5 +1,30 @@
|
||||
package operations
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
admission "k8s.io/api/admission/v1"
|
||||
)
|
||||
|
||||
func PodsValidation() Hook {
|
||||
return Hook{}
|
||||
return Hook{
|
||||
Create: podValidationCreate(),
|
||||
}
|
||||
}
|
||||
|
||||
func podValidationCreate() AdmitFunc {
|
||||
return func(r *admission.AdmissionRequest) (*Result, error) {
|
||||
pod, err := parsePod(r.Object.Raw)
|
||||
if err != nil {
|
||||
return &Result{Msg: err.Error()}, nil
|
||||
}
|
||||
|
||||
for _, c := range pod.Spec.Containers {
|
||||
if strings.HasSuffix(c.Image, ":latest") {
|
||||
return &Result{Msg: "You cannot use the tag 'latest' in a container."}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &Result{Allowed: true}, nil
|
||||
}
|
||||
}
|
||||
|
27
mock-payloads/readme.md
Normal file
27
mock-payloads/readme.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Example Curl Requests
|
||||
|
||||
## Pod Admission
|
||||
|
||||
Request
|
||||
```bash
|
||||
curl \
|
||||
--insecure \
|
||||
--silent \
|
||||
--request POST \
|
||||
--header "Content-Type: application/json" \
|
||||
--data @./mock-payloads/pods/test-pod01.json \
|
||||
https://localhost:8443/api/v1/admit/pod
|
||||
```
|
||||
Response
|
||||
```json
|
||||
{
|
||||
"response": {
|
||||
"uid": "60df4b0b-8856-4ce7-9fb3-bc8034856995",
|
||||
"allowed": false,
|
||||
"status": {
|
||||
"metadata": {},
|
||||
"message": "You cannot use the tag 'latest' in a container."
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user