From 7d1cf0741eded1e6b26ef270581eb69d2c593918 Mon Sep 17 00:00:00 2001 From: whalecold Date: Wed, 13 Mar 2024 15:15:10 +0800 Subject: [PATCH] compatible udpa struct limit --- core/xdsresource/lds.go | 24 ++++++++++++++--- core/xdsresource/lds_test.go | 46 +++++++++++++++++++++++++++++++-- core/xdsresource/xdsresource.go | 2 ++ go.mod | 1 + go.sum | 1 + 5 files changed, 69 insertions(+), 5 deletions(-) diff --git a/core/xdsresource/lds.go b/core/xdsresource/lds.go index 360dfc7..7d4892e 100644 --- a/core/xdsresource/lds.go +++ b/core/xdsresource/lds.go @@ -19,6 +19,7 @@ package xdsresource import ( "fmt" + udpatypev1 "github.com/cncf/udpa/go/udpa/type/v1" v3listenerpb "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" ratelimitv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/local_ratelimit/v3" @@ -246,17 +247,34 @@ func getLocalRateLimitFromHttpConnectionManager(hcm *v3httppb.HttpConnectionMana if filter.GetTypedConfig() == nil { continue } - if filter.GetTypedConfig().TypeUrl == "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit" || - filter.Name == "envoy.filters.http.local_ratelimit" { + typedConfig := filter.GetTypedConfig().GetValue() + switch filter.GetTypedConfig().TypeUrl { + case RateLimitTypeURL: lrl := &ratelimitv3.LocalRateLimit{} - if err := proto.Unmarshal(filter.GetTypedConfig().GetValue(), lrl); err != nil { + if err := proto.Unmarshal(typedConfig, lrl); err != nil { return 0, fmt.Errorf("unmarshal LocalRateLimit failed: %s", err) } if lrl.TokenBucket != nil { return lrl.TokenBucket.MaxTokens, nil } + case TypedStructTypeURL: + // ratelimit may be configed with udpa struct. + ts := &udpatypev1.TypedStruct{} + if err := proto.Unmarshal(typedConfig, ts); err != nil { + return 0, fmt.Errorf("unmarshal TypedStruct failed: %s", err) + } + tokenBucket, ok := ts.GetValue().GetFields()["token_bucket"] + if !ok { + continue + } + maxTokens, ok := tokenBucket.GetStructValue().GetFields()["max_tokens"] + if !ok { + continue + } + return uint32(maxTokens.GetNumberValue()), nil } } + return 0, nil } return 0, nil } diff --git a/core/xdsresource/lds_test.go b/core/xdsresource/lds_test.go index 3ab489b..3331c94 100644 --- a/core/xdsresource/lds_test.go +++ b/core/xdsresource/lds_test.go @@ -20,13 +20,15 @@ import ( "reflect" "testing" + udpatypev1 "github.com/cncf/udpa/go/udpa/type/v1" v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" ratelimitv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/local_ratelimit/v3" v3httppb "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" - "github.com/stretchr/testify/assert" - "github.com/golang/protobuf/ptypes/any" + _struct "github.com/golang/protobuf/ptypes/struct" + "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/structpb" ) func TestUnmarshalLDSError(t *testing.T) { @@ -162,4 +164,44 @@ func TestGetLocalRateLimitFromHttpConnectionManager(t *testing.T) { token, err := getLocalRateLimitFromHttpConnectionManager(hcm) assert.Equal(t, err, nil) assert.Equal(t, token, uint32(10)) + + // ---------------------------------- struct ratelimit ------------------------------------ + structLimit := &udpatypev1.TypedStruct{ + TypeUrl: RateLimitTypeURL, + Value: &_struct.Struct{ + Fields: map[string]*structpb.Value{ + "token_bucket": { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "max_tokens": { + Kind: &structpb.Value_NumberValue{ + NumberValue: 100, + }, + }, + }, + }, + }, + }, + }, + }, + } + + hcm1 := &v3httppb.HttpConnectionManager{ + RouteSpecifier: &v3httppb.HttpConnectionManager_RouteConfig{ + RouteConfig: &v3routepb.RouteConfiguration{ + Name: "InboundPassthroughClusterIpv4", + }, + }, + HttpFilters: []*v3httppb.HttpFilter{ + { + ConfigType: &v3httppb.HttpFilter_TypedConfig{ + TypedConfig: MarshalAny(structLimit), + }, + }, + }, + } + token, err = getLocalRateLimitFromHttpConnectionManager(hcm1) + assert.Equal(t, err, nil) + assert.Equal(t, token, uint32(100)) } diff --git a/core/xdsresource/xdsresource.go b/core/xdsresource/xdsresource.go index 783e2c0..fd54328 100644 --- a/core/xdsresource/xdsresource.go +++ b/core/xdsresource/xdsresource.go @@ -69,6 +69,8 @@ const ( RuntimeTypeURL = apiTypePrefix + "envoy.service.runtime.v3.Runtime" HTTPConnManagerTypeURL = apiTypePrefix + "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager" ThriftProxyTypeURL = apiTypePrefix + "envoy.extensions.filters.network.thrift_proxy.v3.ThriftProxy" + RateLimitTypeURL = apiTypePrefix + "envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit" + TypedStructTypeURL = apiTypePrefix + "udpa.type.v1.TypedStruct" NameTableTypeURL = apiTypePrefix + "istio.networking.nds.v1.NameTable" // AnyType is used only by ADS diff --git a/go.mod b/go.mod index c83f790..1053286 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/bytedance/gopkg v0.0.0-20230728082804-614d0af6619b github.com/cenkalti/backoff/v4 v4.1.0 github.com/cloudwego/kitex v0.7.3 + github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe github.com/envoyproxy/go-control-plane v0.11.1 github.com/golang/protobuf v1.5.3 github.com/stretchr/testify v1.8.3 diff --git a/go.sum b/go.sum index b7a038b..93956e8 100644 --- a/go.sum +++ b/go.sum @@ -686,6 +686,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=