Skip to content

Commit 7c716c2

Browse files
committed
Validation for Backends, BackendTrafficPolicies, HTTPRouteFilters, and SecurityPolicies.
The next set of changes will add validation options to BackendTrafficPolicies, and wire validation options in from the service configuration. In the future, many of these limits may be influenced by quotas.
1 parent 2d11c56 commit 7c716c2

10 files changed

Lines changed: 1164 additions & 33 deletions

internal/validation/backend_validation.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,36 @@ package validation
33
import (
44
envoygatewayv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1"
55
"k8s.io/apimachinery/pkg/util/validation/field"
6+
"k8s.io/utils/ptr"
67
)
78

89
func ValidateBackend(backend *envoygatewayv1alpha1.Backend) field.ErrorList {
9-
return nil
10+
allErrs := field.ErrorList{}
11+
12+
specPath := field.NewPath("spec")
13+
14+
if ptr.Deref(backend.Spec.Type, envoygatewayv1alpha1.BackendTypeEndpoints) != envoygatewayv1alpha1.BackendTypeEndpoints {
15+
supportedTypes := []envoygatewayv1alpha1.BackendType{envoygatewayv1alpha1.BackendTypeEndpoints}
16+
allErrs = append(allErrs, field.NotSupported(specPath.Child("type"), backend.Spec.Type, supportedTypes))
17+
}
18+
19+
allErrs = append(allErrs, validateBackendEndpoints(backend.Spec.Endpoints, specPath.Child("endpoints"))...)
20+
21+
// appProtocols, fallback, and TLS settings are considered safe to leverage as is.
22+
23+
return allErrs
24+
}
25+
26+
func validateBackendEndpoints(endpoints []envoygatewayv1alpha1.BackendEndpoint, fldPath *field.Path) field.ErrorList {
27+
allErrs := field.ErrorList{}
28+
29+
for i, endpoint := range endpoints {
30+
endpointPath := fldPath.Index(i)
31+
32+
if endpoint.Unix != nil {
33+
allErrs = append(allErrs, field.Forbidden(endpointPath.Child("unix"), "unix endpoints are not permitted"))
34+
}
35+
}
36+
37+
return allErrs
1038
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package validation
2+
3+
import (
4+
"testing"
5+
6+
envoygatewayv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1"
7+
"github.com/google/go-cmp/cmp"
8+
"github.com/google/go-cmp/cmp/cmpopts"
9+
"k8s.io/apimachinery/pkg/util/validation/field"
10+
"k8s.io/utils/ptr"
11+
)
12+
13+
func TestValidateBackend(t *testing.T) {
14+
scenarios := map[string]struct {
15+
backend *envoygatewayv1alpha1.Backend
16+
expectedErrors field.ErrorList
17+
}{
18+
"invalid backend type": {
19+
backend: &envoygatewayv1alpha1.Backend{
20+
Spec: envoygatewayv1alpha1.BackendSpec{
21+
Type: ptr.To(envoygatewayv1alpha1.BackendTypeDynamicResolver),
22+
},
23+
},
24+
expectedErrors: field.ErrorList{
25+
field.NotSupported(field.NewPath("spec", "type"), "", []string{}),
26+
},
27+
},
28+
"invalid backend endpoints - unix": {
29+
backend: &envoygatewayv1alpha1.Backend{
30+
Spec: envoygatewayv1alpha1.BackendSpec{
31+
Type: ptr.To(envoygatewayv1alpha1.BackendTypeEndpoints),
32+
Endpoints: []envoygatewayv1alpha1.BackendEndpoint{
33+
{
34+
Unix: ptr.To(envoygatewayv1alpha1.UnixSocket{}),
35+
},
36+
},
37+
},
38+
},
39+
expectedErrors: field.ErrorList{
40+
field.Forbidden(field.NewPath("spec", "endpoints").Index(0).Child("unix"), ""),
41+
},
42+
},
43+
}
44+
45+
for name, scenario := range scenarios {
46+
t.Run(name, func(t *testing.T) {
47+
errs := ValidateBackend(scenario.backend)
48+
delta := cmp.Diff(scenario.expectedErrors, errs, cmpopts.IgnoreFields(field.Error{}, "BadValue", "Detail"))
49+
if delta != "" {
50+
t.Errorf("Testcase %s - expected errors '%v', got '%v', diff: '%v'", name, scenario.expectedErrors, errs, delta)
51+
}
52+
})
53+
}
54+
}

internal/validation/backendtrafficpolicy_validation.go

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package validation
22

33
import (
44
"fmt"
5+
"strconv"
56
"time"
67

78
envoygatewayv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1"
@@ -22,25 +23,33 @@ func ValidateBackendTrafficPolicy(backendTrafficPolicy *envoygatewayv1alpha1.Bac
2223
allErrs = append(allErrs, field.Forbidden(specPath.Child("targetRef"), "deprecated field, use spec.targetRefs or spec.targetSelectors instead"))
2324
}
2425

25-
allErrs = append(allErrs, validateBackendTrafficPolicyLoadBalancer(backendTrafficPolicy.Spec.LoadBalancer, specPath.Child("loadBalancer"))...)
26+
allErrs = append(allErrs, validateGatewayClusterSettings(backendTrafficPolicy.Spec.ClusterSettings, specPath)...)
27+
allErrs = append(allErrs, validateBackendTrafficPolicyRateLimit(backendTrafficPolicy.Spec.RateLimit, specPath.Child("rateLimit"))...)
28+
allErrs = append(allErrs, validateBackendTrafficPolicyFaultInjection(backendTrafficPolicy.Spec.FaultInjection, specPath.Child("faultInjection"))...)
29+
30+
return allErrs
31+
}
2632

27-
if backendTrafficPolicy.Spec.Retry != nil {
28-
allErrs = append(allErrs, field.Forbidden(specPath.Child("retry"), "retry settings are not permitted"))
33+
func validateGatewayClusterSettings(clusterSettings envoygatewayv1alpha1.ClusterSettings, fldPath *field.Path) field.ErrorList {
34+
allErrs := field.ErrorList{}
35+
36+
allErrs = append(allErrs, validateGatewayBackendLoadBalancer(clusterSettings.LoadBalancer, fldPath.Child("loadBalancer"))...)
37+
38+
if clusterSettings.Retry != nil {
39+
allErrs = append(allErrs, field.Forbidden(fldPath.Child("retry"), "retry settings are not permitted"))
2940
}
3041

31-
allErrs = append(allErrs, validateBackendTrafficPolicyTCPKeepalive(backendTrafficPolicy.Spec.TCPKeepalive, specPath.Child("tcpKeepalive"))...)
32-
allErrs = append(allErrs, validateBackendTrafficPolicyHealthCheck(backendTrafficPolicy.Spec.HealthCheck, specPath.Child("healthCheck"))...)
33-
allErrs = append(allErrs, validateBackendTrafficPolicyTimeout(backendTrafficPolicy.Spec.Timeout, specPath.Child("timeout"))...)
34-
allErrs = append(allErrs, validateBackendTrafficPolicyConnection(backendTrafficPolicy.Spec.Connection, specPath.Child("connection"))...)
35-
allErrs = append(allErrs, validateBackendTrafficPolicyDNS(backendTrafficPolicy.Spec.DNS, specPath.Child("dns"))...)
36-
allErrs = append(allErrs, validateBackendTrafficPolicyHTTP2(backendTrafficPolicy.Spec.HTTP2, specPath.Child("http2"))...)
37-
allErrs = append(allErrs, validateBackendTrafficPolicyRateLimit(backendTrafficPolicy.Spec.RateLimit, specPath.Child("rateLimit"))...)
38-
allErrs = append(allErrs, validateBackendTrafficPolicyFaultInjection(backendTrafficPolicy.Spec.FaultInjection, specPath.Child("faultInjection"))...)
42+
allErrs = append(allErrs, validateGatewayClusterSettingsTCPKeepalive(clusterSettings.TCPKeepalive, fldPath.Child("tcpKeepalive"))...)
43+
allErrs = append(allErrs, validateGatewayClusterSettingsHealthCheck(clusterSettings.HealthCheck, fldPath.Child("healthCheck"))...)
44+
allErrs = append(allErrs, validateGatewayClusterSettingsTimeout(clusterSettings.Timeout, fldPath.Child("timeout"))...)
45+
allErrs = append(allErrs, validateGatewayClusterSettingsConnection(clusterSettings.Connection, fldPath.Child("connection"))...)
46+
allErrs = append(allErrs, validateGatewayClusterSettingsDNS(clusterSettings.DNS, fldPath.Child("dns"))...)
47+
allErrs = append(allErrs, validateGatewayClusterSettingsHTTP2(clusterSettings.HTTP2, fldPath.Child("http2"))...)
3948

4049
return allErrs
4150
}
4251

43-
func validateBackendTrafficPolicyLoadBalancer(loadBalancer *envoygatewayv1alpha1.LoadBalancer, fldPath *field.Path) field.ErrorList {
52+
func validateGatewayBackendLoadBalancer(loadBalancer *envoygatewayv1alpha1.LoadBalancer, fldPath *field.Path) field.ErrorList {
4453
if loadBalancer == nil {
4554
return nil
4655
}
@@ -54,15 +63,15 @@ func validateBackendTrafficPolicyLoadBalancer(loadBalancer *envoygatewayv1alpha1
5463
return allErrs
5564
}
5665

57-
func validateBackendTrafficPolicyTCPKeepalive(tcpKeepalive *envoygatewayv1alpha1.TCPKeepalive, fldPath *field.Path) field.ErrorList {
66+
func validateGatewayClusterSettingsTCPKeepalive(tcpKeepalive *envoygatewayv1alpha1.TCPKeepalive, fldPath *field.Path) field.ErrorList {
5867
if tcpKeepalive == nil {
5968
return nil
6069
}
6170

6271
allErrs := field.ErrorList{}
6372

6473
if tcpKeepalive.Probes != nil && *tcpKeepalive.Probes < 9 {
65-
allErrs = append(allErrs, field.Invalid(fldPath.Child("probe"), *tcpKeepalive.Probes, "must be greater than or equal to 9"))
74+
allErrs = append(allErrs, field.Invalid(fldPath.Child("probes"), strconv.FormatUint(uint64(*tcpKeepalive.Probes), 10), "must be greater than or equal to 9"))
6675
}
6776

6877
if v := tcpKeepalive.IdleTime; v != nil {
@@ -78,7 +87,7 @@ func validateBackendTrafficPolicyTCPKeepalive(tcpKeepalive *envoygatewayv1alpha1
7887
return allErrs
7988
}
8089

81-
func validateBackendTrafficPolicyHealthCheck(healthCheck *envoygatewayv1alpha1.HealthCheck, fldPath *field.Path) field.ErrorList {
90+
func validateGatewayClusterSettingsHealthCheck(healthCheck *envoygatewayv1alpha1.HealthCheck, fldPath *field.Path) field.ErrorList {
8291
if healthCheck == nil {
8392
return nil
8493
}
@@ -92,7 +101,7 @@ func validateBackendTrafficPolicyHealthCheck(healthCheck *envoygatewayv1alpha1.H
92101
return allErrs
93102
}
94103

95-
func validateBackendTrafficPolicyTimeout(timeout *envoygatewayv1alpha1.Timeout, fldPath *field.Path) field.ErrorList {
104+
func validateGatewayClusterSettingsTimeout(timeout *envoygatewayv1alpha1.Timeout, fldPath *field.Path) field.ErrorList {
96105
if timeout == nil {
97106
return nil
98107
}
@@ -102,7 +111,7 @@ func validateBackendTrafficPolicyTimeout(timeout *envoygatewayv1alpha1.Timeout,
102111
if timeout.TCP != nil {
103112
if v := timeout.TCP.ConnectTimeout; v != nil {
104113
connectTimeoutFieldPath := fldPath.Child("tcp").Child("connectTimeout")
105-
allErrs = append(allErrs, validateGatewayDuration(connectTimeoutFieldPath, v, nil, ptr.To(1*time.Hour))...)
114+
allErrs = append(allErrs, validateGatewayDuration(connectTimeoutFieldPath, v, nil, ptr.To(10*time.Second))...)
106115
}
107116
}
108117

@@ -129,7 +138,7 @@ func validateBackendTrafficPolicyTimeout(timeout *envoygatewayv1alpha1.Timeout,
129138
return allErrs
130139
}
131140

132-
func validateBackendTrafficPolicyConnection(connection *envoygatewayv1alpha1.BackendConnection, fldPath *field.Path) field.ErrorList {
141+
func validateGatewayClusterSettingsConnection(connection *envoygatewayv1alpha1.BackendConnection, fldPath *field.Path) field.ErrorList {
133142
if connection == nil {
134143
return nil
135144
}
@@ -144,7 +153,7 @@ func validateBackendTrafficPolicyConnection(connection *envoygatewayv1alpha1.Bac
144153
return nil
145154
}
146155

147-
func validateBackendTrafficPolicyDNS(dns *envoygatewayv1alpha1.DNS, fldPath *field.Path) field.ErrorList {
156+
func validateGatewayClusterSettingsDNS(dns *envoygatewayv1alpha1.DNS, fldPath *field.Path) field.ErrorList {
148157
if dns == nil {
149158
return nil
150159
}
@@ -163,7 +172,7 @@ func validateBackendTrafficPolicyDNS(dns *envoygatewayv1alpha1.DNS, fldPath *fie
163172
return allErrs
164173
}
165174

166-
func validateBackendTrafficPolicyHTTP2(http2 *envoygatewayv1alpha1.HTTP2Settings, fldPath *field.Path) field.ErrorList {
175+
func validateGatewayClusterSettingsHTTP2(http2 *envoygatewayv1alpha1.HTTP2Settings, fldPath *field.Path) field.ErrorList {
167176
if http2 == nil {
168177
return nil
169178
}

0 commit comments

Comments
 (0)