diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml index 94d05c401356..3fcbf97212b6 100644 --- a/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml +++ b/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml @@ -4890,6 +4890,134 @@ spec: - targetRef type: object type: array + rules: + description: |- + Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + items: + properties: + default: + description: |- + Default is a configuration specific to the group of clients referenced in + 'targetRef' + properties: + local: + description: LocalConf defines local http or/and tcp rate + limit configuration + properties: + http: + description: |- + LocalHTTP defines configuration of local HTTP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: Describes the actions to take on a + rate limit event + properties: + headers: + description: The Headers to be added to the + HTTP response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: The HTTP status code to be set + on a rate limit event + format: int32 + type: integer + type: object + requestRate: + description: Defines how many requests are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: |- + LocalTCP defines confguration of local TCP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: Defines how many connections are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: |- TargetRef is a reference to the resource the policy takes an effect on. diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml index d5a5e32013d1..0a4ec9e94994 100644 --- a/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml +++ b/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml @@ -4890,6 +4890,134 @@ spec: - targetRef type: object type: array + rules: + description: |- + Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + items: + properties: + default: + description: |- + Default is a configuration specific to the group of clients referenced in + 'targetRef' + properties: + local: + description: LocalConf defines local http or/and tcp rate + limit configuration + properties: + http: + description: |- + LocalHTTP defines configuration of local HTTP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: Describes the actions to take on a + rate limit event + properties: + headers: + description: The Headers to be added to the + HTTP response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: The HTTP status code to be set + on a rate limit event + format: int32 + type: integer + type: object + requestRate: + description: Defines how many requests are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: |- + LocalTCP defines confguration of local TCP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: Defines how many connections are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: |- TargetRef is a reference to the resource the policy takes an effect on. diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml index bb6daadf6bda..3a71d557789c 100644 --- a/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml +++ b/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml @@ -4910,6 +4910,134 @@ spec: - targetRef type: object type: array + rules: + description: |- + Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + items: + properties: + default: + description: |- + Default is a configuration specific to the group of clients referenced in + 'targetRef' + properties: + local: + description: LocalConf defines local http or/and tcp rate + limit configuration + properties: + http: + description: |- + LocalHTTP defines configuration of local HTTP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: Describes the actions to take on a + rate limit event + properties: + headers: + description: The Headers to be added to the + HTTP response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: The HTTP status code to be set + on a rate limit event + format: int32 + type: integer + type: object + requestRate: + description: Defines how many requests are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: |- + LocalTCP defines confguration of local TCP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: Defines how many connections are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: |- TargetRef is a reference to the resource the policy takes an effect on. diff --git a/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml b/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml index 663e1fba625d..cc51a200d279 100644 --- a/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml +++ b/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml @@ -6460,6 +6460,134 @@ spec: - targetRef type: object type: array + rules: + description: |- + Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + items: + properties: + default: + description: |- + Default is a configuration specific to the group of clients referenced in + 'targetRef' + properties: + local: + description: LocalConf defines local http or/and tcp rate + limit configuration + properties: + http: + description: |- + LocalHTTP defines configuration of local HTTP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: Describes the actions to take on a + rate limit event + properties: + headers: + description: The Headers to be added to the + HTTP response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: The HTTP status code to be set + on a rate limit event + format: int32 + type: integer + type: object + requestRate: + description: Defines how many requests are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: |- + LocalTCP defines confguration of local TCP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: Defines how many connections are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: |- TargetRef is a reference to the resource the policy takes an effect on. diff --git a/deployments/charts/kuma/crds/kuma.io_meshratelimits.yaml b/deployments/charts/kuma/crds/kuma.io_meshratelimits.yaml index 7619a295e104..0c3e90c1c55f 100644 --- a/deployments/charts/kuma/crds/kuma.io_meshratelimits.yaml +++ b/deployments/charts/kuma/crds/kuma.io_meshratelimits.yaml @@ -241,6 +241,134 @@ spec: - targetRef type: object type: array + rules: + description: |- + Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + items: + properties: + default: + description: |- + Default is a configuration specific to the group of clients referenced in + 'targetRef' + properties: + local: + description: LocalConf defines local http or/and tcp rate + limit configuration + properties: + http: + description: |- + LocalHTTP defines configuration of local HTTP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: Describes the actions to take on a + rate limit event + properties: + headers: + description: The Headers to be added to the + HTTP response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: The HTTP status code to be set + on a rate limit event + format: int32 + type: integer + type: object + requestRate: + description: Defines how many requests are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: |- + LocalTCP defines confguration of local TCP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: Defines how many connections are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: |- TargetRef is a reference to the resource the policy takes an effect on. diff --git a/docs/generated/openapi.yaml b/docs/generated/openapi.yaml index c7c6ffd346a0..16a22b35a2e3 100644 --- a/docs/generated/openapi.yaml +++ b/docs/generated/openapi.yaml @@ -9153,6 +9153,155 @@ components: - targetRef type: object type: array + rules: + description: >- + Rules defines inbound timeout configurations. Currently limited + to exactly one rule containing + + default timeouts that apply to all inbound traffic, as L7 + matching is not yet implemented. + items: + properties: + default: + description: >- + Default is a configuration specific to the group of + clients referenced in + + 'targetRef' + properties: + local: + description: >- + LocalConf defines local http or/and tcp rate limit + configuration + properties: + http: + description: >- + LocalHTTP defines configuration of local HTTP rate + limiting + + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: >- + Describes the actions to take on a rate limit + event + properties: + headers: + description: >- + The Headers to be added to the HTTP + response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: >- + The HTTP status code to be set on a rate + limit event + format: int32 + type: integer + type: object + requestRate: + description: >- + Defines how many requests are allowed per + interval. + properties: + interval: + description: >- + The interval the number of units is + accounted for. + type: string + num: + description: >- + Number of units per interval (depending on + usage it can be a number of requests, + + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: >- + LocalTCP defines confguration of local TCP rate + limiting + + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: >- + Defines how many connections are allowed per + interval. + properties: + interval: + description: >- + The interval the number of units is + accounted for. + type: string + num: + description: >- + Number of units per interval (depending on + usage it can be a number of requests, + + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: >- TargetRef is a reference to the resource the policy takes an diff --git a/docs/generated/raw/crds/kuma.io_meshratelimits.yaml b/docs/generated/raw/crds/kuma.io_meshratelimits.yaml index 7619a295e104..0c3e90c1c55f 100644 --- a/docs/generated/raw/crds/kuma.io_meshratelimits.yaml +++ b/docs/generated/raw/crds/kuma.io_meshratelimits.yaml @@ -241,6 +241,134 @@ spec: - targetRef type: object type: array + rules: + description: |- + Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + items: + properties: + default: + description: |- + Default is a configuration specific to the group of clients referenced in + 'targetRef' + properties: + local: + description: LocalConf defines local http or/and tcp rate + limit configuration + properties: + http: + description: |- + LocalHTTP defines configuration of local HTTP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: Describes the actions to take on a + rate limit event + properties: + headers: + description: The Headers to be added to the + HTTP response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: The HTTP status code to be set + on a rate limit event + format: int32 + type: integer + type: object + requestRate: + description: Defines how many requests are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: |- + LocalTCP defines confguration of local TCP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: Defines how many connections are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: |- TargetRef is a reference to the resource the policy takes an effect on. diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/meshratelimit.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/meshratelimit.go index 7c713940f468..2bbf568d60c4 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/meshratelimit.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/meshratelimit.go @@ -8,6 +8,7 @@ import ( ) // MeshRateLimit +// +kuma:policy:interpret_from_entries_as_rules=true type MeshRateLimit struct { // TargetRef is a reference to the resource the policy takes an effect on. // The resource could be either a real store object or virtual resource @@ -17,6 +18,15 @@ type MeshRateLimit struct { From []From `json:"from,omitempty"` // To list makes a match between clients and corresponding configurations To []To `json:"to,omitempty"` + // Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + // default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + Rules []Rule `json:"rules,omitempty"` +} + +type Rule struct { + // Default is a configuration specific to the group of clients referenced in + // 'targetRef' + Default Conf `json:"default,omitempty"` } type From struct { diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/schema.yaml b/pkg/plugins/policies/meshratelimit/api/v1alpha1/schema.yaml index 42f759e0179e..5b02aab40ec7 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/schema.yaml +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/schema.yaml @@ -203,6 +203,126 @@ properties: - targetRef type: object type: array + rules: + description: |- + Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + items: + properties: + default: + description: |- + Default is a configuration specific to the group of clients referenced in + 'targetRef' + properties: + local: + description: LocalConf defines local http or/and tcp rate limit configuration + properties: + http: + description: |- + LocalHTTP defines configuration of local HTTP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: Describes the actions to take on a rate limit event + properties: + headers: + description: The Headers to be added to the HTTP response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: The HTTP status code to be set on a rate limit event + format: int32 + type: integer + type: object + requestRate: + description: Defines how many requests are allowed per interval. + properties: + interval: + description: The interval the number of units is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: |- + LocalTCP defines confguration of local TCP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: Defines how many connections are allowed per interval. + properties: + interval: + description: The interval the number of units is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: |- TargetRef is a reference to the resource the policy takes an effect on. diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator.go index 63280ed805dc..6c5bb89b1568 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator.go @@ -15,8 +15,12 @@ import ( func (r *MeshRateLimitResource) validate() error { var verr validators.ValidationError path := validators.RootedAt("spec") + if len(r.Spec.Rules) > 0 && (len(r.Spec.To) > 0 || len(r.Spec.From) > 0) { + verr.AddViolationAt(path, "fields 'to' and 'from' must be empty when 'rules' is defined") + } verr.AddErrorAt(path.Field("targetRef"), r.validateTop(r.Spec.TargetRef, inbound.AffectsInbounds(r.Spec))) topLevel := pointer.DerefOr(r.Spec.TargetRef, common_api.TargetRef{Kind: common_api.Mesh}) + verr.AddErrorAt(path, validateRules(topLevel, r.Spec.Rules)) verr.AddErrorAt(path, validateFrom(topLevel, r.Spec.From)) verr.AddErrorAt(path, validateTo(topLevel, r.Spec.To)) return verr.OrNil() @@ -55,6 +59,23 @@ func (r *MeshRateLimitResource) validateTop(targetRef *common_api.TargetRef, isI } } +func validateRules(topTargetRef common_api.TargetRef, rules []Rule) validators.ValidationError { + var verr validators.ValidationError + if common_api.IncludesGateways(topTargetRef) && len(rules) != 0 { + verr.AddViolationAt(validators.RootedAt("rules"), validators.MustNotBeDefined) + return verr + } + if topTargetRef.Kind == common_api.MeshHTTPRoute && len(rules) != 0 { + verr.AddViolationAt(validators.RootedAt("rules"), validators.MustNotBeDefined) + return verr + } + for idx, ruleItem := range rules { + path := validators.RootedAt("rules").Index(idx) + verr.Add(validateDefault(path.Field("default"), ruleItem.Default)) + } + return verr +} + func validateFrom(topTargetRef common_api.TargetRef, from []From) validators.ValidationError { var verr validators.ValidationError if common_api.IncludesGateways(topTargetRef) && len(from) != 0 { diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator_test.go index d9a275e5cb5d..5e678f75ae9d 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator_test.go @@ -379,6 +379,35 @@ from: violations: - field: spec.from message: 'must not be defined'`, + }), + Entry("mixing from with rules", testCase{ + inputYaml: ` +targetRef: + kind: Mesh +from: + - targetRef: + kind: Mesh + default: + local: + http: + requestRate: + num: 100 + interval: 10s +rules: + - default: + local: + http: + requestRate: + num: 100 + interval: 10s`, + expected: ` +violations: +- field: spec + message: fields 'to' and 'from' must be empty when 'rules' is defined +- field: spec.rules + message: must not be defined +- field: spec.from + message: must not be defined`, }), Entry("invalid gateway example when targeting MeshHTTPRoute", testCase{ inputYaml: ` diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.deepcopy.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.deepcopy.go index 3ab5e889b303..52a047e6b8ae 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.deepcopy.go @@ -187,6 +187,13 @@ func (in *MeshRateLimit) DeepCopyInto(out *MeshRateLimit) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]Rule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshRateLimit. @@ -240,6 +247,22 @@ func (in *Rate) DeepCopy() *Rate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Rule) DeepCopyInto(out *Rule) { + *out = *in + in.Default.DeepCopyInto(&out.Default) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule. +func (in *Rule) DeepCopy() *Rule { + if in == nil { + return nil + } + out := new(Rule) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *To) DeepCopyInto(out *To) { *out = *in diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.helpers.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.helpers.go index 6aaaf79260a3..23b532b5389a 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.helpers.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.helpers.go @@ -7,6 +7,7 @@ package v1alpha1 import ( common_api "github.com/kumahq/kuma/api/common/v1alpha1" core_model "github.com/kumahq/kuma/pkg/core/resources/model" + "github.com/kumahq/kuma/pkg/plugins/policies/core/rules/inbound" "github.com/kumahq/kuma/pkg/util/pointer" ) @@ -47,3 +48,16 @@ func (x *MeshRateLimit) GetToList() []core_model.PolicyItem { } return result } + +func (x *Rule) GetDefault() interface{} { + return x.Default +} + +func (x *MeshRateLimit) GetRules() []inbound.RuleEntry { + var result []inbound.RuleEntry + for i := range x.Rules { + item := x.Rules[i] + result = append(result, &item) + } + return result +} diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.resource.go index 26b1fdf3d666..76e7b3ad4d3a 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.resource.go @@ -150,10 +150,10 @@ var MeshRateLimitResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: true, - HasRulesTargetRef: false, + HasRulesTargetRef: true, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, ShortName: "mrl", - InterpretFromEntriesAsRules: false, + InterpretFromEntriesAsRules: true, } diff --git a/pkg/plugins/policies/meshratelimit/k8s/crd/kuma.io_meshratelimits.yaml b/pkg/plugins/policies/meshratelimit/k8s/crd/kuma.io_meshratelimits.yaml index 7619a295e104..0c3e90c1c55f 100644 --- a/pkg/plugins/policies/meshratelimit/k8s/crd/kuma.io_meshratelimits.yaml +++ b/pkg/plugins/policies/meshratelimit/k8s/crd/kuma.io_meshratelimits.yaml @@ -241,6 +241,134 @@ spec: - targetRef type: object type: array + rules: + description: |- + Rules defines inbound timeout configurations. Currently limited to exactly one rule containing + default timeouts that apply to all inbound traffic, as L7 matching is not yet implemented. + items: + properties: + default: + description: |- + Default is a configuration specific to the group of clients referenced in + 'targetRef' + properties: + local: + description: LocalConf defines local http or/and tcp rate + limit configuration + properties: + http: + description: |- + LocalHTTP defines configuration of local HTTP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter + properties: + disabled: + description: Define if rate limiting should be disabled. + type: boolean + onRateLimit: + description: Describes the actions to take on a + rate limit event + properties: + headers: + description: The Headers to be added to the + HTTP response on a rate limit event + properties: + add: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + set: + items: + properties: + name: + maxLength: 256 + minLength: 1 + pattern: ^[a-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: The HTTP status code to be set + on a rate limit event + format: int32 + type: integer + type: object + requestRate: + description: Defines how many requests are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + type: object + tcp: + description: |- + LocalTCP defines confguration of local TCP rate limiting + https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/local_rate_limit_filter + properties: + connectionRate: + description: Defines how many connections are allowed + per interval. + properties: + interval: + description: The interval the number of units + is accounted for. + type: string + num: + description: |- + Number of units per interval (depending on usage it can be a number of requests, + or a number of connections). + format: int32 + type: integer + required: + - interval + - num + type: object + disabled: + description: |- + Define if rate limiting should be disabled. + Default: false + type: boolean + type: object + type: object + type: object + type: object + type: array targetRef: description: |- TargetRef is a reference to the resource the policy takes an effect on. diff --git a/pkg/plugins/policies/meshratelimit/plugin/v1alpha1/plugin.go b/pkg/plugins/policies/meshratelimit/plugin/v1alpha1/plugin.go index cd56d132e315..01892dfe6617 100644 --- a/pkg/plugins/policies/meshratelimit/plugin/v1alpha1/plugin.go +++ b/pkg/plugins/policies/meshratelimit/plugin/v1alpha1/plugin.go @@ -11,6 +11,7 @@ import ( core_xds "github.com/kumahq/kuma/pkg/core/xds" "github.com/kumahq/kuma/pkg/plugins/policies/core/matchers" core_rules "github.com/kumahq/kuma/pkg/plugins/policies/core/rules" + inbound2 "github.com/kumahq/kuma/pkg/plugins/policies/core/rules/inbound" "github.com/kumahq/kuma/pkg/plugins/policies/core/rules/subsetutils" "github.com/kumahq/kuma/pkg/plugins/policies/core/xds" api "github.com/kumahq/kuma/pkg/plugins/policies/meshratelimit/api/v1alpha1" @@ -117,12 +118,9 @@ func applyToInbounds( if !ok { continue } - rules, ok := fromRules.Rules[listenerKey] - if !ok { - continue - } - if err := configure(rules, listener, nil); err != nil { + conf := inbound2.MatchesAllIncomingTraffic[api.Conf](fromRules.InboundRules[listenerKey]) + if err := configure(conf, listener, nil); err != nil { return err } } @@ -170,14 +168,9 @@ func applyToEgress(rs *core_xds.ResourceSet, proxy *core_xds.Proxy) error { return nil } -func configure( - fromRules core_rules.Rules, - listener *envoy_listener.Listener, - route *envoy_route.RouteConfiguration, -) error { +func configure(conf api.Conf, listener *envoy_listener.Listener, route *envoy_route.RouteConfiguration) error { configurer := plugin_xds.Configurer{ - Rules: fromRules, - // Currently, `from` section of MeshRateLimit only allows Mesh targetRef + Conf: &conf, Element: subsetutils.MeshElement(), } diff --git a/pkg/plugins/policies/meshratelimit/plugin/v1alpha1/plugin_test.go b/pkg/plugins/policies/meshratelimit/plugin/v1alpha1/plugin_test.go index ba0f834dd927..07e27ca34018 100644 --- a/pkg/plugins/policies/meshratelimit/plugin/v1alpha1/plugin_test.go +++ b/pkg/plugins/policies/meshratelimit/plugin/v1alpha1/plugin_test.go @@ -19,6 +19,7 @@ import ( core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh" core_xds "github.com/kumahq/kuma/pkg/core/xds" core_rules "github.com/kumahq/kuma/pkg/plugins/policies/core/rules" + "github.com/kumahq/kuma/pkg/plugins/policies/core/rules/inbound" "github.com/kumahq/kuma/pkg/plugins/policies/core/rules/subsetutils" plugins_xds "github.com/kumahq/kuma/pkg/plugins/policies/core/xds" meshhttproute_api "github.com/kumahq/kuma/pkg/plugins/policies/meshhttproute/api/v1alpha1" @@ -173,6 +174,54 @@ var _ = Describe("MeshRateLimit", func() { }, }}, }, + InboundRules: map[core_rules.InboundListener][]*inbound.Rule{ + {Address: "127.0.0.1", Port: 17777}: {{ + Conf: []interface{}{ + api.Conf{ + Local: &api.Local{ + HTTP: &api.LocalHTTP{ + RequestRate: &api.Rate{Num: 100, Interval: *test.ParseDuration("10s")}, + OnRateLimit: &api.OnRateLimit{ + Status: pointer.To(uint32(444)), + Headers: &api.HeaderModifier{ + Add: []api.HeaderKeyValue{ + { + Name: "x-kuma-rate-limit-header", + Value: "test-value", + }, + { + Name: "x-kuma-rate-limit", + Value: "other-value", + }, + }, + Set: []api.HeaderKeyValue{ + { + Name: "x-kuma-rate-limit-header-set", + Value: "test-value", + }, + }, + }, + }, + }, + }, + }, + }, + }}, + {Address: "127.0.0.1", Port: 17778}: {{ + Conf: []interface{}{ + api.Conf{ + Local: &api.Local{ + HTTP: &api.LocalHTTP{ + RequestRate: &api.Rate{Num: 100, Interval: *test.ParseDuration("10s")}, + }, + TCP: &api.LocalTCP{ + ConnectionRate: &api.Rate{Num: 100, Interval: *test.ParseDuration("10s")}, + }, + }, + }, + }, + }}, + }, }, inboundRateLimitsMap: core_xds.InboundRateLimitsMap{}, expectedListeners: []string{"basic_listener_1.golden.yaml", "basic_listener_2.golden.yaml"}, @@ -255,6 +304,45 @@ var _ = Describe("MeshRateLimit", func() { }, }}, }, + InboundRules: map[core_rules.InboundListener][]*inbound.Rule{ + {Address: "127.0.0.1", Port: 17777}: {{ + Conf: []interface{}{ + api.Conf{ + Local: &api.Local{ + HTTP: &api.LocalHTTP{ + RequestRate: &api.Rate{ + Num: 100, + Interval: *test.ParseDuration("10s"), + }, + OnRateLimit: &api.OnRateLimit{ + Status: pointer.To(uint32(444)), + Headers: &api.HeaderModifier{ + Add: []api.HeaderKeyValue{ + { + Name: "x-kuma-rate-limit-header", + Value: "test-value", + }, + }, + Set: []api.HeaderKeyValue{ + { + Name: "x-kuma-rate-limit", + Value: "other-value", + }, + }, + }, + }, + }, + TCP: &api.LocalTCP{ + ConnectionRate: &api.Rate{ + Num: 100, + Interval: *test.ParseDuration("99s"), + }, + }, + }, + }, + }, + }}, + }, }, inboundRateLimitsMap: core_xds.InboundRateLimitsMap{ mesh_proto.InboundInterface{ @@ -308,6 +396,20 @@ var _ = Describe("MeshRateLimit", func() { }, }}, }, + InboundRules: map[core_rules.InboundListener][]*inbound.Rule{ + {Address: "127.0.0.1", Port: 17778}: {{ + Conf: []interface{}{ + api.Conf{ + Local: &api.Local{ + TCP: &api.LocalTCP{ + Disabled: pointer.To(true), + ConnectionRate: &api.Rate{Num: 100, Interval: *test.ParseDuration("10s")}, + }, + }, + }, + }, + }}, + }, }, inboundRateLimitsMap: core_xds.InboundRateLimitsMap{}, expectedListeners: []string{"tcp_disabled.golden.yaml"}, @@ -348,6 +450,20 @@ var _ = Describe("MeshRateLimit", func() { }, }}, }, + InboundRules: map[core_rules.InboundListener][]*inbound.Rule{ + {Address: "127.0.0.1", Port: 17777}: {{ + Conf: []interface{}{ + api.Conf{ + Local: &api.Local{ + HTTP: &api.LocalHTTP{ + Disabled: pointer.To(true), + RequestRate: &api.Rate{Num: 100, Interval: *test.ParseDuration("10s")}, + }, + }, + }, + }, + }}, + }, }, inboundRateLimitsMap: core_xds.InboundRateLimitsMap{}, expectedListeners: []string{"http_disabled.golden.yaml"}, @@ -374,6 +490,19 @@ var _ = Describe("MeshRateLimit", func() { }, }}, }, + InboundRules: map[core_rules.InboundListener][]*inbound.Rule{ + {Address: "127.0.0.1", Port: 17778}: {{ + Conf: []interface{}{ + api.Conf{ + Local: &api.Local{ + TCP: &api.LocalTCP{ + ConnectionRate: nil, + }, + }, + }, + }, + }}, + }, }, inboundRateLimitsMap: core_xds.InboundRateLimitsMap{}, expectedListeners: []string{"tcp_disabled.golden.yaml"}, @@ -413,6 +542,19 @@ var _ = Describe("MeshRateLimit", func() { }, }}, }, + InboundRules: map[core_rules.InboundListener][]*inbound.Rule{ + {Address: "127.0.0.1", Port: 17777}: {{ + Conf: []interface{}{ + api.Conf{ + Local: &api.Local{ + HTTP: &api.LocalHTTP{ + RequestRate: nil, + }, + }, + }, + }, + }}, + }, }, inboundRateLimitsMap: core_xds.InboundRateLimitsMap{}, expectedListeners: []string{"http_disabled.golden.yaml"}, diff --git a/pkg/plugins/policies/meshratelimit/plugin/xds/configurer.go b/pkg/plugins/policies/meshratelimit/plugin/xds/configurer.go index d3553688e2d6..5694602f484c 100644 --- a/pkg/plugins/policies/meshratelimit/plugin/xds/configurer.go +++ b/pkg/plugins/policies/meshratelimit/plugin/xds/configurer.go @@ -58,6 +58,7 @@ func RateLimitConfigurationFromPolicy(rl *api.LocalHTTP) *envoy_routes_v3.RateLi type Configurer struct { Element subsetutils.Element Rules core_rules.Rules + Conf *api.Conf } func (c *Configurer) ConfigureFilterChain(filterChain *envoy_listener.FilterChain) error { @@ -246,6 +247,9 @@ func (c *Configurer) addRateLimitToRoute(route *envoy_route.Route, rateLimit *an } func (c *Configurer) getConf(element subsetutils.Element) *api.Conf { + if c.Conf != nil { + return c.Conf + } if c.Rules == nil { return &api.Conf{} } diff --git a/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.output.yaml b/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.output.yaml index 8b12654ca86f..21d5b0eb6e33 100644 --- a/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.output.yaml +++ b/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.output.yaml @@ -1,3 +1,3 @@ violations: - - field: spec.targetRef.sectionName - message: can only be used with inbound policies \ No newline at end of file +- field: spec.targetRef.sectionName + message: can only be used with inbound policies diff --git a/test/e2e_env/kubernetes/kubernetes_suite_test.go b/test/e2e_env/kubernetes/kubernetes_suite_test.go index 3135fee97213..65f5bc194f62 100644 --- a/test/e2e_env/kubernetes/kubernetes_suite_test.go +++ b/test/e2e_env/kubernetes/kubernetes_suite_test.go @@ -29,7 +29,6 @@ import ( "github.com/kumahq/kuma/test/e2e_env/kubernetes/meshmetric" "github.com/kumahq/kuma/test/e2e_env/kubernetes/meshpassthrough" "github.com/kumahq/kuma/test/e2e_env/kubernetes/meshproxypatch" - "github.com/kumahq/kuma/test/e2e_env/kubernetes/meshratelimit" "github.com/kumahq/kuma/test/e2e_env/kubernetes/meshretry" "github.com/kumahq/kuma/test/e2e_env/kubernetes/meshtcproute" "github.com/kumahq/kuma/test/e2e_env/kubernetes/meshtimeout" @@ -81,7 +80,6 @@ var ( _ = Describe("Virtual Outbound", virtualoutbound.VirtualOutbound, Ordered) _ = Describe("Kong Ingress Controller", kic.KICKubernetes, Ordered) _ = Describe("MeshTrafficPermission API", meshtrafficpermission.API, Ordered) - _ = Describe("MeshRateLimit API", meshratelimit.API, Ordered) _ = Describe("MeshTimeout API", meshtimeout.MeshTimeout, Ordered) _ = Describe("MeshHealthCheck API", meshhealthcheck.API, Ordered) _ = Describe("MeshCircuitBreaker API", meshcircuitbreaker.API, Ordered) diff --git a/test/e2e_env/kubernetes/meshratelimit/api.go b/test/e2e_env/kubernetes/meshratelimit/api.go deleted file mode 100644 index 6e14c69e99f3..000000000000 --- a/test/e2e_env/kubernetes/meshratelimit/api.go +++ /dev/null @@ -1,96 +0,0 @@ -package meshratelimit - -import ( - "fmt" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/kumahq/kuma/pkg/plugins/policies/meshratelimit/api/v1alpha1" - . "github.com/kumahq/kuma/test/framework" - "github.com/kumahq/kuma/test/framework/envs/kubernetes" -) - -func API() { - meshName := "meshratelimit-api" - - BeforeAll(func() { - err := NewClusterSetup(). - Install(MeshKubernetes(meshName)). - Setup(kubernetes.Cluster) - Expect(err).ToNot(HaveOccurred()) - }) - - AfterEachFailure(func() { - DebugKube(kubernetes.Cluster, meshName, Config.KumaNamespace) - }) - - E2EAfterEach(func() { - Expect(DeleteMeshResources(kubernetes.Cluster, meshName, v1alpha1.MeshRateLimitResourceTypeDescriptor)).To(Succeed()) - }) - - E2EAfterAll(func() { - Expect(kubernetes.Cluster.DeleteMesh(meshName)).To(Succeed()) - }) - - It("should create MeshRateLimit policy", func() { - // given no MeshRateLimit - mrls, err := kubernetes.Cluster.GetKumactlOptions().KumactlList("meshratelimits", meshName) - Expect(err).ToNot(HaveOccurred()) - Expect(mrls).To(BeEmpty()) - - // when - Expect(YamlK8s(fmt.Sprintf(` -apiVersion: kuma.io/v1alpha1 -kind: MeshRateLimit -metadata: - name: mesh-rate-limit - namespace: %s - labels: - kuma.io/mesh: %s -spec: - targetRef: - kind: MeshService - name: backend - from: - - targetRef: - kind: Mesh - default: - local: - http: - requestRate: - num: 1 - interval: 10s - onRateLimit: - status: 429 - headers: - add: - - name: "x-kuma-rate-limited" - value: "true" - - targetRef: - kind: Mesh - default: - local: - http: - requestRate: - num: 1 - interval: 10s - onRateLimit: - status: 429 - headers: - add: - - name: "x-kuma-rate-limited" - value: "true" - tcp: - connectionRate: - num: 100 - interval: 10s -`, Config.KumaNamespace, meshName))(kubernetes.Cluster)).To(Succeed()) - - // then - mrls, err = kubernetes.Cluster.GetKumactlOptions().KumactlList("meshratelimits", meshName) - Expect(err).ToNot(HaveOccurred()) - Expect(mrls).To(HaveLen(1)) - Expect(mrls[0]).To(Equal(fmt.Sprintf("mesh-rate-limit.%s", Config.KumaNamespace))) - }) -} diff --git a/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.demo-client.golden.json b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.demo-client.golden.json new file mode 100644 index 000000000000..af997888dfd0 --- /dev/null +++ b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.demo-client.golden.json @@ -0,0 +1,424 @@ +{ + "diff": [], + "xds": { + "type.googleapis.com/envoy.config.cluster.v3.Cluster": { + "envoyconfig_demo-client__kuma-3_msvc_3000": { + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "envoyconfig_demo-client__kuma-3_msvc_3000", + "type": "EDS", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + }, + "envoyconfig_test-server__kuma-3_msvc_80": { + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "envoyconfig_test-server__kuma-3_msvc_80", + "type": "EDS", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + }, + "inbound:passthrough:ipv4": { + "altStatName": "inbound_passthrough_ipv4", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "inbound:passthrough:ipv4", + "type": "ORIGINAL_DST", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "inbound:passthrough:ipv6": { + "altStatName": "inbound_passthrough_ipv6", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "inbound:passthrough:ipv6", + "type": "ORIGINAL_DST", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "localhost:3000": { + "altStatName": "localhost_3000", + "connectTimeout": "10s", + "loadAssignment": { + "clusterName": "localhost:3000", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + } + } + } + ] + } + ] + }, + "name": "localhost:3000", + "type": "STATIC", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "outbound:passthrough:ipv4": { + "altStatName": "outbound_passthrough_ipv4", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "outbound:passthrough:ipv4", + "type": "ORIGINAL_DST" + }, + "outbound:passthrough:ipv6": { + "altStatName": "outbound_passthrough_ipv6", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "outbound:passthrough:ipv6", + "type": "ORIGINAL_DST" + } + }, + "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment": { + "envoyconfig_demo-client__kuma-3_msvc_3000": { + "clusterName": "envoyconfig_demo-client__kuma-3_msvc_3000", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + } + }, + "loadBalancingWeight": 1, + "metadata": { + "filterMetadata": { + "envoy.lb": { + "kuma.io/zone": "kuma-3", + "team": "client-owners" + }, + "envoy.transport_socket_match": { + "kuma.io/zone": "kuma-3", + "team": "client-owners" + } + } + } + } + ], + "locality": { + "zone": "kuma-3" + } + } + ] + }, + "envoyconfig_test-server__kuma-3_msvc_80": { + "clusterName": "envoyconfig_test-server__kuma-3_msvc_80", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + } + }, + "loadBalancingWeight": 1, + "metadata": { + "filterMetadata": { + "envoy.lb": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + }, + "envoy.transport_socket_match": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + } + } + } + } + ], + "locality": { + "zone": "kuma-3" + } + } + ] + } + }, + "type.googleapis.com/envoy.config.listener.v3.Listener": { + "inbound:IP_REDACTED:3000": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + }, + "bindToPort": false, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "localhost:3000", + "idleTimeout": "7200s", + "statPrefix": "localhost_3000" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": { + "kuma.io/service": "demo-client", + "kuma.io/zone": "kuma-3", + "team": "client-owners" + } + } + }, + "name": "inbound:IP_REDACTED:3000", + "trafficDirection": "INBOUND" + }, + "inbound:passthrough:ipv4": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15006 + } + }, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "inbound:passthrough:ipv4", + "statPrefix": "inbound_passthrough_ipv4" + } + } + ] + } + ], + "name": "inbound:passthrough:ipv4", + "trafficDirection": "INBOUND", + "useOriginalDst": true + }, + "inbound:passthrough:ipv6": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15006 + } + }, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "inbound:passthrough:ipv6", + "statPrefix": "inbound_passthrough_ipv6" + } + } + ] + } + ], + "name": "inbound:passthrough:ipv6", + "trafficDirection": "INBOUND", + "useOriginalDst": true + }, + "outbound:IP_REDACTED:3000": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + }, + "bindToPort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "envoyconfig_demo-client__kuma-3_msvc_3000", + "statPrefix": "envoyconfig_demo-client__kuma-3_msvc_3000" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": {} + } + }, + "name": "outbound:IP_REDACTED:3000", + "trafficDirection": "OUTBOUND" + }, + "outbound:IP_REDACTED:80": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + }, + "bindToPort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "normalizePath": true, + "routeConfig": { + "name": "outbound:envoyconfig_test-server__kuma-3_msvc_80", + "validateClusters": false, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "envoyconfig_test-server__kuma-3_msvc_80", + "routes": [ + { + "match": { + "prefix": "/" + }, + "name": "9Zuf5Tg79OuZcQITwBbQykxAk2u4fRKrwYn3//AL4Yo=", + "route": { + "cluster": "envoyconfig_test-server__kuma-3_msvc_80", + "timeout": "0s" + } + } + ] + } + ] + }, + "statPrefix": "envoyconfig_test-server__kuma-3_msvc_80" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": {} + } + }, + "name": "outbound:IP_REDACTED:80", + "trafficDirection": "OUTBOUND" + }, + "outbound:passthrough:ipv4": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "outbound:passthrough:ipv4", + "statPrefix": "outbound_passthrough_ipv4" + } + } + ] + } + ], + "name": "outbound:passthrough:ipv4", + "trafficDirection": "OUTBOUND", + "useOriginalDst": true + }, + "outbound:passthrough:ipv6": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "outbound:passthrough:ipv6", + "statPrefix": "outbound_passthrough_ipv6" + } + } + ] + } + ], + "name": "outbound:passthrough:ipv6", + "trafficDirection": "OUTBOUND", + "useOriginalDst": true + } + } + } +} diff --git a/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.input.yaml b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.input.yaml new file mode 100644 index 000000000000..6ef77f03e9cf --- /dev/null +++ b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.input.yaml @@ -0,0 +1,22 @@ +type: MeshRateLimit +name: mrl-1 +mesh: envoyconfig +labels: + kuma.io/effect: shadow +spec: + targetRef: + kind: Dataplane + name: test-server + rules: + - default: + local: + http: + requestRate: + num: 5 + interval: 10s + onRateLimit: + status: 423 + headers: + set: + - name: x-kuma-rate-limited + value: 'true' diff --git a/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.test-server.golden.json b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.test-server.golden.json new file mode 100644 index 000000000000..ab66357e11b9 --- /dev/null +++ b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules-dpp.test-server.golden.json @@ -0,0 +1,571 @@ +{ + "diff": [ + { + "op": "add", + "path": "/type.googleapis.com~1envoy.config.listener.v3.Listener/inbound:IP_REDACTED:80/filterChains/0/filters/0/typedConfig/httpFilters/0", + "value": { + "name": "envoy.filters.http.local_ratelimit", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit", + "statPrefix": "rate_limit" + } + } + }, + { + "op": "add", + "path": "/type.googleapis.com~1envoy.config.listener.v3.Listener/inbound:IP_REDACTED:80/filterChains/0/filters/0/typedConfig/routeConfig/virtualHosts/0/routes/0/typedPerFilterConfig", + "value": { + "envoy.filters.http.local_ratelimit": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit", + "filterEnabled": { + "defaultValue": { + "numerator": 100 + }, + "runtimeKey": "local_rate_limit_enabled" + }, + "filterEnforced": { + "defaultValue": { + "numerator": 100 + }, + "runtimeKey": "local_rate_limit_enforced" + }, + "responseHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-kuma-rate-limited", + "value": "true" + } + } + ], + "statPrefix": "rate_limit", + "status": { + "code": "Locked" + }, + "tokenBucket": { + "fillInterval": "10s", + "maxTokens": 5, + "tokensPerFill": 5 + } + } + } + } + ], + "xds": { + "type.googleapis.com/envoy.config.cluster.v3.Cluster": { + "envoyconfig_demo-client__kuma-3_msvc_3000": { + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "envoyconfig_demo-client__kuma-3_msvc_3000", + "type": "EDS", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + }, + "envoyconfig_test-server__kuma-3_msvc_80": { + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "envoyconfig_test-server__kuma-3_msvc_80", + "type": "EDS", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + }, + "inbound:passthrough:ipv4": { + "altStatName": "inbound_passthrough_ipv4", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "inbound:passthrough:ipv4", + "type": "ORIGINAL_DST", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "inbound:passthrough:ipv6": { + "altStatName": "inbound_passthrough_ipv6", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "inbound:passthrough:ipv6", + "type": "ORIGINAL_DST", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "localhost:8080": { + "altStatName": "localhost_8080", + "connectTimeout": "10s", + "loadAssignment": { + "clusterName": "localhost:8080", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 8080 + } + } + } + } + ] + } + ] + }, + "name": "localhost:8080", + "type": "STATIC", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "commonHttpProtocolOptions": { + "idleTimeout": "7200s" + }, + "explicitHttpConfig": { + "httpProtocolOptions": {} + } + } + }, + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "outbound:passthrough:ipv4": { + "altStatName": "outbound_passthrough_ipv4", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "outbound:passthrough:ipv4", + "type": "ORIGINAL_DST" + }, + "outbound:passthrough:ipv6": { + "altStatName": "outbound_passthrough_ipv6", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "outbound:passthrough:ipv6", + "type": "ORIGINAL_DST" + } + }, + "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment": { + "envoyconfig_demo-client__kuma-3_msvc_3000": { + "clusterName": "envoyconfig_demo-client__kuma-3_msvc_3000", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + } + }, + "loadBalancingWeight": 1, + "metadata": { + "filterMetadata": { + "envoy.lb": { + "kuma.io/zone": "kuma-3", + "team": "client-owners" + }, + "envoy.transport_socket_match": { + "kuma.io/zone": "kuma-3", + "team": "client-owners" + } + } + } + } + ], + "locality": { + "zone": "kuma-3" + } + } + ] + }, + "envoyconfig_test-server__kuma-3_msvc_80": { + "clusterName": "envoyconfig_test-server__kuma-3_msvc_80", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + } + }, + "loadBalancingWeight": 1, + "metadata": { + "filterMetadata": { + "envoy.lb": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + }, + "envoy.transport_socket_match": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + } + } + } + } + ], + "locality": { + "zone": "kuma-3" + } + } + ] + } + }, + "type.googleapis.com/envoy.config.listener.v3.Listener": { + "inbound:IP_REDACTED:80": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + }, + "bindToPort": false, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "commonHttpProtocolOptions": { + "idleTimeout": "7200s" + }, + "forwardClientCertDetails": "SANITIZE_SET", + "httpFilters": [ + { + "name": "envoy.filters.http.local_ratelimit", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit", + "statPrefix": "rate_limit" + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "routeConfig": { + "name": "inbound:test-server", + "requestHeadersToRemove": [ + "x-kuma-tags" + ], + "validateClusters": false, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "test-server", + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "localhost:8080", + "timeout": "0s" + }, + "typedPerFilterConfig": { + "envoy.filters.http.local_ratelimit": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit", + "filterEnabled": { + "defaultValue": { + "numerator": 100 + }, + "runtimeKey": "local_rate_limit_enabled" + }, + "filterEnforced": { + "defaultValue": { + "numerator": 100 + }, + "runtimeKey": "local_rate_limit_enforced" + }, + "responseHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-kuma-rate-limited", + "value": "true" + } + } + ], + "statPrefix": "rate_limit", + "status": { + "code": "Locked" + }, + "tokenBucket": { + "fillInterval": "10s", + "maxTokens": 5, + "tokensPerFill": 5 + } + } + } + } + ] + } + ] + }, + "setCurrentClientCertDetails": { + "uri": true + }, + "statPrefix": "localhost_8080", + "streamIdleTimeout": "3600s" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/service": "test-server", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + } + } + }, + "name": "inbound:IP_REDACTED:80", + "trafficDirection": "INBOUND" + }, + "inbound:passthrough:ipv4": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15006 + } + }, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "inbound:passthrough:ipv4", + "statPrefix": "inbound_passthrough_ipv4" + } + } + ] + } + ], + "name": "inbound:passthrough:ipv4", + "trafficDirection": "INBOUND", + "useOriginalDst": true + }, + "inbound:passthrough:ipv6": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15006 + } + }, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "inbound:passthrough:ipv6", + "statPrefix": "inbound_passthrough_ipv6" + } + } + ] + } + ], + "name": "inbound:passthrough:ipv6", + "trafficDirection": "INBOUND", + "useOriginalDst": true + }, + "outbound:IP_REDACTED:3000": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + }, + "bindToPort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "envoyconfig_demo-client__kuma-3_msvc_3000", + "statPrefix": "envoyconfig_demo-client__kuma-3_msvc_3000" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": {} + } + }, + "name": "outbound:IP_REDACTED:3000", + "trafficDirection": "OUTBOUND" + }, + "outbound:IP_REDACTED:80": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + }, + "bindToPort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "normalizePath": true, + "routeConfig": { + "name": "outbound:envoyconfig_test-server__kuma-3_msvc_80", + "validateClusters": false, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "envoyconfig_test-server__kuma-3_msvc_80", + "routes": [ + { + "match": { + "prefix": "/" + }, + "name": "9Zuf5Tg79OuZcQITwBbQykxAk2u4fRKrwYn3//AL4Yo=", + "route": { + "cluster": "envoyconfig_test-server__kuma-3_msvc_80", + "timeout": "0s" + } + } + ] + } + ] + }, + "statPrefix": "envoyconfig_test-server__kuma-3_msvc_80" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": {} + } + }, + "name": "outbound:IP_REDACTED:80", + "trafficDirection": "OUTBOUND" + }, + "outbound:passthrough:ipv4": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "outbound:passthrough:ipv4", + "statPrefix": "outbound_passthrough_ipv4" + } + } + ] + } + ], + "name": "outbound:passthrough:ipv4", + "trafficDirection": "OUTBOUND", + "useOriginalDst": true + }, + "outbound:passthrough:ipv6": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "outbound:passthrough:ipv6", + "statPrefix": "outbound_passthrough_ipv6" + } + } + ] + } + ], + "name": "outbound:passthrough:ipv6", + "trafficDirection": "OUTBOUND", + "useOriginalDst": true + } + } + } +} diff --git a/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.demo-client.golden.json b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.demo-client.golden.json new file mode 100644 index 000000000000..af997888dfd0 --- /dev/null +++ b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.demo-client.golden.json @@ -0,0 +1,424 @@ +{ + "diff": [], + "xds": { + "type.googleapis.com/envoy.config.cluster.v3.Cluster": { + "envoyconfig_demo-client__kuma-3_msvc_3000": { + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "envoyconfig_demo-client__kuma-3_msvc_3000", + "type": "EDS", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + }, + "envoyconfig_test-server__kuma-3_msvc_80": { + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "envoyconfig_test-server__kuma-3_msvc_80", + "type": "EDS", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + }, + "inbound:passthrough:ipv4": { + "altStatName": "inbound_passthrough_ipv4", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "inbound:passthrough:ipv4", + "type": "ORIGINAL_DST", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "inbound:passthrough:ipv6": { + "altStatName": "inbound_passthrough_ipv6", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "inbound:passthrough:ipv6", + "type": "ORIGINAL_DST", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "localhost:3000": { + "altStatName": "localhost_3000", + "connectTimeout": "10s", + "loadAssignment": { + "clusterName": "localhost:3000", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + } + } + } + ] + } + ] + }, + "name": "localhost:3000", + "type": "STATIC", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "outbound:passthrough:ipv4": { + "altStatName": "outbound_passthrough_ipv4", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "outbound:passthrough:ipv4", + "type": "ORIGINAL_DST" + }, + "outbound:passthrough:ipv6": { + "altStatName": "outbound_passthrough_ipv6", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "outbound:passthrough:ipv6", + "type": "ORIGINAL_DST" + } + }, + "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment": { + "envoyconfig_demo-client__kuma-3_msvc_3000": { + "clusterName": "envoyconfig_demo-client__kuma-3_msvc_3000", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + } + }, + "loadBalancingWeight": 1, + "metadata": { + "filterMetadata": { + "envoy.lb": { + "kuma.io/zone": "kuma-3", + "team": "client-owners" + }, + "envoy.transport_socket_match": { + "kuma.io/zone": "kuma-3", + "team": "client-owners" + } + } + } + } + ], + "locality": { + "zone": "kuma-3" + } + } + ] + }, + "envoyconfig_test-server__kuma-3_msvc_80": { + "clusterName": "envoyconfig_test-server__kuma-3_msvc_80", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + } + }, + "loadBalancingWeight": 1, + "metadata": { + "filterMetadata": { + "envoy.lb": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + }, + "envoy.transport_socket_match": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + } + } + } + } + ], + "locality": { + "zone": "kuma-3" + } + } + ] + } + }, + "type.googleapis.com/envoy.config.listener.v3.Listener": { + "inbound:IP_REDACTED:3000": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + }, + "bindToPort": false, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "localhost:3000", + "idleTimeout": "7200s", + "statPrefix": "localhost_3000" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": { + "kuma.io/service": "demo-client", + "kuma.io/zone": "kuma-3", + "team": "client-owners" + } + } + }, + "name": "inbound:IP_REDACTED:3000", + "trafficDirection": "INBOUND" + }, + "inbound:passthrough:ipv4": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15006 + } + }, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "inbound:passthrough:ipv4", + "statPrefix": "inbound_passthrough_ipv4" + } + } + ] + } + ], + "name": "inbound:passthrough:ipv4", + "trafficDirection": "INBOUND", + "useOriginalDst": true + }, + "inbound:passthrough:ipv6": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15006 + } + }, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "inbound:passthrough:ipv6", + "statPrefix": "inbound_passthrough_ipv6" + } + } + ] + } + ], + "name": "inbound:passthrough:ipv6", + "trafficDirection": "INBOUND", + "useOriginalDst": true + }, + "outbound:IP_REDACTED:3000": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + }, + "bindToPort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "envoyconfig_demo-client__kuma-3_msvc_3000", + "statPrefix": "envoyconfig_demo-client__kuma-3_msvc_3000" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": {} + } + }, + "name": "outbound:IP_REDACTED:3000", + "trafficDirection": "OUTBOUND" + }, + "outbound:IP_REDACTED:80": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + }, + "bindToPort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "normalizePath": true, + "routeConfig": { + "name": "outbound:envoyconfig_test-server__kuma-3_msvc_80", + "validateClusters": false, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "envoyconfig_test-server__kuma-3_msvc_80", + "routes": [ + { + "match": { + "prefix": "/" + }, + "name": "9Zuf5Tg79OuZcQITwBbQykxAk2u4fRKrwYn3//AL4Yo=", + "route": { + "cluster": "envoyconfig_test-server__kuma-3_msvc_80", + "timeout": "0s" + } + } + ] + } + ] + }, + "statPrefix": "envoyconfig_test-server__kuma-3_msvc_80" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": {} + } + }, + "name": "outbound:IP_REDACTED:80", + "trafficDirection": "OUTBOUND" + }, + "outbound:passthrough:ipv4": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "outbound:passthrough:ipv4", + "statPrefix": "outbound_passthrough_ipv4" + } + } + ] + } + ], + "name": "outbound:passthrough:ipv4", + "trafficDirection": "OUTBOUND", + "useOriginalDst": true + }, + "outbound:passthrough:ipv6": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "outbound:passthrough:ipv6", + "statPrefix": "outbound_passthrough_ipv6" + } + } + ] + } + ], + "name": "outbound:passthrough:ipv6", + "trafficDirection": "OUTBOUND", + "useOriginalDst": true + } + } + } +} diff --git a/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.input.yaml b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.input.yaml new file mode 100644 index 000000000000..998d2e6bd318 --- /dev/null +++ b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.input.yaml @@ -0,0 +1,22 @@ +type: MeshRateLimit +name: mrl-1 +mesh: envoyconfig +labels: + kuma.io/effect: shadow +spec: + targetRef: + kind: Mesh + proxyTypes: [Sidecar] + rules: + - default: + local: + http: + requestRate: + num: 5 + interval: 10s + onRateLimit: + status: 423 + headers: + set: + - name: x-kuma-rate-limited + value: 'true' diff --git a/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.test-server.golden.json b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.test-server.golden.json new file mode 100644 index 000000000000..ab66357e11b9 --- /dev/null +++ b/test/e2e_env/universal/envoyconfig/testdata/meshratelimit/inbound-rules.test-server.golden.json @@ -0,0 +1,571 @@ +{ + "diff": [ + { + "op": "add", + "path": "/type.googleapis.com~1envoy.config.listener.v3.Listener/inbound:IP_REDACTED:80/filterChains/0/filters/0/typedConfig/httpFilters/0", + "value": { + "name": "envoy.filters.http.local_ratelimit", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit", + "statPrefix": "rate_limit" + } + } + }, + { + "op": "add", + "path": "/type.googleapis.com~1envoy.config.listener.v3.Listener/inbound:IP_REDACTED:80/filterChains/0/filters/0/typedConfig/routeConfig/virtualHosts/0/routes/0/typedPerFilterConfig", + "value": { + "envoy.filters.http.local_ratelimit": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit", + "filterEnabled": { + "defaultValue": { + "numerator": 100 + }, + "runtimeKey": "local_rate_limit_enabled" + }, + "filterEnforced": { + "defaultValue": { + "numerator": 100 + }, + "runtimeKey": "local_rate_limit_enforced" + }, + "responseHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-kuma-rate-limited", + "value": "true" + } + } + ], + "statPrefix": "rate_limit", + "status": { + "code": "Locked" + }, + "tokenBucket": { + "fillInterval": "10s", + "maxTokens": 5, + "tokensPerFill": 5 + } + } + } + } + ], + "xds": { + "type.googleapis.com/envoy.config.cluster.v3.Cluster": { + "envoyconfig_demo-client__kuma-3_msvc_3000": { + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "envoyconfig_demo-client__kuma-3_msvc_3000", + "type": "EDS", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + }, + "envoyconfig_test-server__kuma-3_msvc_80": { + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "envoyconfig_test-server__kuma-3_msvc_80", + "type": "EDS", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + }, + "inbound:passthrough:ipv4": { + "altStatName": "inbound_passthrough_ipv4", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "inbound:passthrough:ipv4", + "type": "ORIGINAL_DST", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "inbound:passthrough:ipv6": { + "altStatName": "inbound_passthrough_ipv6", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "inbound:passthrough:ipv6", + "type": "ORIGINAL_DST", + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "localhost:8080": { + "altStatName": "localhost_8080", + "connectTimeout": "10s", + "loadAssignment": { + "clusterName": "localhost:8080", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 8080 + } + } + } + } + ] + } + ] + }, + "name": "localhost:8080", + "type": "STATIC", + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "commonHttpProtocolOptions": { + "idleTimeout": "7200s" + }, + "explicitHttpConfig": { + "httpProtocolOptions": {} + } + } + }, + "upstreamBindConfig": { + "sourceAddress": { + "address": "IP_REDACTED", + "portValue": 0 + } + } + }, + "outbound:passthrough:ipv4": { + "altStatName": "outbound_passthrough_ipv4", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "outbound:passthrough:ipv4", + "type": "ORIGINAL_DST" + }, + "outbound:passthrough:ipv6": { + "altStatName": "outbound_passthrough_ipv6", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED", + "name": "outbound:passthrough:ipv6", + "type": "ORIGINAL_DST" + } + }, + "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment": { + "envoyconfig_demo-client__kuma-3_msvc_3000": { + "clusterName": "envoyconfig_demo-client__kuma-3_msvc_3000", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + } + }, + "loadBalancingWeight": 1, + "metadata": { + "filterMetadata": { + "envoy.lb": { + "kuma.io/zone": "kuma-3", + "team": "client-owners" + }, + "envoy.transport_socket_match": { + "kuma.io/zone": "kuma-3", + "team": "client-owners" + } + } + } + } + ], + "locality": { + "zone": "kuma-3" + } + } + ] + }, + "envoyconfig_test-server__kuma-3_msvc_80": { + "clusterName": "envoyconfig_test-server__kuma-3_msvc_80", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + } + }, + "loadBalancingWeight": 1, + "metadata": { + "filterMetadata": { + "envoy.lb": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + }, + "envoy.transport_socket_match": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + } + } + } + } + ], + "locality": { + "zone": "kuma-3" + } + } + ] + } + }, + "type.googleapis.com/envoy.config.listener.v3.Listener": { + "inbound:IP_REDACTED:80": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + }, + "bindToPort": false, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "commonHttpProtocolOptions": { + "idleTimeout": "7200s" + }, + "forwardClientCertDetails": "SANITIZE_SET", + "httpFilters": [ + { + "name": "envoy.filters.http.local_ratelimit", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit", + "statPrefix": "rate_limit" + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "routeConfig": { + "name": "inbound:test-server", + "requestHeadersToRemove": [ + "x-kuma-tags" + ], + "validateClusters": false, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "test-server", + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "localhost:8080", + "timeout": "0s" + }, + "typedPerFilterConfig": { + "envoy.filters.http.local_ratelimit": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit", + "filterEnabled": { + "defaultValue": { + "numerator": 100 + }, + "runtimeKey": "local_rate_limit_enabled" + }, + "filterEnforced": { + "defaultValue": { + "numerator": 100 + }, + "runtimeKey": "local_rate_limit_enforced" + }, + "responseHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-kuma-rate-limited", + "value": "true" + } + } + ], + "statPrefix": "rate_limit", + "status": { + "code": "Locked" + }, + "tokenBucket": { + "fillInterval": "10s", + "maxTokens": 5, + "tokensPerFill": 5 + } + } + } + } + ] + } + ] + }, + "setCurrentClientCertDetails": { + "uri": true + }, + "statPrefix": "localhost_8080", + "streamIdleTimeout": "3600s" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": { + "instance": "1", + "kuma.io/protocol": "http", + "kuma.io/service": "test-server", + "kuma.io/zone": "kuma-3", + "team": "server-owners", + "version": "v1" + } + } + }, + "name": "inbound:IP_REDACTED:80", + "trafficDirection": "INBOUND" + }, + "inbound:passthrough:ipv4": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15006 + } + }, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "inbound:passthrough:ipv4", + "statPrefix": "inbound_passthrough_ipv4" + } + } + ] + } + ], + "name": "inbound:passthrough:ipv4", + "trafficDirection": "INBOUND", + "useOriginalDst": true + }, + "inbound:passthrough:ipv6": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15006 + } + }, + "enableReusePort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "inbound:passthrough:ipv6", + "statPrefix": "inbound_passthrough_ipv6" + } + } + ] + } + ], + "name": "inbound:passthrough:ipv6", + "trafficDirection": "INBOUND", + "useOriginalDst": true + }, + "outbound:IP_REDACTED:3000": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 3000 + } + }, + "bindToPort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "envoyconfig_demo-client__kuma-3_msvc_3000", + "statPrefix": "envoyconfig_demo-client__kuma-3_msvc_3000" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": {} + } + }, + "name": "outbound:IP_REDACTED:3000", + "trafficDirection": "OUTBOUND" + }, + "outbound:IP_REDACTED:80": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 80 + } + }, + "bindToPort": false, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "normalizePath": true, + "routeConfig": { + "name": "outbound:envoyconfig_test-server__kuma-3_msvc_80", + "validateClusters": false, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "envoyconfig_test-server__kuma-3_msvc_80", + "routes": [ + { + "match": { + "prefix": "/" + }, + "name": "9Zuf5Tg79OuZcQITwBbQykxAk2u4fRKrwYn3//AL4Yo=", + "route": { + "cluster": "envoyconfig_test-server__kuma-3_msvc_80", + "timeout": "0s" + } + } + ] + } + ] + }, + "statPrefix": "envoyconfig_test-server__kuma-3_msvc_80" + } + } + ] + } + ], + "metadata": { + "filterMetadata": { + "io.kuma.tags": {} + } + }, + "name": "outbound:IP_REDACTED:80", + "trafficDirection": "OUTBOUND" + }, + "outbound:passthrough:ipv4": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "outbound:passthrough:ipv4", + "statPrefix": "outbound_passthrough_ipv4" + } + } + ] + } + ], + "name": "outbound:passthrough:ipv4", + "trafficDirection": "OUTBOUND", + "useOriginalDst": true + }, + "outbound:passthrough:ipv6": { + "address": { + "socketAddress": { + "address": "IP_REDACTED", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "cluster": "outbound:passthrough:ipv6", + "statPrefix": "outbound_passthrough_ipv6" + } + } + ] + } + ], + "name": "outbound:passthrough:ipv6", + "trafficDirection": "OUTBOUND", + "useOriginalDst": true + } + } + } +} diff --git a/test/e2e_env/universal/meshratelimit/meshratelimit.go b/test/e2e_env/universal/meshratelimit/meshratelimit.go index d848ad1fad72..36f76f31cb3e 100644 --- a/test/e2e_env/universal/meshratelimit/meshratelimit.go +++ b/test/e2e_env/universal/meshratelimit/meshratelimit.go @@ -23,10 +23,8 @@ spec: targetRef: kind: MeshService name: test-server - from: - - targetRef: - kind: Mesh - default: + rules: + - default: local: http: requestRate: @@ -46,10 +44,8 @@ spec: targetRef: kind: MeshService name: test-server-tcp - from: - - targetRef: - kind: Mesh - default: + rules: + - default: local: tcp: connectionRate: