Skip to content
This repository was archived by the owner on Jul 11, 2023. It is now read-only.

Commit 4a1b993

Browse files
authored
validator: validate HTTP rate limiting status code (#4857)
Adds logic to validate the HTTP status code is among a list of status codes supported by Envoy. Part of #2018 Signed-off-by: Shashank Ram <[email protected]>
1 parent 9222555 commit 4a1b993

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

pkg/validator/validators.go

+18
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99

1010
mapset "github.com/deckarep/golang-set"
11+
xds_type "github.com/envoyproxy/go-control-plane/envoy/type/v3"
1112
"github.com/pkg/errors"
1213
smiAccess "github.com/servicemeshinterface/smi-sdk-go/pkg/apis/access/v1alpha3"
1314
smiSpecs "github.com/servicemeshinterface/smi-sdk-go/pkg/apis/specs/v1alpha4"
@@ -246,5 +247,22 @@ func (kc *policyValidator) upstreamTrafficSettingValidator(req *admissionv1.Admi
246247
return nil, errors.Errorf("UpstreamTrafficSetting %s/%s conflicts with %s/%s since they have the same host %s", ns, upstreamTrafficSetting.ObjectMeta.GetName(), ns, matchingUpstreamTrafficSetting.ObjectMeta.GetName(), matchingUpstreamTrafficSetting.Spec.Host)
247248
}
248249

250+
// Validate rate limiting config
251+
rl := upstreamTrafficSetting.Spec.RateLimit
252+
if rl != nil && rl.Local != nil && rl.Local.HTTP != nil {
253+
if _, ok := xds_type.StatusCode_name[int32(rl.Local.HTTP.ResponseStatusCode)]; !ok {
254+
return nil, errors.Errorf("Invalid responseStatusCode %d. See https://www.envoyproxy.io/docs/envoy/latest/api-v3/type/v3/http_status.proto#enum-type-v3-statuscode for allowed values",
255+
rl.Local.HTTP.ResponseStatusCode)
256+
}
257+
}
258+
for _, route := range upstreamTrafficSetting.Spec.HTTPRoutes {
259+
if route.RateLimit != nil && route.RateLimit.Local != nil {
260+
if _, ok := xds_type.StatusCode_name[int32(route.RateLimit.Local.ResponseStatusCode)]; !ok {
261+
return nil, errors.Errorf("Invalid responseStatusCode %d. See https://www.envoyproxy.io/docs/envoy/latest/api-v3/type/v3/http_status.proto#enum-type-v3-statuscode for allowed values",
262+
route.RateLimit.Local.ResponseStatusCode)
263+
}
264+
}
265+
}
266+
249267
return nil, nil
250268
}

pkg/validator/validators_test.go

+120
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,126 @@ func TestUpstreamTrafficSettingValidator(t *testing.T) {
11471147
expResp: nil,
11481148
expErrStr: "",
11491149
},
1150+
{
1151+
name: "UpstreamTrafficSetting with valid rate limiting config",
1152+
input: &admissionv1.AdmissionRequest{
1153+
Kind: metav1.GroupVersionKind{
1154+
Group: "v1alpha1",
1155+
Version: "policy.openservicemesh.io",
1156+
Kind: "UpstreamTrafficSetting",
1157+
},
1158+
Object: runtime.RawExtension{
1159+
Raw: []byte(`
1160+
{
1161+
"apiVersion": "policy.openservicemesh.io/v1alpha1",
1162+
"kind": "UpstreamTrafficSetting",
1163+
"metadata": {
1164+
"name": "httpbin",
1165+
"namespace": "test"
1166+
},
1167+
"spec": {
1168+
"host": "httpbin.test.svc.cluster.local",
1169+
"rateLimit": {
1170+
"local": {
1171+
"http": {
1172+
"responseStatusCode": 429
1173+
}
1174+
}
1175+
},
1176+
"httpRoutes": [
1177+
{
1178+
"rateLimit": {
1179+
"local": {
1180+
"responseStatusCode": 503
1181+
}
1182+
}
1183+
}
1184+
]
1185+
}
1186+
}
1187+
`),
1188+
},
1189+
},
1190+
expResp: nil,
1191+
expErrStr: "",
1192+
},
1193+
{
1194+
name: "UpstreamTrafficSetting with invalid vhost rate limiting HTTP status code",
1195+
input: &admissionv1.AdmissionRequest{
1196+
Kind: metav1.GroupVersionKind{
1197+
Group: "v1alpha1",
1198+
Version: "policy.openservicemesh.io",
1199+
Kind: "UpstreamTrafficSetting",
1200+
},
1201+
Object: runtime.RawExtension{
1202+
Raw: []byte(`
1203+
{
1204+
"apiVersion": "policy.openservicemesh.io/v1alpha1",
1205+
"kind": "UpstreamTrafficSetting",
1206+
"metadata": {
1207+
"name": "httpbin",
1208+
"namespace": "test"
1209+
},
1210+
"spec": {
1211+
"host": "httpbin.test.svc.cluster.local",
1212+
"rateLimit": {
1213+
"local": {
1214+
"http": {
1215+
"responseStatusCode": 1
1216+
}
1217+
}
1218+
}
1219+
}
1220+
}
1221+
`),
1222+
},
1223+
},
1224+
expResp: nil,
1225+
expErrStr: "Invalid responseStatusCode 1. See https://www.envoyproxy.io/docs/envoy/latest/api-v3/type/v3/http_status.proto#enum-type-v3-statuscode for allowed values",
1226+
},
1227+
{
1228+
name: "UpstreamTrafficSetting with invalid HTTP route rate limiting status code",
1229+
input: &admissionv1.AdmissionRequest{
1230+
Kind: metav1.GroupVersionKind{
1231+
Group: "v1alpha1",
1232+
Version: "policy.openservicemesh.io",
1233+
Kind: "UpstreamTrafficSetting",
1234+
},
1235+
Object: runtime.RawExtension{
1236+
Raw: []byte(`
1237+
{
1238+
"apiVersion": "policy.openservicemesh.io/v1alpha1",
1239+
"kind": "UpstreamTrafficSetting",
1240+
"metadata": {
1241+
"name": "httpbin",
1242+
"namespace": "test"
1243+
},
1244+
"spec": {
1245+
"host": "httpbin.test.svc.cluster.local",
1246+
"rateLimit": {
1247+
"local": {
1248+
"http": {
1249+
"responseStatusCode": 429
1250+
}
1251+
}
1252+
},
1253+
"httpRoutes": [
1254+
{
1255+
"rateLimit": {
1256+
"local": {
1257+
"responseStatusCode": 1
1258+
}
1259+
}
1260+
}
1261+
]
1262+
}
1263+
}
1264+
`),
1265+
},
1266+
},
1267+
expResp: nil,
1268+
expErrStr: "Invalid responseStatusCode 1. See https://www.envoyproxy.io/docs/envoy/latest/api-v3/type/v3/http_status.proto#enum-type-v3-statuscode for allowed values",
1269+
},
11501270
}
11511271

11521272
for _, tc := range testCases {

0 commit comments

Comments
 (0)