Skip to content

Commit

Permalink
add validate_with_warn_tests
Browse files Browse the repository at this point in the history
  • Loading branch information
abbas-gheydi committed Apr 16, 2024
1 parent 2410e24 commit b4bfe42
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ Dockerfile.cross
*.swp
*.swo
*~
config.yaml
38 changes: 38 additions & 0 deletions internal/webhook/testdata/httpProxy_rls.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: echo
namespace: test
spec:
ingressClassName: private
virtualhost:
fqdn: test.example.local
routes:
- conditions:
- prefix: /
services:
- name: ingress-conformance-echo
port: 80
rateLimitPolicy:
global:
descriptors:
- entries:
- genericKey:
key: test.echo.limit1 # Namespace.Name.optional_Name
value: "3/m"
- requestHeaderValueMatch:
headers:
- name: foo
exact: bar
value: bar
- entries:
- genericKey:
key: test.echo.limit2 # Namespace.Name.optional_Name
value: "4/m"
- requestHeader:
headerName: id
descriptorKey: id
- entries:
- genericKey:
key: test.echo.limit3 # Namespace.Name.optional_Name
value: "30/m"
92 changes: 92 additions & 0 deletions internal/webhook/testdata/rls_AdmissionReview.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
kind: AdmissionReview
apiVersion: admission.k8s.io/v1
request:
uid: 7feb799c-8315-4364-9251-0cae98a9a64b
kind:
group: projectcontour.io
version: v1
kind: HTTPProxy
resource:
group: projectcontour.io
version: v1
resource: httpproxies
requestKind:
group: projectcontour.io
version: v1
kind: HTTPProxy
requestResource:
group: projectcontour.io
version: v1
resource: httpproxies
name: echo
namespace: test
operation: CREATE
userInfo:
username: docker-for-desktop
groups:
- system:masters
- system:authenticated
object:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
creationTimestamp: '2024-04-15T14:15:31Z'
generation: 1
managedFields:
- apiVersion: projectcontour.io/v1
fieldsType: FieldsV1
fieldsV1:
f:spec:
".": {}
f:ingressClassName: {}
f:routes: {}
f:virtualhost:
".": {}
f:fqdn: {}
manager: kubectl-create
operation: Update
time: '2024-04-15T14:15:31Z'
name: echo
namespace: test
uid: '04180731-f36a-4acd-a770-614279ba193d'
spec:
ingressClassName: private
routes:
- conditions:
- prefix: "/"
rateLimitPolicy:
global:
descriptors:
- entries:
- genericKey:
key: test.echo.limit1
value: 3/m
- requestHeaderValueMatch:
expectMatch: true
headers:
- exact: bar
name: foo
value: bar
- entries:
- genericKey:
key: test.echo.limit2
value: 4/m
- requestHeader:
descriptorKey: id
headerName: id
- entries:
- genericKey:
key: test.echo.limit3
value: 30/m
services:
- name: ingress-conformance-echo
port: 80
virtualhost:
fqdn: test.example.local
oldObject:
dryRun: false
options:
kind: CreateOptions
apiVersion: meta.k8s.io/v1
fieldManager: kubectl-create
4 changes: 2 additions & 2 deletions internal/webhook/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func validateV1(ar admissionv1.AdmissionReview, cache *cache.Cache) (*admissionv

response, err := cicnoc.check(cr)
//warning rules
response, err = validateWariningRules(response, err, cr, &warningValidatorRlsRules)
response, err = validateWarningRules(response, err, cr, &warningValidatorRlsRules)

return response, err

Expand All @@ -80,7 +80,7 @@ func validateV1(ar admissionv1.AdmissionReview, cache *cache.Cache) (*admissionv

response, err := cicnou.check(cr)
//warning rules
response, err = validateWariningRules(response, err, cr, &warningValidatorRlsRules)
response, err = validateWarningRules(response, err, cr, &warningValidatorRlsRules)

return response, err

Expand Down
2 changes: 1 addition & 1 deletion internal/webhook/validate_with_warn.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func validateWariningRules(response *admissionv1.AdmissionResponse, err *httpErr, request *checkRequest, checkers ...checker) (*admissionv1.AdmissionResponse, *httpErr) {
func validateWarningRules(response *admissionv1.AdmissionResponse, err *httpErr, request *checkRequest, checkers ...checker) (*admissionv1.AdmissionResponse, *httpErr) {
//If the request is rejected during rule checking, then do not process the warning rules.
if !response.Allowed {
return response, err
Expand Down
97 changes: 97 additions & 0 deletions internal/webhook/validate_with_warn_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package webhook

import (
"io"
"os"
"strings"
"testing"

contourv1 "github.com/projectcontour/contour/apis/projectcontour/v1"
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/util/yaml"
)

// getHTTPProxyFromYAML reads a YAML file containing an HTTPProxy object
// and returns the parsed HTTPProxy object.
func getHTTPProxyFromYAML(path string) (*contourv1.HTTPProxy, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()

httpProxyByte, err := io.ReadAll(file)
if err != nil {
return nil, err
}

httpProxyObject := &contourv1.HTTPProxy{}
err = yaml.Unmarshal(httpProxyByte, httpProxyObject)
return httpProxyObject, err
}

// Test_validateWarningRules is a unit test to validate the warning rules function.
func Test_validateWarningRules(t *testing.T) {
// Read HTTPProxy object from YAML file.
httpProxyObj, err := getHTTPProxyFromYAML("./testdata/httpProxy_rls.yaml")
if err != nil {
t.Error(err)
}

// Define test arguments.
request := struct {
givenResponse *admissionv1.AdmissionResponse
request *checkRequest
checkers []checker
}{
givenResponse: &admissionv1.AdmissionResponse{Allowed: true},
request: &checkRequest{newObj: httpProxyObj},
checkers: []checker{&rlsValidator{}},
}

// Test: An HTTPProxy with valid RLS configuration should not have warnings.
acceptedResponse, err := validateWarningRules(request.givenResponse, nil, request.request, request.checkers...)
if !acceptedResponse.Allowed {
t.Error("response for HTTPProxy with valid configuration should be allowed")
}
if len(acceptedResponse.Warnings) != 0 {
t.Errorf("response for HTTPProxy with valid configuration should not have any warning messages: %v", acceptedResponse.Warnings)
}

// Test: A request with incorrect configuration should trigger warnings.
request.request.newObj.Spec.Routes[0].RateLimitPolicy.Global.Descriptors[0].Entries[0].GenericKey.Key = "wrong.name.xx"
acceptedResponseWithWarn, err := validateWarningRules(request.givenResponse, nil, request.request, request.checkers...)
if len(acceptedResponseWithWarn.Warnings) == 0 {
t.Error("for request with incorrect configuration, warning should be sent")
}
}

func Test_acceptWithWarning(t *testing.T) {
type args struct {
message string
}
tests := []struct {
name string
args args
want *admissionv1.AdmissionResponse
}{
{
name: "msg with value less than 120 char",
args: args{message: "test"},
want: &admissionv1.AdmissionResponse{Allowed: true, Warnings: []string{"Rate Limit Config Error: test"}},
},
{
name: "msg with value more than 120 should truncate to 120",
args: args{message: strings.Repeat("a", 120)},
want: &admissionv1.AdmissionResponse{Allowed: true, Warnings: []string{"Rate Limit Config Error: " + strings.Repeat("a", 120-len("Rate Limit Config Error: "))}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, _ := acceptWithWarning(tt.args.message)
if tt.want.Warnings[0] != got.Warnings[0] {
t.Errorf("acceptWithWarning() got = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit b4bfe42

Please sign in to comment.