From 2a03c58a7de443da740f1ab9d86fed87237f637d Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Tue, 24 Jan 2023 09:39:48 -0800 Subject: [PATCH] RateLimitFilter: Gateway API to Xds IR translaton (#933) * RateLimitFilter: Gateway API to Xds IR translaton * Also rm'ed `ResetConditon` and instead set `Accepted=False` for negative cases for ExtensionFilter cases Relates to https://github.com/envoyproxy/gateway/issues/670 Signed-off-by: Arko Dasgupta --- internal/gatewayapi/filters.go | 131 +++++++++++++----- internal/gatewayapi/route.go | 5 + ...route-with-invalid-ratelimitfilter.in.yaml | 60 ++++++++ ...oute-with-invalid-ratelimitfilter.out.yaml | 106 ++++++++++++++ ...with-non-existent-authenfilter-ref.in.yaml | 2 +- ...ith-non-existent-authenfilter-ref.out.yaml | 10 +- ...with-non-matching-authenfilter-ref.in.yaml | 2 +- ...ith-non-matching-authenfilter-ref.out.yaml | 10 +- ...tproute-with-valid-ratelimitfilter.in.yaml | 59 ++++++++ ...proute-with-valid-ratelimitfilter.out.yaml | 110 +++++++++++++++ internal/ir/xds.go | 11 +- internal/xds/translator/ratelimit.go | 4 +- 12 files changed, 456 insertions(+), 54 deletions(-) create mode 100644 internal/gatewayapi/testdata/httproute-with-invalid-ratelimitfilter.in.yaml create mode 100644 internal/gatewayapi/testdata/httproute-with-invalid-ratelimitfilter.out.yaml create mode 100644 internal/gatewayapi/testdata/httproute-with-valid-ratelimitfilter.in.yaml create mode 100644 internal/gatewayapi/testdata/httproute-with-valid-ratelimitfilter.out.yaml diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go index 4b4b3b3c1a1..10b2f98c03b 100644 --- a/internal/gatewayapi/filters.go +++ b/internal/gatewayapi/filters.go @@ -12,6 +12,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/gateway-api/apis/v1beta1" + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" ) @@ -55,6 +56,7 @@ type HTTPFilterChains struct { Mirrors []*ir.RouteDestination RequestAuthentication *ir.RequestAuthentication + RateLimit *ir.RateLimit } // ProcessHTTPFilters translate gateway api http filters to IRs. @@ -622,50 +624,90 @@ func (t *Translator) processExtensionRefHTTPFilter(filter v1beta1.HTTPRouteFilte return } - // Set negative status condition and return early if the no AuthenticationFilters exist. - if len(resources.AuthenticationFilters) == 0 { - errMsg := fmt.Sprintf("Reference not found for filter type: %v", filter.Type) - filterContext.ParentRef.ResetConditions(filterContext.HTTPRoute) - filterContext.ParentRef.SetCondition(filterContext.HTTPRoute, - v1beta1.RouteConditionResolvedRefs, - metav1.ConditionFalse, - v1beta1.RouteReasonBackendNotFound, - errMsg, - ) - filterContext.DirectResponse = &ir.DirectResponse{ - Body: &errMsg, - StatusCode: 500, + // Set the filter context and return early if a matching AuthenticationFilter is found. + if string(filter.ExtensionRef.Kind) == egv1a1.KindAuthenticationFilter { + for _, authenFilter := range resources.AuthenticationFilters { + if authenFilter.Namespace == filterContext.HTTPRoute.Namespace && + authenFilter.Name == string(extFilter.Name) { + filterContext.HTTPFilterChains.RequestAuthentication = &ir.RequestAuthentication{ + JWT: &ir.JwtRequestAuthentication{ + Providers: authenFilter.Spec.JwtProviders, + }, + } + return + } } - return } - // Set the filter context and return early if a matching AuthenticationFilter is found. - for _, authenFilter := range resources.AuthenticationFilters { - if authenFilter.Namespace == filterContext.HTTPRoute.Namespace && - authenFilter.Name == string(extFilter.Name) { - filterContext.HTTPFilterChains.RequestAuthentication = &ir.RequestAuthentication{ - JWT: &ir.JwtRequestAuthentication{ - Providers: authenFilter.Spec.JwtProviders, - }, + // Set the filter context and return early if a matching RateLimitFilter is found. + if string(filter.ExtensionRef.Kind) == egv1a1.KindRateLimitFilter { + for _, rateLimitFilter := range resources.RateLimitFilters { + if rateLimitFilter.Namespace == filterContext.HTTPRoute.Namespace && + rateLimitFilter.Name == string(extFilter.Name) { + if rateLimitFilter.Spec.Global == nil { + errMsg := fmt.Sprintf("Global configuration empty for RateLimitFilter: %s/%s", filterContext.HTTPRoute.Namespace, + filter.ExtensionRef.Name) + t.processUnresolvedHTTPFilter(errMsg, filterContext) + return + } + rateLimit := &ir.RateLimit{ + Global: &ir.GlobalRateLimit{ + Rules: make([]*ir.RateLimitRule, len(rateLimitFilter.Spec.Global.Rules)), + }, + } + rules := rateLimit.Global.Rules + for i, rule := range rateLimitFilter.Spec.Global.Rules { + rules[i] = &ir.RateLimitRule{ + Limit: &ir.RateLimitValue{ + Requests: rule.Limit.Requests, + Unit: ir.RateLimitUnit(rule.Limit.Unit), + }, + HeaderMatches: make([]*ir.StringMatch, 0), + } + for _, match := range rule.ClientSelectors { + for _, header := range match.Headers { + switch { + case header.Type == nil && header.Value != nil: + fallthrough + case *header.Type == egv1a1.HeaderMatchExact && header.Value != nil: + m := &ir.StringMatch{ + Name: header.Name, + Exact: header.Value, + } + rules[i].HeaderMatches = append(rules[i].HeaderMatches, m) + case *header.Type == egv1a1.HeaderMatchRegularExpression && header.Value != nil: + m := &ir.StringMatch{ + Name: header.Name, + SafeRegex: header.Value, + } + rules[i].HeaderMatches = append(rules[i].HeaderMatches, m) + case *header.Type == egv1a1.HeaderMatchRegularExpression && header.Value == nil: + m := &ir.StringMatch{ + Name: header.Name, + Distinct: true, + } + rules[i].HeaderMatches = append(rules[i].HeaderMatches, m) + default: + // set negative status condition. + errMsg := fmt.Sprintf("Unable to translate RateLimitFilter: %s/%s", filterContext.HTTPRoute.Namespace, + filter.ExtensionRef.Name) + t.processUnresolvedHTTPFilter(errMsg, filterContext) + return + } + } + } + + } + filterContext.HTTPFilterChains.RateLimit = rateLimit + return } - return } } - // Matching AuthenticationFilter not found, so set negative status condition. + // Matching filter not found, so set negative status condition. errMsg := fmt.Sprintf("Reference %s/%s not found for filter type: %v", filterContext.HTTPRoute.Namespace, filter.ExtensionRef.Name, filter.Type) - filterContext.ParentRef.ResetConditions(filterContext.HTTPRoute) - filterContext.ParentRef.SetCondition(filterContext.HTTPRoute, - v1beta1.RouteConditionResolvedRefs, - metav1.ConditionFalse, - v1beta1.RouteReasonBackendNotFound, - errMsg, - ) - filterContext.DirectResponse = &ir.DirectResponse{ - Body: &errMsg, - StatusCode: 500, - } + t.processUnresolvedHTTPFilter(errMsg, filterContext) } func (t *Translator) processRequestMirrorFilter( @@ -711,6 +753,25 @@ func (t *Translator) processRequestMirrorFilter( } +func (t *Translator) processUnresolvedHTTPFilter(errMsg string, filterContext *HTTPFiltersContext) { + filterContext.ParentRef.SetCondition(filterContext.HTTPRoute, + v1beta1.RouteConditionResolvedRefs, + metav1.ConditionFalse, + v1beta1.RouteReasonBackendNotFound, + errMsg, + ) + filterContext.ParentRef.SetCondition(filterContext.HTTPRoute, + v1beta1.RouteConditionAccepted, + metav1.ConditionFalse, + v1beta1.RouteReasonUnsupportedValue, + errMsg, + ) + filterContext.DirectResponse = &ir.DirectResponse{ + Body: &errMsg, + StatusCode: 500, + } +} + func (t *Translator) processUnsupportedHTTPFilter(filter v1beta1.HTTPRouteFilter, filterContext *HTTPFiltersContext) { errMsg := fmt.Sprintf("Unsupported filter type: %s", filter.Type) filterContext.ParentRef.SetCondition(filterContext.HTTPRoute, diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index 546b49c366b..0c69692f8c0 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -226,6 +226,10 @@ func (t *Translator) processHTTPRouteRule(httpRoute *HTTPRouteContext, ruleIdx i if httpFiltersContext.RequestAuthentication != nil { irRoute.RequestAuthentication = httpFiltersContext.RequestAuthentication } + if httpFiltersContext.RateLimit != nil { + irRoute.RateLimit = httpFiltersContext.RateLimit + } + ruleRoutes = append(ruleRoutes, irRoute) } @@ -280,6 +284,7 @@ func (t *Translator) processHTTPRouteParentRefListener(httpRoute *HTTPRouteConte URLRewrite: routeRoute.URLRewrite, Mirrors: routeRoute.Mirrors, RequestAuthentication: routeRoute.RequestAuthentication, + RateLimit: routeRoute.RateLimit, } // Don't bother copying over the weights unless the route has invalid backends. if routeRoute.BackendWeights.Invalid > 0 { diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-ratelimitfilter.in.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-ratelimitfilter.in.yaml new file mode 100644 index 00000000000..4883307c8e7 --- /dev/null +++ b/internal/gatewayapi/testdata/httproute-with-invalid-ratelimitfilter.in.yaml @@ -0,0 +1,60 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 + filters: + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: test +rateLimitFilters: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: RateLimitFilter + metadata: + name: test + namespace: default + spec: + type: Global + global: + rules: + - clientSelectors: + - headers: + - type: Distinct + name: x-user-id + value: one + limit: + requests: 10 + unit: Hour diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-ratelimitfilter.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-ratelimitfilter.out.yaml new file mode 100644 index 00000000000..261364b75f8 --- /dev/null +++ b/internal/gatewayapi/testdata/httproute-with-invalid-ratelimitfilter.out.yaml @@ -0,0 +1,106 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All + status: + listeners: + - name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + attachedRoutes: 1 + conditions: + - type: Programmed + status: "True" + reason: Programmed + message: Listener is ready +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 + filters: + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: test + status: + parents: + - parentRef: + namespace: envoy-gateway + name: gateway-1 + sectionName: http + controllerName: gateway.envoyproxy.io/gatewayclass-controller + conditions: + - type: Accepted + status: "False" + reason: UnsupportedValue + message: "Unable to translate RateLimitFilter: default/test" + - type: ResolvedRefs + status: "False" + reason: BackendNotFound + message: "Unable to translate RateLimitFilter: default/test" +xdsIR: + envoy-gateway-gateway-1: + http: + - name: envoy-gateway-gateway-1-http + address: 0.0.0.0 + port: 10080 + hostnames: + - "*.envoyproxy.io" + routes: + - name: default-httproute-1-rule-0-match-0-gateway.envoyproxy.io + pathMatch: + prefix: "/" + headerMatches: + - name: ":authority" + exact: gateway.envoyproxy.io + # I believe the correct way to handle an invalid filter should be to allow the HTTPRoute to function + # normally but leave out the filter config and set the status, but this behaviour can be changed. + directResponse: + body: "Unable to translate RateLimitFilter: default/test" + statusCode: 500 +infraIR: + envoy-gateway-gateway-1: + proxy: + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + name: envoy-gateway-gateway-1 + image: envoyproxy/envoy:translator-tests + listeners: + - address: "" + ports: + - name: http + protocol: "HTTP" + containerPort: 10080 + servicePort: 80 diff --git a/internal/gatewayapi/testdata/httproute-with-non-existent-authenfilter-ref.in.yaml b/internal/gatewayapi/testdata/httproute-with-non-existent-authenfilter-ref.in.yaml index fa040d26f83..7fdb47e419c 100644 --- a/internal/gatewayapi/testdata/httproute-with-non-existent-authenfilter-ref.in.yaml +++ b/internal/gatewayapi/testdata/httproute-with-non-existent-authenfilter-ref.in.yaml @@ -39,5 +39,5 @@ httpRoutes: extensionRef: group: gateway.envoyproxy.io kind: AuthenticationFilter - name: test + name: non-exist diff --git a/internal/gatewayapi/testdata/httproute-with-non-existent-authenfilter-ref.out.yaml b/internal/gatewayapi/testdata/httproute-with-non-existent-authenfilter-ref.out.yaml index 5be2dec7216..54f60545af3 100644 --- a/internal/gatewayapi/testdata/httproute-with-non-existent-authenfilter-ref.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-non-existent-authenfilter-ref.out.yaml @@ -51,7 +51,7 @@ httpRoutes: extensionRef: group: gateway.envoyproxy.io kind: AuthenticationFilter - name: test + name: non-exist status: parents: - parentRef: @@ -60,10 +60,14 @@ httpRoutes: sectionName: http controllerName: gateway.envoyproxy.io/gatewayclass-controller conditions: + - type: Accepted + status: "False" + reason: UnsupportedValue + message: "Reference default/non-exist not found for filter type: ExtensionRef" - type: ResolvedRefs status: "False" reason: BackendNotFound - message: "Reference not found for filter type: ExtensionRef" + message: "Reference default/non-exist not found for filter type: ExtensionRef" xdsIR: envoy-gateway-gateway-1: http: @@ -82,7 +86,7 @@ xdsIR: # I believe the correct way to handle an invalid filter should be to allow the HTTPRoute to function # normally but leave out the filter config and set the status, but this behaviour can be changed. directResponse: - body: "Reference not found for filter type: ExtensionRef" + body: "Reference default/non-exist not found for filter type: ExtensionRef" statusCode: 500 infraIR: envoy-gateway-gateway-1: diff --git a/internal/gatewayapi/testdata/httproute-with-non-matching-authenfilter-ref.in.yaml b/internal/gatewayapi/testdata/httproute-with-non-matching-authenfilter-ref.in.yaml index b3311f2e83e..a571b30739c 100644 --- a/internal/gatewayapi/testdata/httproute-with-non-matching-authenfilter-ref.in.yaml +++ b/internal/gatewayapi/testdata/httproute-with-non-matching-authenfilter-ref.in.yaml @@ -39,7 +39,7 @@ httpRoutes: extensionRef: group: gateway.envoyproxy.io kind: AuthenticationFilter - name: not-exist + name: test authenticationFilters: - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: AuthenticationFilter diff --git a/internal/gatewayapi/testdata/httproute-with-non-matching-authenfilter-ref.out.yaml b/internal/gatewayapi/testdata/httproute-with-non-matching-authenfilter-ref.out.yaml index b81f118caa1..363a3e3ed8e 100644 --- a/internal/gatewayapi/testdata/httproute-with-non-matching-authenfilter-ref.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-non-matching-authenfilter-ref.out.yaml @@ -51,7 +51,7 @@ httpRoutes: extensionRef: group: gateway.envoyproxy.io kind: AuthenticationFilter - name: not-exist + name: test status: parents: - parentRef: @@ -60,10 +60,14 @@ httpRoutes: sectionName: http controllerName: gateway.envoyproxy.io/gatewayclass-controller conditions: + - type: Accepted + status: "False" + reason: UnsupportedValue + message: "Reference default/test not found for filter type: ExtensionRef" - type: ResolvedRefs status: "False" reason: BackendNotFound - message: "Reference default/not-exist not found for filter type: ExtensionRef" + message: "Reference default/test not found for filter type: ExtensionRef" xdsIR: envoy-gateway-gateway-1: http: @@ -82,7 +86,7 @@ xdsIR: # I believe the correct way to handle an invalid filter should be to allow the HTTPRoute to function # normally but leave out the filter config and set the status, but this behaviour can be changed. directResponse: - body: "Reference default/not-exist not found for filter type: ExtensionRef" + body: "Reference default/test not found for filter type: ExtensionRef" statusCode: 500 infraIR: envoy-gateway-gateway-1: diff --git a/internal/gatewayapi/testdata/httproute-with-valid-ratelimitfilter.in.yaml b/internal/gatewayapi/testdata/httproute-with-valid-ratelimitfilter.in.yaml new file mode 100644 index 00000000000..6aa58ec5414 --- /dev/null +++ b/internal/gatewayapi/testdata/httproute-with-valid-ratelimitfilter.in.yaml @@ -0,0 +1,59 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 + filters: + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: test +rateLimitFilters: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: RateLimitFilter + metadata: + name: test + namespace: default + spec: + type: Global + global: + rules: + - clientSelectors: + - headers: + - name: x-user-id + value: one + limit: + requests: 10 + unit: Hour diff --git a/internal/gatewayapi/testdata/httproute-with-valid-ratelimitfilter.out.yaml b/internal/gatewayapi/testdata/httproute-with-valid-ratelimitfilter.out.yaml new file mode 100644 index 00000000000..f5d34768c1f --- /dev/null +++ b/internal/gatewayapi/testdata/httproute-with-valid-ratelimitfilter.out.yaml @@ -0,0 +1,110 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All + status: + listeners: + - name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + attachedRoutes: 1 + conditions: + - type: Programmed + status: "True" + reason: Programmed + message: Listener is ready +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 + filters: + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: test + status: + parents: + - parentRef: + namespace: envoy-gateway + name: gateway-1 + sectionName: http + controllerName: gateway.envoyproxy.io/gatewayclass-controller + conditions: + - type: Accepted + status: "True" + reason: Accepted + message: Route is accepted +xdsIR: + envoy-gateway-gateway-1: + http: + - name: envoy-gateway-gateway-1-http + address: 0.0.0.0 + port: 10080 + hostnames: + - "*.envoyproxy.io" + routes: + - name: default-httproute-1-rule-0-match-0-gateway.envoyproxy.io + pathMatch: + prefix: "/" + headerMatches: + - name: ":authority" + exact: gateway.envoyproxy.io + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 10 + unit: Hour + destinations: + - host: 7.7.7.7 + port: 8080 + weight: 1 +infraIR: + envoy-gateway-gateway-1: + proxy: + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + name: envoy-gateway-gateway-1 + image: envoyproxy/envoy:translator-tests + listeners: + - address: "" + ports: + - name: http + protocol: "HTTP" + containerPort: 10080 + servicePort: 80 diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 02eae4689c7..adc30efae81 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -684,20 +684,13 @@ type RateLimitRule struct { Limit *RateLimitValue } -type RateLimitUnit string - -const ( - Second RateLimitUnit = "second" - Minute RateLimitUnit = "minute" - Hour RateLimitUnit = "hour" - Day RateLimitUnit = "day" -) +type RateLimitUnit egv1a1.RateLimitUnit // RateLimitValue holds the // +k8s:deepcopy-gen=true type RateLimitValue struct { // Requests are the number of requests that need to be rate limited. - Requests uint32 + Requests uint // Unit of rate limiting. Unit RateLimitUnit } diff --git a/internal/xds/translator/ratelimit.go b/internal/xds/translator/ratelimit.go index ea3956d5da1..dd00c200e81 100644 --- a/internal/xds/translator/ratelimit.go +++ b/internal/xds/translator/ratelimit.go @@ -200,7 +200,7 @@ func buildRateLimitServiceDescriptors(descriptorPrefix string, global *ir.Global yamlDesc.Key = getRateLimitDescriptorKey(descriptorPrefix, rIdx, -1) yamlDesc.Value = getRateLimitDescriptorValue(descriptorPrefix, rIdx, -1) rateLimit := ratelimitserviceconfig.YamlRateLimit{ - RequestsPerUnit: rule.Limit.Requests, + RequestsPerUnit: uint32(rule.Limit.Requests), Unit: string(rule.Limit.Unit), } yamlDesc.RateLimit = &rateLimit @@ -225,7 +225,7 @@ func buildRateLimitServiceDescriptors(descriptorPrefix string, global *ir.Global // Add the ratelimit values to the last descriptor if mIdx == len(rule.HeaderMatches)-1 { rateLimit := ratelimitserviceconfig.YamlRateLimit{ - RequestsPerUnit: rule.Limit.Requests, + RequestsPerUnit: uint32(rule.Limit.Requests), Unit: string(rule.Limit.Unit), } yamlDesc.RateLimit = &rateLimit