diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index dbb0e05e2d3c7..2ed41c0cbbfac 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -240,6 +240,11 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { ep.IP = fmt.Sprintf("%d.%d.%d.%d", c.Rand.Intn(256), c.Rand.Intn(256), c.Rand.Intn(256), c.Rand.Intn(256)) ep.Port = c.Rand.Intn(65536) }, + func(http *api.HTTPGetAction, c fuzz.Continue) { + http.Path = "/" + c.RandString() // can't be blank + c.Fuzz(&http.Port) + c.Fuzz(&http.Host) + }, ) return f } diff --git a/pkg/api/v1beta1/defaults.go b/pkg/api/v1beta1/defaults.go index 7c9042dea329f..2e20d58a8e77c 100644 --- a/pkg/api/v1beta1/defaults.go +++ b/pkg/api/v1beta1/defaults.go @@ -90,5 +90,10 @@ func init() { obj.Protocol = "TCP" } }, + func(obj *HTTPGetAction) { + if obj.Path == "" { + obj.Path = "/" + } + }, ) } diff --git a/pkg/api/v1beta2/defaults.go b/pkg/api/v1beta2/defaults.go index db59b8cd272ee..61433932d0971 100644 --- a/pkg/api/v1beta2/defaults.go +++ b/pkg/api/v1beta2/defaults.go @@ -92,5 +92,10 @@ func init() { obj.Protocol = "TCP" } }, + func(obj *HTTPGetAction) { + if obj.Path == "" { + obj.Path = "/" + } + }, ) } diff --git a/pkg/api/v1beta3/defaults.go b/pkg/api/v1beta3/defaults.go index 55c867c3614dd..e297c7354a4a3 100644 --- a/pkg/api/v1beta3/defaults.go +++ b/pkg/api/v1beta3/defaults.go @@ -85,5 +85,10 @@ func init() { obj.Protocol = "TCP" } }, + func(obj *HTTPGetAction) { + if obj.Path == "" { + obj.Path = "/" + } + }, ) } diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index d3b12f8d44bcd..97cc76a511a86 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -451,6 +451,21 @@ func validateHTTPGetAction(http *api.HTTPGetAction) errs.ValidationErrorList { if len(http.Path) == 0 { allErrors = append(allErrors, errs.NewFieldRequired("path", http.Path)) } + if http.Port.Kind == util.IntstrInt && !util.IsValidPortNum(http.Port.IntVal) { + allErrors = append(allErrors, errs.NewFieldInvalid("port", http.Port, portRangeErrorMsg)) + } else if http.Port.Kind == util.IntstrString && len(http.Port.StrVal) == 0 { + allErrors = append(allErrors, errs.NewFieldRequired("port", http.Port.StrVal)) + } + return allErrors +} + +func validateTCPSocketAction(tcp *api.TCPSocketAction) errs.ValidationErrorList { + allErrors := errs.ValidationErrorList{} + if tcp.Port.Kind == util.IntstrInt && !util.IsValidPortNum(tcp.Port.IntVal) { + allErrors = append(allErrors, errs.NewFieldInvalid("port", tcp.Port, portRangeErrorMsg)) + } else if tcp.Port.Kind == util.IntstrString && len(tcp.Port.StrVal) == 0 { + allErrors = append(allErrors, errs.NewFieldRequired("port", tcp.Port.StrVal)) + } return allErrors } @@ -465,6 +480,10 @@ func validateHandler(handler *api.Handler) errs.ValidationErrorList { numHandlers++ allErrors = append(allErrors, validateHTTPGetAction(handler.HTTPGet).Prefix("httpGet")...) } + if handler.TCPSocket != nil { + numHandlers++ + allErrors = append(allErrors, validateTCPSocketAction(handler.TCPSocket).Prefix("tcpSocket")...) + } if numHandlers != 1 { allErrors = append(allErrors, errs.NewFieldInvalid("", handler, "exactly 1 handler type is required")) } @@ -662,6 +681,11 @@ func ValidateService(service *api.Service) errs.ValidationErrorList { } else if !supportedPortProtocols.Has(strings.ToUpper(string(service.Spec.Protocol))) { allErrs = append(allErrs, errs.NewFieldNotSupported("spec.protocol", service.Spec.Protocol)) } + if service.Spec.ContainerPort.Kind == util.IntstrInt && service.Spec.ContainerPort.IntVal != 0 && !util.IsValidPortNum(service.Spec.ContainerPort.IntVal) { + allErrs = append(allErrs, errs.NewFieldInvalid("spec.containerPort", service.Spec.Port, portRangeErrorMsg)) + } else if service.Spec.ContainerPort.Kind == util.IntstrString && len(service.Spec.ContainerPort.StrVal) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("spec.containerPort", service.Spec.ContainerPort.StrVal)) + } if service.Spec.Selector != nil { allErrs = append(allErrs, ValidateLabels(service.Spec.Selector, "spec.selector")...) diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index ca2ac42f8dd9f..ba82c783c6c5c 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -331,6 +331,33 @@ func TestValidateProbe(t *testing.T) { } } +func TestValidateHandler(t *testing.T) { + successCases := []api.Handler{ + {Exec: &api.ExecAction{Command: []string{"echo"}}}, + {HTTPGet: &api.HTTPGetAction{Path: "/", Port: util.NewIntOrStringFromInt(1), Host: ""}}, + {HTTPGet: &api.HTTPGetAction{Path: "/foo", Port: util.NewIntOrStringFromInt(65535), Host: "host"}}, + {HTTPGet: &api.HTTPGetAction{Path: "/", Port: util.NewIntOrStringFromString("port"), Host: ""}}, + } + for _, h := range successCases { + if errs := validateHandler(&h); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := []api.Handler{ + {}, + {Exec: &api.ExecAction{Command: []string{}}}, + {HTTPGet: &api.HTTPGetAction{Path: "", Port: util.NewIntOrStringFromInt(0), Host: ""}}, + {HTTPGet: &api.HTTPGetAction{Path: "/foo", Port: util.NewIntOrStringFromInt(65536), Host: "host"}}, + {HTTPGet: &api.HTTPGetAction{Path: "", Port: util.NewIntOrStringFromString(""), Host: ""}}, + } + for _, h := range errorCases { + if errs := validateHandler(&h); len(errs) == 0 { + t.Errorf("expected failure for %#v", h) + } + } +} + func TestValidatePullPolicy(t *testing.T) { type T struct { Container api.Container