mirror of
https://github.com/alibaba/higress.git
synced 2026-03-18 17:27:28 +08:00
Compare commits
19 Commits
plugins/wa
...
v1.3.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9c7df78a9 | ||
|
|
1e018770e5 | ||
|
|
53ff28c58b | ||
|
|
66f2d8980d | ||
|
|
b1e4cf9492 | ||
|
|
c250e850d5 | ||
|
|
1f7e98cef5 | ||
|
|
4273bf573a | ||
|
|
13f36856cc | ||
|
|
e84f9980a1 | ||
|
|
a2fecd59a1 | ||
|
|
89c72777e1 | ||
|
|
85df257f4e | ||
|
|
659a982496 | ||
|
|
0ae376b320 | ||
|
|
c647ab3a08 | ||
|
|
688247f4f9 | ||
|
|
10f5267b3f | ||
|
|
cec99686a0 |
4
.github/workflows/latest-release.yaml
vendored
4
.github/workflows/latest-release.yaml
vendored
@@ -18,6 +18,8 @@ jobs:
|
|||||||
tar -zcvf hgctl_latest_linux_arm64.tar.gz out/linux_arm64/
|
tar -zcvf hgctl_latest_linux_arm64.tar.gz out/linux_arm64/
|
||||||
tar -zcvf hgctl_latest_darwin_amd64.tar.gz out/darwin_amd64/
|
tar -zcvf hgctl_latest_darwin_amd64.tar.gz out/darwin_amd64/
|
||||||
tar -zcvf hgctl_latest_darwin_arm64.tar.gz out/darwin_arm64/
|
tar -zcvf hgctl_latest_darwin_arm64.tar.gz out/darwin_arm64/
|
||||||
|
zip -q -r hgctl_latest_windows_amd64.zip out/windows_amd64/
|
||||||
|
zip -q -r hgctl_latest_windows_arm64.zip out/windows_arm64/
|
||||||
|
|
||||||
# Ignore the error when we delete the latest release, it might not exist.
|
# Ignore the error when we delete the latest release, it might not exist.
|
||||||
|
|
||||||
@@ -54,6 +56,8 @@ jobs:
|
|||||||
hgctl_latest_linux_arm64.tar.gz
|
hgctl_latest_linux_arm64.tar.gz
|
||||||
hgctl_latest_darwin_amd64.tar.gz
|
hgctl_latest_darwin_amd64.tar.gz
|
||||||
hgctl_latest_darwin_arm64.tar.gz
|
hgctl_latest_darwin_arm64.tar.gz
|
||||||
|
hgctl_latest_windows_amd64.zip
|
||||||
|
hgctl_latest_windows_arm64.zip
|
||||||
body: |
|
body: |
|
||||||
This is the "latest" release of **Higress**, which contains the most recent commits from the main branch.
|
This is the "latest" release of **Higress**, which contains the most recent commits from the main branch.
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ header:
|
|||||||
- 'VERSION'
|
- 'VERSION'
|
||||||
- 'tools/'
|
- 'tools/'
|
||||||
- 'test/README.md'
|
- 'test/README.md'
|
||||||
- 'pkg/cmd/hgctl/testdata/config'
|
- 'cmd/hgctl/config/testdata/config'
|
||||||
- 'pkg/cmd/hgctl/manifests'
|
- 'pkg/cmd/hgctl/manifests'
|
||||||
|
|
||||||
comment: on-failure
|
comment: on-failure
|
||||||
|
|||||||
14
CODEOWNERS
14
CODEOWNERS
@@ -1,10 +1,10 @@
|
|||||||
/api @johnlanni
|
/api @johnlanni @CH3CHO
|
||||||
/envoy @gengleilei @johnlanni @Lynskylate
|
/envoy @gengleilei @johnlanni
|
||||||
/istio @SpecialYang @johnlanni
|
/istio @SpecialYang @johnlanni
|
||||||
/pkg @SpecialYang @johnlanni @Charlie17Li @Xunzhuo
|
/pkg @SpecialYang @johnlanni @CH3CHO @Xunzhuo
|
||||||
/plugins @johnlanni
|
/plugins @johnlanni @WeixinX
|
||||||
/registry @NameHaibinZhang @johnlanni
|
/registry @NameHaibinZhang @2456868764 @johnlanni
|
||||||
/test @Xunzhuo
|
/test @Xunzhuo @2456868764 @CH3CHO
|
||||||
/tools @johnlanni @Xunzhuo
|
/tools @johnlanni @Xunzhuo @2456868764
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ build-hgctl-multiarch: prebuild $(OUT)
|
|||||||
GOPROXY=$(GOPROXY) GOOS=linux GOARCH=arm64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/linux_arm64/ $(HGCTL_BINARIES)
|
GOPROXY=$(GOPROXY) GOOS=linux GOARCH=arm64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/linux_arm64/ $(HGCTL_BINARIES)
|
||||||
GOPROXY=$(GOPROXY) GOOS=darwin GOARCH=amd64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/darwin_amd64/ $(HGCTL_BINARIES)
|
GOPROXY=$(GOPROXY) GOOS=darwin GOARCH=amd64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/darwin_amd64/ $(HGCTL_BINARIES)
|
||||||
GOPROXY=$(GOPROXY) GOOS=darwin GOARCH=arm64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/darwin_arm64/ $(HGCTL_BINARIES)
|
GOPROXY=$(GOPROXY) GOOS=darwin GOARCH=arm64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/darwin_arm64/ $(HGCTL_BINARIES)
|
||||||
|
GOPROXY=$(GOPROXY) GOOS=windows GOARCH=amd64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/windows_amd64/ $(HGCTL_BINARIES)
|
||||||
|
GOPROXY=$(GOPROXY) GOOS=windows GOARCH=arm64 LDFLAGS=$(RELEASE_LDFLAGS) tools/hack/gobuild.sh ./out/windows_arm64/ $(HGCTL_BINARIES)
|
||||||
# Create targets for OUT_LINUX/binary
|
# Create targets for OUT_LINUX/binary
|
||||||
# There are two use cases here:
|
# There are two use cases here:
|
||||||
# * Building all docker images (generally in CI). In this case we want to build everything at once, so they share work
|
# * Building all docker images (generally in CI). In this case we want to build everything at once, so they share work
|
||||||
@@ -137,11 +138,11 @@ export ENVOY_TAR_PATH:=/home/package/envoy.tar.gz
|
|||||||
|
|
||||||
external/package/envoy-amd64.tar.gz:
|
external/package/envoy-amd64.tar.gz:
|
||||||
# cd external/proxy; BUILD_WITH_CONTAINER=1 make test_release
|
# cd external/proxy; BUILD_WITH_CONTAINER=1 make test_release
|
||||||
cd external/package; wget "https://github.com/alibaba/higress/releases/download/v1.3.0/envoy-amd64.tar.gz"
|
cd external/package; wget "https://github.com/alibaba/higress/releases/download/v1.3.2/envoy-amd64.tar.gz"
|
||||||
|
|
||||||
external/package/envoy-arm64.tar.gz:
|
external/package/envoy-arm64.tar.gz:
|
||||||
# cd external/proxy; BUILD_WITH_CONTAINER=1 make test_release
|
# cd external/proxy; BUILD_WITH_CONTAINER=1 make test_release
|
||||||
cd external/package; wget "https://github.com/alibaba/higress/releases/download/v1.3.0/envoy-arm64.tar.gz"
|
cd external/package; wget "https://github.com/alibaba/higress/releases/download/v1.3.2/envoy-arm64.tar.gz"
|
||||||
|
|
||||||
build-pilot:
|
build-pilot:
|
||||||
cd external/istio; rm -rf out/linux_amd64; GOOS_LOCAL=linux TARGET_OS=linux TARGET_ARCH=amd64 BUILD_WITH_CONTAINER=1 make build-linux
|
cd external/istio; rm -rf out/linux_amd64; GOOS_LOCAL=linux TARGET_OS=linux TARGET_ARCH=amd64 BUILD_WITH_CONTAINER=1 make build-linux
|
||||||
@@ -176,8 +177,8 @@ install: pre-install
|
|||||||
cd helm/higress; helm dependency build
|
cd helm/higress; helm dependency build
|
||||||
helm install higress helm/higress -n higress-system --create-namespace --set 'global.local=true'
|
helm install higress helm/higress -n higress-system --create-namespace --set 'global.local=true'
|
||||||
|
|
||||||
ENVOY_LATEST_IMAGE_TAG ?= sha-34054f8
|
ENVOY_LATEST_IMAGE_TAG ?= sha-53ff28c
|
||||||
ISTIO_LATEST_IMAGE_TAG ?= sha-34054f8
|
ISTIO_LATEST_IMAGE_TAG ?= sha-53ff28c
|
||||||
|
|
||||||
install-dev: pre-install
|
install-dev: pre-install
|
||||||
helm install higress helm/core -n higress-system --create-namespace --set 'controller.tag=$(TAG)' --set 'gateway.replicas=1' --set 'pilot.tag=$(ISTIO_LATEST_IMAGE_TAG)' --set 'gateway.tag=$(ENVOY_LATEST_IMAGE_TAG)' --set 'global.local=true'
|
helm install higress helm/core -n higress-system --create-namespace --set 'controller.tag=$(TAG)' --set 'gateway.replicas=1' --set 'pilot.tag=$(ISTIO_LATEST_IMAGE_TAG)' --set 'gateway.tag=$(ENVOY_LATEST_IMAGE_TAG)' --set 'global.local=true'
|
||||||
|
|||||||
@@ -154,6 +154,11 @@ spec:
|
|||||||
type: array
|
type: array
|
||||||
httpPath:
|
httpPath:
|
||||||
type: string
|
type: string
|
||||||
|
paramFromEntireBody:
|
||||||
|
properties:
|
||||||
|
paramType:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
params:
|
params:
|
||||||
items:
|
items:
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@@ -200,14 +200,15 @@ func (m *DubboService) GetMethods() []*Method {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Method struct {
|
type Method struct {
|
||||||
ServiceMethod string `protobuf:"bytes,1,opt,name=service_method,json=serviceMethod,proto3" json:"service_method,omitempty"`
|
ServiceMethod string `protobuf:"bytes,1,opt,name=service_method,json=serviceMethod,proto3" json:"service_method,omitempty"`
|
||||||
HeadersAttach string `protobuf:"bytes,2,opt,name=headers_attach,json=headersAttach,proto3" json:"headers_attach,omitempty"`
|
HeadersAttach string `protobuf:"bytes,2,opt,name=headers_attach,json=headersAttach,proto3" json:"headers_attach,omitempty"`
|
||||||
HttpPath string `protobuf:"bytes,3,opt,name=http_path,json=httpPath,proto3" json:"http_path,omitempty"`
|
HttpPath string `protobuf:"bytes,3,opt,name=http_path,json=httpPath,proto3" json:"http_path,omitempty"`
|
||||||
HttpMethods []string `protobuf:"bytes,4,rep,name=http_methods,json=httpMethods,proto3" json:"http_methods,omitempty"`
|
HttpMethods []string `protobuf:"bytes,4,rep,name=http_methods,json=httpMethods,proto3" json:"http_methods,omitempty"`
|
||||||
Params []*Param `protobuf:"bytes,5,rep,name=params,proto3" json:"params,omitempty"`
|
Params []*Param `protobuf:"bytes,5,rep,name=params,proto3" json:"params,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
ParamFromEntireBody *ParamFromEntireBody `protobuf:"bytes,6,opt,name=paramFromEntireBody,proto3" json:"paramFromEntireBody,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Method) Reset() { *m = Method{} }
|
func (m *Method) Reset() { *m = Method{} }
|
||||||
@@ -278,6 +279,13 @@ func (m *Method) GetParams() []*Param {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Method) GetParamFromEntireBody() *ParamFromEntireBody {
|
||||||
|
if m != nil {
|
||||||
|
return m.ParamFromEntireBody
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type Param struct {
|
type Param struct {
|
||||||
ParamSource string `protobuf:"bytes,1,opt,name=param_source,json=paramSource,proto3" json:"param_source,omitempty"`
|
ParamSource string `protobuf:"bytes,1,opt,name=param_source,json=paramSource,proto3" json:"param_source,omitempty"`
|
||||||
ParamKey string `protobuf:"bytes,2,opt,name=param_key,json=paramKey,proto3" json:"param_key,omitempty"`
|
ParamKey string `protobuf:"bytes,2,opt,name=param_key,json=paramKey,proto3" json:"param_key,omitempty"`
|
||||||
@@ -341,6 +349,53 @@ func (m *Param) GetParamType() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ParamFromEntireBody struct {
|
||||||
|
ParamType string `protobuf:"bytes,1,opt,name=param_type,json=paramType,proto3" json:"param_type,omitempty"`
|
||||||
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ParamFromEntireBody) Reset() { *m = ParamFromEntireBody{} }
|
||||||
|
func (m *ParamFromEntireBody) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*ParamFromEntireBody) ProtoMessage() {}
|
||||||
|
func (*ParamFromEntireBody) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_dc706c3b890c1c84, []int{4}
|
||||||
|
}
|
||||||
|
func (m *ParamFromEntireBody) XXX_Unmarshal(b []byte) error {
|
||||||
|
return m.Unmarshal(b)
|
||||||
|
}
|
||||||
|
func (m *ParamFromEntireBody) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
if deterministic {
|
||||||
|
return xxx_messageInfo_ParamFromEntireBody.Marshal(b, m, deterministic)
|
||||||
|
} else {
|
||||||
|
b = b[:cap(b)]
|
||||||
|
n, err := m.MarshalToSizedBuffer(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return b[:n], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (m *ParamFromEntireBody) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_ParamFromEntireBody.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *ParamFromEntireBody) XXX_Size() int {
|
||||||
|
return m.Size()
|
||||||
|
}
|
||||||
|
func (m *ParamFromEntireBody) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_ParamFromEntireBody.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_ParamFromEntireBody proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *ParamFromEntireBody) GetParamType() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.ParamType
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type GrpcService struct {
|
type GrpcService struct {
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
@@ -351,7 +406,7 @@ func (m *GrpcService) Reset() { *m = GrpcService{} }
|
|||||||
func (m *GrpcService) String() string { return proto.CompactTextString(m) }
|
func (m *GrpcService) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GrpcService) ProtoMessage() {}
|
func (*GrpcService) ProtoMessage() {}
|
||||||
func (*GrpcService) Descriptor() ([]byte, []int) {
|
func (*GrpcService) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_dc706c3b890c1c84, []int{4}
|
return fileDescriptor_dc706c3b890c1c84, []int{5}
|
||||||
}
|
}
|
||||||
func (m *GrpcService) XXX_Unmarshal(b []byte) error {
|
func (m *GrpcService) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
@@ -385,42 +440,46 @@ func init() {
|
|||||||
proto.RegisterType((*DubboService)(nil), "higress.networking.v1.DubboService")
|
proto.RegisterType((*DubboService)(nil), "higress.networking.v1.DubboService")
|
||||||
proto.RegisterType((*Method)(nil), "higress.networking.v1.Method")
|
proto.RegisterType((*Method)(nil), "higress.networking.v1.Method")
|
||||||
proto.RegisterType((*Param)(nil), "higress.networking.v1.Param")
|
proto.RegisterType((*Param)(nil), "higress.networking.v1.Param")
|
||||||
|
proto.RegisterType((*ParamFromEntireBody)(nil), "higress.networking.v1.ParamFromEntireBody")
|
||||||
proto.RegisterType((*GrpcService)(nil), "higress.networking.v1.GrpcService")
|
proto.RegisterType((*GrpcService)(nil), "higress.networking.v1.GrpcService")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { proto.RegisterFile("networking/v1/http_2_rpc.proto", fileDescriptor_dc706c3b890c1c84) }
|
func init() { proto.RegisterFile("networking/v1/http_2_rpc.proto", fileDescriptor_dc706c3b890c1c84) }
|
||||||
|
|
||||||
var fileDescriptor_dc706c3b890c1c84 = []byte{
|
var fileDescriptor_dc706c3b890c1c84 = []byte{
|
||||||
// 463 bytes of a gzipped FileDescriptorProto
|
// 506 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x53, 0xcf, 0x8a, 0xd3, 0x40,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x93, 0xdf, 0x6e, 0xd3, 0x30,
|
||||||
0x18, 0x77, 0xba, 0x6d, 0xb7, 0xfb, 0x65, 0xeb, 0x61, 0x40, 0x08, 0x8b, 0xc6, 0x35, 0x7b, 0x70,
|
0x14, 0xc6, 0x71, 0xd7, 0x76, 0xdd, 0xc9, 0xca, 0x85, 0x27, 0xa4, 0x68, 0x82, 0x32, 0xb2, 0x0b,
|
||||||
0x41, 0x49, 0xd8, 0xea, 0x41, 0x14, 0x0f, 0x5b, 0x04, 0x17, 0x44, 0x58, 0xb2, 0x9e, 0xbc, 0x84,
|
0x26, 0x40, 0x89, 0x56, 0xb8, 0x40, 0x43, 0x5c, 0xac, 0xe2, 0xcf, 0x24, 0x84, 0x34, 0x65, 0x5c,
|
||||||
0x49, 0x32, 0x66, 0x86, 0x6d, 0x33, 0xc3, 0xcc, 0x34, 0xda, 0xb7, 0xf0, 0x35, 0x7c, 0x13, 0x8f,
|
0x71, 0x13, 0x39, 0x89, 0x49, 0xac, 0xb5, 0xb1, 0x65, 0xbb, 0x85, 0xbc, 0x05, 0xaf, 0xc1, 0x9b,
|
||||||
0x3e, 0x82, 0x14, 0x1f, 0x44, 0x32, 0x93, 0x6e, 0x13, 0xb1, 0xb7, 0xf0, 0xfb, 0x33, 0xdf, 0xef,
|
0xec, 0x92, 0x47, 0x40, 0x7d, 0x12, 0x14, 0x3b, 0x5d, 0x93, 0xa9, 0xdd, 0x5d, 0x74, 0xbe, 0xef,
|
||||||
0xc7, 0xf7, 0x05, 0x82, 0x8a, 0x9a, 0xaf, 0x42, 0xdd, 0xf2, 0xaa, 0x8c, 0xeb, 0x8b, 0x98, 0x19,
|
0x77, 0x7c, 0x3e, 0x9f, 0x18, 0x46, 0x05, 0xd5, 0x3f, 0xb9, 0xbc, 0x66, 0x45, 0x16, 0x2c, 0x4e,
|
||||||
0x23, 0xd3, 0x59, 0xaa, 0x64, 0x1e, 0x49, 0x25, 0x8c, 0xc0, 0x0f, 0x18, 0x2f, 0x15, 0xd5, 0x3a,
|
0x83, 0x5c, 0x6b, 0x11, 0x8d, 0x23, 0x29, 0x12, 0x5f, 0x48, 0xae, 0x39, 0x7e, 0x94, 0xb3, 0x4c,
|
||||||
0xda, 0xe9, 0xa2, 0xfa, 0xe2, 0xe4, 0x71, 0x29, 0x44, 0xb9, 0xa0, 0x31, 0x91, 0x3c, 0xfe, 0xc2,
|
0x52, 0xa5, 0xfc, 0xb5, 0xcf, 0x5f, 0x9c, 0x1e, 0x3e, 0xcd, 0x38, 0xcf, 0xa6, 0x34, 0x20, 0x82,
|
||||||
0xe9, 0xa2, 0x48, 0x33, 0xca, 0x48, 0xcd, 0x85, 0x72, 0xbe, 0xf0, 0x3b, 0x82, 0xc9, 0x95, 0x31,
|
0x05, 0x3f, 0x18, 0x9d, 0xa6, 0x51, 0x4c, 0x73, 0xb2, 0x60, 0x5c, 0x5a, 0xce, 0xfb, 0x8d, 0x60,
|
||||||
0x72, 0x96, 0xc8, 0x1c, 0xbf, 0x81, 0x51, 0xb1, 0xca, 0x32, 0xe1, 0xa3, 0x53, 0x74, 0xee, 0xcd,
|
0x70, 0xa1, 0xb5, 0x18, 0x87, 0x22, 0xc1, 0xef, 0xa0, 0x97, 0xce, 0xe3, 0x98, 0xbb, 0xe8, 0x08,
|
||||||
0xce, 0xa2, 0xff, 0x3e, 0x1a, 0xbd, 0x6b, 0x34, 0x37, 0x54, 0xd5, 0x3c, 0xa7, 0x57, 0xf7, 0x12,
|
0x9d, 0x38, 0xe3, 0x63, 0x7f, 0x63, 0x53, 0xff, 0x43, 0xe5, 0xb9, 0xa2, 0x72, 0xc1, 0x12, 0x7a,
|
||||||
0xe7, 0xc1, 0xaf, 0x60, 0x58, 0x2a, 0x99, 0xfb, 0x03, 0xeb, 0x0d, 0xf7, 0x78, 0xdf, 0x2b, 0x99,
|
0xf1, 0x20, 0xb4, 0x0c, 0x7e, 0x0b, 0xdd, 0x4c, 0x8a, 0xc4, 0xed, 0x18, 0xd6, 0xdb, 0xc2, 0x7e,
|
||||||
0xef, 0xac, 0xd6, 0x31, 0x9f, 0x82, 0x57, 0x50, 0x6d, 0x78, 0x45, 0x0c, 0x17, 0x55, 0xf8, 0x03,
|
0x96, 0x22, 0x59, 0xa3, 0x86, 0x98, 0x0c, 0xc1, 0x49, 0xa9, 0xd2, 0xac, 0x20, 0x9a, 0xf1, 0xc2,
|
||||||
0xc1, 0x71, 0x77, 0x04, 0x0e, 0xe0, 0x50, 0xbb, 0x4f, 0x1b, 0xec, 0x68, 0x3e, 0xdc, 0x5c, 0xa2,
|
0xfb, 0x83, 0x60, 0xbf, 0x79, 0x04, 0x1e, 0xc1, 0xae, 0xb2, 0x9f, 0x66, 0xb0, 0xbd, 0x49, 0x77,
|
||||||
0x41, 0xb2, 0x05, 0x1b, 0xbe, 0xa6, 0x4a, 0x73, 0x51, 0xd9, 0xe1, 0x77, 0x7c, 0x0b, 0xe2, 0x13,
|
0x79, 0x8e, 0x3a, 0xe1, 0xaa, 0x58, 0xe9, 0x0b, 0x2a, 0x15, 0xe3, 0x85, 0x39, 0xfc, 0x56, 0xaf,
|
||||||
0x18, 0x95, 0x4a, 0xac, 0xa4, 0x7f, 0x70, 0xc7, 0xa2, 0xc4, 0x41, 0xf8, 0x2d, 0x1c, 0x2e, 0xa9,
|
0x8b, 0xf8, 0x10, 0x7a, 0x99, 0xe4, 0x73, 0xe1, 0xee, 0xdc, 0xaa, 0x28, 0xb4, 0x25, 0xfc, 0x1e,
|
||||||
0x61, 0xa2, 0xd0, 0xfe, 0xf0, 0xf4, 0xe0, 0xdc, 0x9b, 0x3d, 0xda, 0x13, 0xfc, 0xa3, 0x55, 0x6d,
|
0x76, 0x67, 0x54, 0xe7, 0x3c, 0x55, 0x6e, 0xf7, 0x68, 0xe7, 0xc4, 0x19, 0x3f, 0xd9, 0x32, 0xf8,
|
||||||
0x9f, 0x6e, 0x3d, 0xe1, 0x1f, 0x04, 0x63, 0xc7, 0xe0, 0x67, 0x70, 0xbf, 0x0d, 0x94, 0x3a, 0xb6,
|
0x57, 0xe3, 0x5a, 0xb5, 0xae, 0x19, 0xef, 0xa6, 0x03, 0x7d, 0xab, 0xe0, 0x97, 0xf0, 0xb0, 0x1e,
|
||||||
0x17, 0x76, 0xda, 0x72, 0x3b, 0x31, 0xa3, 0xa4, 0xa0, 0x4a, 0xa7, 0xc4, 0x18, 0x92, 0xb3, 0x4e,
|
0x28, 0xb2, 0x6a, 0x6b, 0xd8, 0x61, 0xad, 0xad, 0xcd, 0x39, 0x25, 0x29, 0x95, 0x2a, 0x22, 0x5a,
|
||||||
0x72, 0x94, 0x4c, 0x5b, 0xee, 0xd2, 0x52, 0xf8, 0x09, 0x1c, 0xd9, 0x7d, 0x4b, 0x62, 0x58, 0xa7,
|
0x93, 0x24, 0x6f, 0x4c, 0x8e, 0xc2, 0x61, 0xad, 0x9d, 0x1b, 0x09, 0x3f, 0x83, 0x3d, 0xb3, 0x6f,
|
||||||
0xc3, 0x20, 0x99, 0x34, 0xf0, 0x35, 0x31, 0x0c, 0x3f, 0x85, 0x63, 0x2b, 0xe9, 0x76, 0xd9, 0xaa,
|
0x41, 0x74, 0xde, 0xc8, 0xd0, 0x09, 0x07, 0x55, 0xf9, 0x92, 0xe8, 0x1c, 0x3f, 0x87, 0x7d, 0x63,
|
||||||
0xbc, 0x86, 0x71, 0x73, 0x35, 0x7e, 0x09, 0x63, 0x49, 0x14, 0x59, 0x6a, 0x7f, 0x64, 0xeb, 0x3e,
|
0x69, 0x66, 0x59, 0xb9, 0x9c, 0x4a, 0xb1, 0xe7, 0x2a, 0xfc, 0x06, 0xfa, 0x82, 0x48, 0x32, 0x53,
|
||||||
0xdc, 0x53, 0xf7, 0xba, 0x11, 0x25, 0xad, 0x36, 0xfc, 0x06, 0x23, 0x0b, 0x34, 0x73, 0x2c, 0x94,
|
0x6e, 0xcf, 0xc4, 0x7d, 0xbc, 0x25, 0xee, 0x65, 0x65, 0x0a, 0x6b, 0x2f, 0x8e, 0xe1, 0xc0, 0x7c,
|
||||||
0x6a, 0xb1, 0x52, 0xff, 0xec, 0xc3, 0xb3, 0xcc, 0x8d, 0x25, 0x9a, 0xcc, 0x4e, 0x78, 0x4b, 0xd7,
|
0x7d, 0x92, 0x7c, 0xf6, 0xb1, 0xd0, 0x4c, 0xd2, 0x09, 0x4f, 0x4b, 0xb7, 0x6f, 0x56, 0xfd, 0xe2,
|
||||||
0xbd, 0xad, 0x4c, 0x2c, 0xfc, 0x81, 0xae, 0xf1, 0x19, 0x80, 0x93, 0x98, 0xb5, 0xa4, 0xbd, 0x5e,
|
0xbe, 0x16, 0x6d, 0xa2, 0xce, 0xb7, 0xa9, 0x99, 0xf7, 0x0b, 0x7a, 0x86, 0xa8, 0xb2, 0x18, 0x3d,
|
||||||
0xce, 0xfa, 0x69, 0x2d, 0x69, 0x38, 0x05, 0xaf, 0x73, 0x32, 0xf3, 0xd7, 0x3f, 0x37, 0x01, 0xfa,
|
0x52, 0x7c, 0x2e, 0xef, 0xec, 0xdc, 0x31, 0xca, 0x95, 0x11, 0xaa, 0x7b, 0xb1, 0xc6, 0x6b, 0x5a,
|
||||||
0xb5, 0x09, 0xd0, 0xef, 0x4d, 0x80, 0x3e, 0x3f, 0x2f, 0xb9, 0x61, 0xab, 0x2c, 0xca, 0xc5, 0x32,
|
0xb6, 0x36, 0x3f, 0x30, 0xe5, 0x2f, 0xb4, 0xc4, 0xc7, 0x00, 0xd6, 0xa2, 0x4b, 0x41, 0x5b, 0x77,
|
||||||
0x26, 0x0b, 0x9e, 0x91, 0x8c, 0xc4, 0x6d, 0x1d, 0x7b, 0xf1, 0xbd, 0x7f, 0x26, 0x1b, 0xdb, 0x8b,
|
0x67, 0xd1, 0x6f, 0xa5, 0xa0, 0xde, 0x19, 0x1c, 0x6c, 0x98, 0xf5, 0x0e, 0x8b, 0x36, 0xb3, 0x43,
|
||||||
0x7f, 0xf1, 0x37, 0x00, 0x00, 0xff, 0xff, 0x75, 0x5c, 0x9e, 0x28, 0x4b, 0x03, 0x00, 0x00,
|
0x70, 0x1a, 0xbf, 0xf4, 0xe4, 0xec, 0x66, 0x39, 0x42, 0x7f, 0x97, 0x23, 0xf4, 0x6f, 0x39, 0x42,
|
||||||
|
0xdf, 0x5f, 0x65, 0x4c, 0xe7, 0xf3, 0xd8, 0x4f, 0xf8, 0x2c, 0x20, 0x53, 0x16, 0x93, 0x98, 0x04,
|
||||||
|
0xf5, 0x5d, 0x99, 0x17, 0xd9, 0x7a, 0xd3, 0x71, 0xdf, 0xbc, 0xc8, 0xd7, 0xff, 0x03, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0x30, 0xef, 0x3d, 0xa9, 0xeb, 0x03, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Http2Rpc) Marshal() (dAtA []byte, err error) {
|
func (m *Http2Rpc) Marshal() (dAtA []byte, err error) {
|
||||||
@@ -587,6 +646,18 @@ func (m *Method) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||||||
i -= len(m.XXX_unrecognized)
|
i -= len(m.XXX_unrecognized)
|
||||||
copy(dAtA[i:], m.XXX_unrecognized)
|
copy(dAtA[i:], m.XXX_unrecognized)
|
||||||
}
|
}
|
||||||
|
if m.ParamFromEntireBody != nil {
|
||||||
|
{
|
||||||
|
size, err := m.ParamFromEntireBody.MarshalToSizedBuffer(dAtA[:i])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
i -= size
|
||||||
|
i = encodeVarintHttp_2Rpc(dAtA, i, uint64(size))
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x32
|
||||||
|
}
|
||||||
if len(m.Params) > 0 {
|
if len(m.Params) > 0 {
|
||||||
for iNdEx := len(m.Params) - 1; iNdEx >= 0; iNdEx-- {
|
for iNdEx := len(m.Params) - 1; iNdEx >= 0; iNdEx-- {
|
||||||
{
|
{
|
||||||
@@ -682,6 +753,40 @@ func (m *Param) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||||||
return len(dAtA) - i, nil
|
return len(dAtA) - i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ParamFromEntireBody) Marshal() (dAtA []byte, err error) {
|
||||||
|
size := m.Size()
|
||||||
|
dAtA = make([]byte, size)
|
||||||
|
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dAtA[:n], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ParamFromEntireBody) MarshalTo(dAtA []byte) (int, error) {
|
||||||
|
size := m.Size()
|
||||||
|
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ParamFromEntireBody) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
|
i := len(dAtA)
|
||||||
|
_ = i
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
if m.XXX_unrecognized != nil {
|
||||||
|
i -= len(m.XXX_unrecognized)
|
||||||
|
copy(dAtA[i:], m.XXX_unrecognized)
|
||||||
|
}
|
||||||
|
if len(m.ParamType) > 0 {
|
||||||
|
i -= len(m.ParamType)
|
||||||
|
copy(dAtA[i:], m.ParamType)
|
||||||
|
i = encodeVarintHttp_2Rpc(dAtA, i, uint64(len(m.ParamType)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0xa
|
||||||
|
}
|
||||||
|
return len(dAtA) - i, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *GrpcService) Marshal() (dAtA []byte, err error) {
|
func (m *GrpcService) Marshal() (dAtA []byte, err error) {
|
||||||
size := m.Size()
|
size := m.Size()
|
||||||
dAtA = make([]byte, size)
|
dAtA = make([]byte, size)
|
||||||
@@ -819,6 +924,10 @@ func (m *Method) Size() (n int) {
|
|||||||
n += 1 + l + sovHttp_2Rpc(uint64(l))
|
n += 1 + l + sovHttp_2Rpc(uint64(l))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if m.ParamFromEntireBody != nil {
|
||||||
|
l = m.ParamFromEntireBody.Size()
|
||||||
|
n += 1 + l + sovHttp_2Rpc(uint64(l))
|
||||||
|
}
|
||||||
if m.XXX_unrecognized != nil {
|
if m.XXX_unrecognized != nil {
|
||||||
n += len(m.XXX_unrecognized)
|
n += len(m.XXX_unrecognized)
|
||||||
}
|
}
|
||||||
@@ -849,6 +958,22 @@ func (m *Param) Size() (n int) {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ParamFromEntireBody) Size() (n int) {
|
||||||
|
if m == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
l = len(m.ParamType)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovHttp_2Rpc(uint64(l))
|
||||||
|
}
|
||||||
|
if m.XXX_unrecognized != nil {
|
||||||
|
n += len(m.XXX_unrecognized)
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
func (m *GrpcService) Size() (n int) {
|
func (m *GrpcService) Size() (n int) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return 0
|
return 0
|
||||||
@@ -1360,6 +1485,42 @@ func (m *Method) Unmarshal(dAtA []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 6:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field ParamFromEntireBody", wireType)
|
||||||
|
}
|
||||||
|
var msglen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowHttp_2Rpc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
msglen |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msglen < 0 {
|
||||||
|
return ErrInvalidLengthHttp_2Rpc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + msglen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthHttp_2Rpc
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
if m.ParamFromEntireBody == nil {
|
||||||
|
m.ParamFromEntireBody = &ParamFromEntireBody{}
|
||||||
|
}
|
||||||
|
if err := m.ParamFromEntireBody.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipHttp_2Rpc(dAtA[iNdEx:])
|
skippy, err := skipHttp_2Rpc(dAtA[iNdEx:])
|
||||||
@@ -1529,6 +1690,89 @@ func (m *Param) Unmarshal(dAtA []byte) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (m *ParamFromEntireBody) Unmarshal(dAtA []byte) error {
|
||||||
|
l := len(dAtA)
|
||||||
|
iNdEx := 0
|
||||||
|
for iNdEx < l {
|
||||||
|
preIndex := iNdEx
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowHttp_2Rpc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
wire |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldNum := int32(wire >> 3)
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
if wireType == 4 {
|
||||||
|
return fmt.Errorf("proto: ParamFromEntireBody: wiretype end group for non-group")
|
||||||
|
}
|
||||||
|
if fieldNum <= 0 {
|
||||||
|
return fmt.Errorf("proto: ParamFromEntireBody: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
|
}
|
||||||
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field ParamType", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowHttp_2Rpc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthHttp_2Rpc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthHttp_2Rpc
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.ParamType = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
default:
|
||||||
|
iNdEx = preIndex
|
||||||
|
skippy, err := skipHttp_2Rpc(dAtA[iNdEx:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||||
|
return ErrInvalidLengthHttp_2Rpc
|
||||||
|
}
|
||||||
|
if (iNdEx + skippy) > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
|
||||||
|
iNdEx += skippy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if iNdEx > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (m *GrpcService) Unmarshal(dAtA []byte) error {
|
func (m *GrpcService) Unmarshal(dAtA []byte) error {
|
||||||
l := len(dAtA)
|
l := len(dAtA)
|
||||||
iNdEx := 0
|
iNdEx := 0
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ message Method {
|
|||||||
string http_path = 3 [(google.api.field_behavior) = REQUIRED];
|
string http_path = 3 [(google.api.field_behavior) = REQUIRED];
|
||||||
repeated string http_methods = 4 [(google.api.field_behavior) = REQUIRED];
|
repeated string http_methods = 4 [(google.api.field_behavior) = REQUIRED];
|
||||||
repeated Param params = 5;
|
repeated Param params = 5;
|
||||||
|
ParamFromEntireBody paramFromEntireBody = 6 [(google.api.field_behavior) = OPTIONAL];
|
||||||
}
|
}
|
||||||
|
|
||||||
message Param {
|
message Param {
|
||||||
@@ -70,5 +71,9 @@ message Param {
|
|||||||
string param_type = 3 [(google.api.field_behavior) = REQUIRED];
|
string param_type = 3 [(google.api.field_behavior) = REQUIRED];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ParamFromEntireBody {
|
||||||
|
string param_type = 1 [(google.api.field_behavior) = REQUIRED];
|
||||||
|
}
|
||||||
|
|
||||||
message GrpcService {
|
message GrpcService {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,6 +99,27 @@ func (in *Param) DeepCopyInterface() interface{} {
|
|||||||
return in.DeepCopy()
|
return in.DeepCopy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto supports using ParamFromEntireBody within kubernetes types, where deepcopy-gen is used.
|
||||||
|
func (in *ParamFromEntireBody) DeepCopyInto(out *ParamFromEntireBody) {
|
||||||
|
p := proto.Clone(in).(*ParamFromEntireBody)
|
||||||
|
*out = *p
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParamFromEntireBody. Required by controller-gen.
|
||||||
|
func (in *ParamFromEntireBody) DeepCopy() *ParamFromEntireBody {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ParamFromEntireBody)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ParamFromEntireBody. Required by controller-gen.
|
||||||
|
func (in *ParamFromEntireBody) DeepCopyInterface() interface{} {
|
||||||
|
return in.DeepCopy()
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto supports using GrpcService within kubernetes types, where deepcopy-gen is used.
|
// DeepCopyInto supports using GrpcService within kubernetes types, where deepcopy-gen is used.
|
||||||
func (in *GrpcService) DeepCopyInto(out *GrpcService) {
|
func (in *GrpcService) DeepCopyInto(out *GrpcService) {
|
||||||
p := proto.Clone(in).(*GrpcService)
|
p := proto.Clone(in).(*GrpcService)
|
||||||
|
|||||||
@@ -61,6 +61,17 @@ func (this *Param) UnmarshalJSON(b []byte) error {
|
|||||||
return Http_2RpcUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
return Http_2RpcUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON is a custom marshaler for ParamFromEntireBody
|
||||||
|
func (this *ParamFromEntireBody) MarshalJSON() ([]byte, error) {
|
||||||
|
str, err := Http_2RpcMarshaler.MarshalToString(this)
|
||||||
|
return []byte(str), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON is a custom unmarshaler for ParamFromEntireBody
|
||||||
|
func (this *ParamFromEntireBody) UnmarshalJSON(b []byte) error {
|
||||||
|
return Http_2RpcUnmarshaler.Unmarshal(bytes.NewReader(b), this)
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON is a custom marshaler for GrpcService
|
// MarshalJSON is a custom marshaler for GrpcService
|
||||||
func (this *GrpcService) MarshalJSON() ([]byte, error) {
|
func (this *GrpcService) MarshalJSON() ([]byte, error) {
|
||||||
str, err := Http_2RpcMarshaler.MarshalToString(this)
|
str, err := Http_2RpcMarshaler.MarshalToString(this)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package hgctl
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -27,26 +27,61 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
output string
|
BootstrapEnvoyConfigType EnvoyConfigType = "bootstrap"
|
||||||
podName string
|
ClusterEnvoyConfigType EnvoyConfigType = "cluster"
|
||||||
podNamespace string
|
EndpointEnvoyConfigType EnvoyConfigType = "endpoint"
|
||||||
|
ListenerEnvoyConfigType EnvoyConfigType = "listener"
|
||||||
|
RouteEnvoyConfigType EnvoyConfigType = "route"
|
||||||
|
AllEnvoyConfigType EnvoyConfigType = "all"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultProxyAdminPort = 15000
|
defaultProxyAdminPort = 15000
|
||||||
containerName = "envoy"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func retrieveConfigDump(args []string, includeEds bool) ([]byte, error) {
|
type EnvoyConfigType string
|
||||||
if len(args) != 0 {
|
|
||||||
podName = args[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
type GetEnvoyConfigOptions struct {
|
||||||
|
IncludeEds bool
|
||||||
|
PodName string
|
||||||
|
PodNamespace string
|
||||||
|
BindAddress string
|
||||||
|
Output string
|
||||||
|
EnvoyConfigType EnvoyConfigType
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultGetEnvoyConfigOptions() *GetEnvoyConfigOptions {
|
||||||
|
return &GetEnvoyConfigOptions{
|
||||||
|
IncludeEds: true,
|
||||||
|
PodName: "",
|
||||||
|
PodNamespace: "higress-system",
|
||||||
|
BindAddress: "localhost",
|
||||||
|
Output: "json",
|
||||||
|
EnvoyConfigType: AllEnvoyConfigType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEnvoyConfig(config *GetEnvoyConfigOptions) ([]byte, error) {
|
||||||
|
configDump, err := retrieveConfigDump(config.PodName, config.PodNamespace, config.BindAddress, config.IncludeEds)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if config.EnvoyConfigType == AllEnvoyConfigType {
|
||||||
|
return configDump, nil
|
||||||
|
}
|
||||||
|
resource, err := getXDSResource(config.EnvoyConfigType, configDump)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return formatGatewayConfig(resource, config.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func retrieveConfigDump(podName, podNamespace, bindAddress string, includeEds bool) ([]byte, error) {
|
||||||
if podNamespace == "" {
|
if podNamespace == "" {
|
||||||
return nil, fmt.Errorf("pod namespace is required")
|
return nil, fmt.Errorf("pod namespace is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if podName == "" || len(args) == 0 {
|
if podName == "" {
|
||||||
c, err := kubernetes.NewCLIClient(options.DefaultConfigFlags.ToRawKubeConfigLoader())
|
c, err := kubernetes.NewCLIClient(options.DefaultConfigFlags.ToRawKubeConfigLoader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to build kubernetes client: %w", err)
|
return nil, fmt.Errorf("failed to build kubernetes client: %w", err)
|
||||||
@@ -65,7 +100,7 @@ func retrieveConfigDump(args []string, includeEds bool) ([]byte, error) {
|
|||||||
fw, err := portForwarder(types.NamespacedName{
|
fw, err := portForwarder(types.NamespacedName{
|
||||||
Namespace: podNamespace,
|
Namespace: podNamespace,
|
||||||
Name: podName,
|
Name: podName,
|
||||||
})
|
}, bindAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -82,7 +117,7 @@ func retrieveConfigDump(args []string, includeEds bool) ([]byte, error) {
|
|||||||
return configDump, nil
|
return configDump, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func portForwarder(nn types.NamespacedName) (kubernetes.PortForwarder, error) {
|
func portForwarder(nn types.NamespacedName, bindAddress string) (kubernetes.PortForwarder, error) {
|
||||||
c, err := kubernetes.NewCLIClient(options.DefaultConfigFlags.ToRawKubeConfigLoader())
|
c, err := kubernetes.NewCLIClient(options.DefaultConfigFlags.ToRawKubeConfigLoader())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("build CLI client fail: %w", err)
|
return nil, fmt.Errorf("build CLI client fail: %w", err)
|
||||||
@@ -149,3 +184,53 @@ func configDumpRequest(address string, includeEds bool) ([]byte, error) {
|
|||||||
|
|
||||||
return io.ReadAll(resp.Body)
|
return io.ReadAll(resp.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getXDSResource(resourceType EnvoyConfigType, configDump []byte) (any, error) {
|
||||||
|
cd := map[string]any{}
|
||||||
|
if err := json.Unmarshal(configDump, &cd); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resourceType == AllEnvoyConfigType {
|
||||||
|
return cd, nil
|
||||||
|
}
|
||||||
|
configs := cd["configs"]
|
||||||
|
globalConfigs := configs.([]any)
|
||||||
|
|
||||||
|
switch resourceType {
|
||||||
|
case BootstrapEnvoyConfigType:
|
||||||
|
for _, config := range globalConfigs {
|
||||||
|
if config.(map[string]interface{})["@type"] == "type.googleapis.com/envoy.admin.v3.BootstrapConfigDump" {
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case EndpointEnvoyConfigType:
|
||||||
|
for _, config := range globalConfigs {
|
||||||
|
if config.(map[string]interface{})["@type"] == "type.googleapis.com/envoy.admin.v3.EndpointsConfigDump" {
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case ClusterEnvoyConfigType:
|
||||||
|
for _, config := range globalConfigs {
|
||||||
|
if config.(map[string]interface{})["@type"] == "type.googleapis.com/envoy.admin.v3.ClustersConfigDump" {
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ListenerEnvoyConfigType:
|
||||||
|
for _, config := range globalConfigs {
|
||||||
|
if config.(map[string]interface{})["@type"] == "type.googleapis.com/envoy.admin.v3.ListenersConfigDump" {
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case RouteEnvoyConfigType:
|
||||||
|
for _, config := range globalConfigs {
|
||||||
|
if config.(map[string]interface{})["@type"] == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump" {
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown resourceType %s", resourceType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("unknown resourceType %s", resourceType)
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package hgctl
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -109,7 +109,7 @@ func TestExtractAllConfigDump(t *testing.T) {
|
|||||||
t.Run(tc.output, func(t *testing.T) {
|
t.Run(tc.output, func(t *testing.T) {
|
||||||
configDump, err := fetchGatewayConfig(fw, true)
|
configDump, err := fetchGatewayConfig(fw, true)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
data, err := GetXDSResource(AllEnvoyConfigType, configDump)
|
data, err := getXDSResource(AllEnvoyConfigType, configDump)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
got, err := formatGatewayConfig(data, tc.output)
|
got, err := formatGatewayConfig(data, tc.output)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -137,7 +137,7 @@ func TestExtractSubResourcesConfigDump(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
output string
|
output string
|
||||||
expected string
|
expected string
|
||||||
resourceType envoyConfigType
|
resourceType EnvoyConfigType
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
output: "json",
|
output: "json",
|
||||||
@@ -192,7 +192,7 @@ func TestExtractSubResourcesConfigDump(t *testing.T) {
|
|||||||
t.Run(tc.output, func(t *testing.T) {
|
t.Run(tc.output, func(t *testing.T) {
|
||||||
configDump, err := fetchGatewayConfig(fw, false)
|
configDump, err := fetchGatewayConfig(fw, false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
resource, err := GetXDSResource(tc.resourceType, configDump)
|
resource, err := getXDSResource(tc.resourceType, configDump)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
got, err := formatGatewayConfig(resource, tc.output)
|
got, err := formatGatewayConfig(resource, tc.output)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
483
envoy/1.20/patches/envoy/20240104-enhance-srds.patch
Normal file
483
envoy/1.20/patches/envoy/20240104-enhance-srds.patch
Normal file
@@ -0,0 +1,483 @@
|
|||||||
|
diff -Naur envoy/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto envoy-new/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto
|
||||||
|
--- envoy/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto 2024-01-04 21:07:40.000000000 +0800
|
||||||
|
+++ envoy-new/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto 2024-01-04 21:09:13.000000000 +0800
|
||||||
|
@@ -888,11 +888,31 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ message HostValueExtractor {
|
||||||
|
+ option (udpa.annotations.versioning).previous_message_type =
|
||||||
|
+ "envoy.config.filter.network.http_connection_manager.v2.ScopedRoutes.ScopeKeyBuilder."
|
||||||
|
+ "FragmentBuilder.HostValueExtractor";
|
||||||
|
+
|
||||||
|
+ // The maximum number of host superset recomputes. If not specified, defaults to 100.
|
||||||
|
+ google.protobuf.UInt32Value max_recompute_num = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ message LocalPortValueExtractor {
|
||||||
|
+ option (udpa.annotations.versioning).previous_message_type =
|
||||||
|
+ "envoy.config.filter.network.http_connection_manager.v2.ScopedRoutes.ScopeKeyBuilder."
|
||||||
|
+ "FragmentBuilder.LocalPortValueExtractor";
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
oneof type {
|
||||||
|
option (validate.required) = true;
|
||||||
|
|
||||||
|
// Specifies how a header field's value should be extracted.
|
||||||
|
HeaderValueExtractor header_value_extractor = 1;
|
||||||
|
+
|
||||||
|
+ HostValueExtractor host_value_extractor = 101;
|
||||||
|
+
|
||||||
|
+ LocalPortValueExtractor local_port_value_extractor = 102;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -Naur envoy/envoy/router/scopes.h envoy-new/envoy/router/scopes.h
|
||||||
|
--- envoy/envoy/router/scopes.h 2024-01-04 21:07:38.000000000 +0800
|
||||||
|
+++ envoy-new/envoy/router/scopes.h 2024-01-04 21:09:13.000000000 +0800
|
||||||
|
@@ -92,7 +92,12 @@
|
||||||
|
* @param headers the request headers to match the scoped routing configuration against.
|
||||||
|
* @return ConfigConstSharedPtr the router's Config matching the request headers.
|
||||||
|
*/
|
||||||
|
+#if defined ALIMESH
|
||||||
|
+ virtual ConfigConstSharedPtr getRouteConfig(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info) const PURE;
|
||||||
|
+#else
|
||||||
|
virtual ConfigConstSharedPtr getRouteConfig(const Http::HeaderMap& headers) const PURE;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Based on the incoming HTTP request headers, returns the hash value of its scope key.
|
||||||
|
@@ -100,6 +105,12 @@
|
||||||
|
* @return unique_ptr of the scope key computed from header.
|
||||||
|
*/
|
||||||
|
virtual ScopeKeyPtr computeScopeKey(const Http::HeaderMap&) const { return {}; }
|
||||||
|
+
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ virtual ScopeKeyPtr computeScopeKey(const Http::HeaderMap&, const StreamInfo::StreamInfo&) const {
|
||||||
|
+ return {};
|
||||||
|
+ };
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
using ScopedConfigConstSharedPtr = std::shared_ptr<const ScopedConfig>;
|
||||||
|
diff -Naur envoy/source/common/http/conn_manager_impl.cc envoy-new/source/common/http/conn_manager_impl.cc
|
||||||
|
--- envoy/source/common/http/conn_manager_impl.cc 2024-01-04 21:07:41.000000000 +0800
|
||||||
|
+++ envoy-new/source/common/http/conn_manager_impl.cc 2024-01-04 21:09:13.000000000 +0800
|
||||||
|
@@ -577,8 +577,13 @@
|
||||||
|
requestVhdsUpdate(host_header, thread_local_dispatcher, std::move(route_config_updated_cb));
|
||||||
|
return;
|
||||||
|
} else if (parent_.snapped_scoped_routes_config_ != nullptr) {
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ Router::ScopeKeyPtr scope_key = parent_.snapped_scoped_routes_config_->computeScopeKey(
|
||||||
|
+ *parent_.request_headers_, parent_.connection()->streamInfo());
|
||||||
|
+#else
|
||||||
|
Router::ScopeKeyPtr scope_key =
|
||||||
|
parent_.snapped_scoped_routes_config_->computeScopeKey(*parent_.request_headers_);
|
||||||
|
+#endif
|
||||||
|
// If scope_key is not null, the scope exists but RouteConfiguration is not initialized.
|
||||||
|
if (scope_key != nullptr) {
|
||||||
|
requestSrdsUpdate(std::move(scope_key), thread_local_dispatcher,
|
||||||
|
@@ -1197,7 +1202,13 @@
|
||||||
|
void ConnectionManagerImpl::ActiveStream::snapScopedRouteConfig() {
|
||||||
|
// NOTE: if a RDS subscription hasn't got a RouteConfiguration back, a Router::NullConfigImpl is
|
||||||
|
// returned, in that case we let it pass.
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ snapped_route_config_ =
|
||||||
|
+ snapped_scoped_routes_config_->getRouteConfig(*request_headers_, connection()->streamInfo());
|
||||||
|
+#else
|
||||||
|
snapped_route_config_ = snapped_scoped_routes_config_->getRouteConfig(*request_headers_);
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
if (snapped_route_config_ == nullptr) {
|
||||||
|
ENVOY_STREAM_LOG(trace, "can't find SRDS scope.", *this);
|
||||||
|
// TODO(stevenzzzz): Consider to pass an error message to router filter, so that it can
|
||||||
|
diff -Naur envoy/source/common/router/scoped_config_impl.cc envoy-new/source/common/router/scoped_config_impl.cc
|
||||||
|
--- envoy/source/common/router/scoped_config_impl.cc 2024-01-04 21:07:36.000000000 +0800
|
||||||
|
+++ envoy-new/source/common/router/scoped_config_impl.cc 2024-01-04 21:09:13.000000000 +0800
|
||||||
|
@@ -6,6 +6,160 @@
|
||||||
|
namespace Envoy {
|
||||||
|
namespace Router {
|
||||||
|
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+namespace {
|
||||||
|
+
|
||||||
|
+std::string maskFirstDNSLabel(absl::string_view host) {
|
||||||
|
+ if (host == "*") {
|
||||||
|
+ return std::string(host);
|
||||||
|
+ }
|
||||||
|
+ if (host.size() < 2) {
|
||||||
|
+ return "*";
|
||||||
|
+ }
|
||||||
|
+ size_t start_pos = (host[0] == '*' && host[1] == '.') ? 2 : 0;
|
||||||
|
+ size_t dot_pos = host.find('.', start_pos);
|
||||||
|
+ if (dot_pos != absl::string_view::npos) {
|
||||||
|
+ return absl::StrCat("*", absl::string_view(host.data() + dot_pos, host.size() - dot_pos));
|
||||||
|
+ }
|
||||||
|
+ return "*";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+} // namespace
|
||||||
|
+
|
||||||
|
+LocalPortValueExtractorImpl::LocalPortValueExtractorImpl(
|
||||||
|
+ ScopedRoutes::ScopeKeyBuilder::FragmentBuilder&& config)
|
||||||
|
+ : FragmentBuilderBase(std::move(config)) {
|
||||||
|
+ ASSERT(config_.type_case() ==
|
||||||
|
+ ScopedRoutes::ScopeKeyBuilder::FragmentBuilder::kLocalPortValueExtractor,
|
||||||
|
+ "local_port_value_extractor is not set.");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+std::unique_ptr<ScopeKeyFragmentBase> LocalPortValueExtractorImpl::computeFragment(
|
||||||
|
+ const Http::HeaderMap&, const StreamInfo::StreamInfo& info, ReComputeCbPtr&) const {
|
||||||
|
+ auto port = info.downstreamAddressProvider().localAddress()->ip()->port();
|
||||||
|
+ return std::make_unique<StringKeyFragment>(std::to_string(long(port)));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+HostValueExtractorImpl::HostValueExtractorImpl(
|
||||||
|
+ ScopedRoutes::ScopeKeyBuilder::FragmentBuilder&& config)
|
||||||
|
+ : FragmentBuilderBase(std::move(config)),
|
||||||
|
+ host_value_extractor_config_(config_.host_value_extractor()),
|
||||||
|
+ max_recompute_num_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(
|
||||||
|
+ host_value_extractor_config_, max_recompute_num, DefaultMaxRecomputeNum)) {
|
||||||
|
+ ASSERT(config_.type_case() == ScopedRoutes::ScopeKeyBuilder::FragmentBuilder::kHostValueExtractor,
|
||||||
|
+ "host_value_extractor is not set.");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+std::unique_ptr<ScopeKeyFragmentBase>
|
||||||
|
+HostValueExtractorImpl::reComputeHelper(const std::string& host, ReComputeCbPtr& next_recompute,
|
||||||
|
+ uint32_t recompute_seq) const {
|
||||||
|
+ if (recompute_seq == max_recompute_num_) {
|
||||||
|
+ ENVOY_LOG_MISC(warn,
|
||||||
|
+ "recompute host fragment failed, maximum number of recalculations exceeded");
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ if (host == "*") {
|
||||||
|
+ *next_recompute = nullptr;
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ auto masked_host = maskFirstDNSLabel(host);
|
||||||
|
+ *next_recompute = [this, masked_host, recompute_seq,
|
||||||
|
+ next_recompute]() mutable -> std::unique_ptr<ScopeKeyFragmentBase> {
|
||||||
|
+ return reComputeHelper(masked_host, next_recompute, recompute_seq + 1);
|
||||||
|
+ };
|
||||||
|
+ return std::make_unique<StringKeyFragment>(masked_host);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+std::unique_ptr<ScopeKeyFragmentBase>
|
||||||
|
+HostValueExtractorImpl::computeFragment(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo&,
|
||||||
|
+ ReComputeCbPtr& recompute) const {
|
||||||
|
+ auto fragment = computeFragment(headers);
|
||||||
|
+ auto host = static_cast<const Http::RequestHeaderMap&>(headers).getHostValue();
|
||||||
|
+ *recompute = [this, host, recompute]() mutable -> std::unique_ptr<ScopeKeyFragmentBase> {
|
||||||
|
+ return reComputeHelper(std::string(host), recompute, 0);
|
||||||
|
+ };
|
||||||
|
+ return fragment;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+std::unique_ptr<ScopeKeyFragmentBase>
|
||||||
|
+HostValueExtractorImpl::computeFragment(const Http::HeaderMap& headers) const {
|
||||||
|
+ return std::make_unique<StringKeyFragment>(
|
||||||
|
+ static_cast<const Http::RequestHeaderMap&>(headers).getHostValue());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+std::unique_ptr<ScopeKeyFragmentBase>
|
||||||
|
+HeaderValueExtractorImpl::computeFragment(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo&, ReComputeCbPtr&) const {
|
||||||
|
+ return computeFragment(headers);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+ScopeKeyPtr ScopeKeyBuilderImpl::computeScopeKey(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info,
|
||||||
|
+ std::function<ScopeKeyPtr()>& recompute) const {
|
||||||
|
+ ScopeKey key;
|
||||||
|
+ bool recomputeable = false;
|
||||||
|
+ auto recompute_cbs = std::make_shared<std::vector<ReComputeCbPtr>>();
|
||||||
|
+ for (const auto& builder : fragment_builders_) {
|
||||||
|
+ // returns nullopt if a null fragment is found.
|
||||||
|
+ ReComputeCbPtr recompute_fragment_cb = std::make_shared<ReComputeCb>();
|
||||||
|
+ std::unique_ptr<ScopeKeyFragmentBase> fragment =
|
||||||
|
+ builder->computeFragment(headers, info, recompute_fragment_cb);
|
||||||
|
+ if (fragment == nullptr) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ if (*recompute_fragment_cb == nullptr) {
|
||||||
|
+ auto key_fragment = static_cast<StringKeyFragment*>(fragment.get());
|
||||||
|
+ auto copied_fragment = std::make_shared<StringKeyFragment>(*key_fragment);
|
||||||
|
+ auto recompute_cb =
|
||||||
|
+ std::make_shared<ReComputeCb>([copied_fragment]() -> std::unique_ptr<StringKeyFragment> {
|
||||||
|
+ return std::make_unique<StringKeyFragment>(*copied_fragment);
|
||||||
|
+ });
|
||||||
|
+ recompute_cbs->push_back(recompute_cb);
|
||||||
|
+ } else {
|
||||||
|
+ recomputeable = true;
|
||||||
|
+ recompute_cbs->push_back(recompute_fragment_cb);
|
||||||
|
+ }
|
||||||
|
+ key.addFragment(std::move(fragment));
|
||||||
|
+ }
|
||||||
|
+ if (recomputeable) {
|
||||||
|
+ recompute = [&recompute, recompute_cbs]() mutable -> ScopeKeyPtr {
|
||||||
|
+ ScopeKey new_key;
|
||||||
|
+ for (auto& cb : *recompute_cbs) {
|
||||||
|
+ auto new_fragment = (*cb)();
|
||||||
|
+ if (new_fragment == nullptr) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ if (*cb == nullptr) {
|
||||||
|
+ recompute = nullptr;
|
||||||
|
+ }
|
||||||
|
+ new_key.addFragment(std::move(new_fragment));
|
||||||
|
+ }
|
||||||
|
+ return std::make_unique<ScopeKey>(std::move(new_key));
|
||||||
|
+ };
|
||||||
|
+ }
|
||||||
|
+ return std::make_unique<ScopeKey>(std::move(key));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+ScopeKeyPtr ScopedConfigImpl::computeScopeKey(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info) const {
|
||||||
|
+ std::function<Router::ScopeKeyPtr()> recompute;
|
||||||
|
+ ScopeKeyPtr scope_key = scope_key_builder_.computeScopeKey(headers, info, recompute);
|
||||||
|
+ if (scope_key == nullptr) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ decltype(scoped_route_info_by_key_.begin()) iter;
|
||||||
|
+ do {
|
||||||
|
+ iter = scoped_route_info_by_key_.find(scope_key->hash());
|
||||||
|
+ if (iter != scoped_route_info_by_key_.end()) {
|
||||||
|
+ return scope_key;
|
||||||
|
+ }
|
||||||
|
+ } while (recompute != nullptr && (scope_key = recompute()));
|
||||||
|
+ return nullptr;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
bool ScopeKey::operator!=(const ScopeKey& other) const { return !(*this == other); }
|
||||||
|
|
||||||
|
bool ScopeKey::operator==(const ScopeKey& other) const {
|
||||||
|
@@ -95,6 +249,16 @@
|
||||||
|
: ScopeKeyBuilderBase(std::move(config)) {
|
||||||
|
for (const auto& fragment_builder : config_.fragments()) {
|
||||||
|
switch (fragment_builder.type_case()) {
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ case ScopedRoutes::ScopeKeyBuilder::FragmentBuilder::kHostValueExtractor:
|
||||||
|
+ fragment_builders_.emplace_back(std::make_unique<HostValueExtractorImpl>(
|
||||||
|
+ ScopedRoutes::ScopeKeyBuilder::FragmentBuilder(fragment_builder)));
|
||||||
|
+ break;
|
||||||
|
+ case ScopedRoutes::ScopeKeyBuilder::FragmentBuilder::kLocalPortValueExtractor:
|
||||||
|
+ fragment_builders_.emplace_back(std::make_unique<LocalPortValueExtractorImpl>(
|
||||||
|
+ ScopedRoutes::ScopeKeyBuilder::FragmentBuilder(fragment_builder)));
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
case ScopedRoutes::ScopeKeyBuilder::FragmentBuilder::kHeaderValueExtractor:
|
||||||
|
fragment_builders_.emplace_back(std::make_unique<HeaderValueExtractorImpl>(
|
||||||
|
ScopedRoutes::ScopeKeyBuilder::FragmentBuilder(fragment_builder)));
|
||||||
|
@@ -143,6 +307,22 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
Router::ConfigConstSharedPtr
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ScopedConfigImpl::getRouteConfig(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info) const {
|
||||||
|
+ std::function<ScopeKeyPtr()> recompute;
|
||||||
|
+ ScopeKeyPtr scope_key = scope_key_builder_.computeScopeKey(headers, info, recompute);
|
||||||
|
+ if (scope_key == nullptr) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ decltype(scoped_route_info_by_key_.begin()) iter;
|
||||||
|
+ do {
|
||||||
|
+ iter = scoped_route_info_by_key_.find(scope_key->hash());
|
||||||
|
+ if (iter != scoped_route_info_by_key_.end()) {
|
||||||
|
+ return iter->second->routeConfig();
|
||||||
|
+ }
|
||||||
|
+ } while (recompute != nullptr && (scope_key = recompute()));
|
||||||
|
+#else
|
||||||
|
ScopedConfigImpl::getRouteConfig(const Http::HeaderMap& headers) const {
|
||||||
|
ScopeKeyPtr scope_key = scope_key_builder_.computeScopeKey(headers);
|
||||||
|
if (scope_key == nullptr) {
|
||||||
|
@@ -152,6 +332,7 @@
|
||||||
|
if (iter != scoped_route_info_by_key_.end()) {
|
||||||
|
return iter->second->routeConfig();
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -Naur envoy/source/common/router/scoped_config_impl.h envoy-new/source/common/router/scoped_config_impl.h
|
||||||
|
--- envoy/source/common/router/scoped_config_impl.h 2024-01-04 21:07:36.000000000 +0800
|
||||||
|
+++ envoy-new/source/common/router/scoped_config_impl.h 2024-01-04 21:09:13.000000000 +0800
|
||||||
|
@@ -22,6 +22,11 @@
|
||||||
|
|
||||||
|
using envoy::extensions::filters::network::http_connection_manager::v3::ScopedRoutes;
|
||||||
|
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+using ReComputeCb = std::function<std::unique_ptr<ScopeKeyFragmentBase>()>;
|
||||||
|
+using ReComputeCbPtr = std::shared_ptr<ReComputeCb>;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Base class for fragment builders.
|
||||||
|
*/
|
||||||
|
@@ -36,6 +41,12 @@
|
||||||
|
virtual std::unique_ptr<ScopeKeyFragmentBase>
|
||||||
|
computeFragment(const Http::HeaderMap& headers) const PURE;
|
||||||
|
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ virtual std::unique_ptr<ScopeKeyFragmentBase>
|
||||||
|
+ computeFragment(const Http::HeaderMap& headers, const StreamInfo::StreamInfo& info,
|
||||||
|
+ ReComputeCbPtr& recompute) const PURE;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
protected:
|
||||||
|
const ScopedRoutes::ScopeKeyBuilder::FragmentBuilder config_;
|
||||||
|
};
|
||||||
|
@@ -47,11 +58,54 @@
|
||||||
|
std::unique_ptr<ScopeKeyFragmentBase>
|
||||||
|
computeFragment(const Http::HeaderMap& headers) const override;
|
||||||
|
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ std::unique_ptr<ScopeKeyFragmentBase> computeFragment(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info,
|
||||||
|
+ ReComputeCbPtr& recompute) const override;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
private:
|
||||||
|
const ScopedRoutes::ScopeKeyBuilder::FragmentBuilder::HeaderValueExtractor&
|
||||||
|
header_value_extractor_config_;
|
||||||
|
};
|
||||||
|
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+class HostValueExtractorImpl : public FragmentBuilderBase {
|
||||||
|
+public:
|
||||||
|
+ explicit HostValueExtractorImpl(ScopedRoutes::ScopeKeyBuilder::FragmentBuilder&& config);
|
||||||
|
+
|
||||||
|
+ std::unique_ptr<ScopeKeyFragmentBase>
|
||||||
|
+ computeFragment(const Http::HeaderMap& headers) const override;
|
||||||
|
+
|
||||||
|
+ std::unique_ptr<ScopeKeyFragmentBase> computeFragment(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info,
|
||||||
|
+ ReComputeCbPtr& recompute) const override;
|
||||||
|
+
|
||||||
|
+private:
|
||||||
|
+ std::unique_ptr<ScopeKeyFragmentBase> reComputeHelper(const std::string& host,
|
||||||
|
+ ReComputeCbPtr& next_recompute,
|
||||||
|
+ uint32_t recompute_seq) const;
|
||||||
|
+
|
||||||
|
+ static constexpr uint32_t DefaultMaxRecomputeNum = 100;
|
||||||
|
+
|
||||||
|
+ const ScopedRoutes::ScopeKeyBuilder::FragmentBuilder::HostValueExtractor&
|
||||||
|
+ host_value_extractor_config_;
|
||||||
|
+ const uint32_t max_recompute_num_;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+class LocalPortValueExtractorImpl : public FragmentBuilderBase {
|
||||||
|
+public:
|
||||||
|
+ explicit LocalPortValueExtractorImpl(ScopedRoutes::ScopeKeyBuilder::FragmentBuilder&& config);
|
||||||
|
+
|
||||||
|
+ std::unique_ptr<ScopeKeyFragmentBase> computeFragment(const Http::HeaderMap&) const override {
|
||||||
|
+ return nullptr;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ std::unique_ptr<ScopeKeyFragmentBase> computeFragment(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info,
|
||||||
|
+ ReComputeCbPtr& recompute) const override;
|
||||||
|
+};
|
||||||
|
+#endif
|
||||||
|
/**
|
||||||
|
* Base class for ScopeKeyBuilder implementations.
|
||||||
|
*/
|
||||||
|
@@ -64,6 +118,12 @@
|
||||||
|
// Computes scope key for given headers, returns nullptr if a key can't be computed.
|
||||||
|
virtual ScopeKeyPtr computeScopeKey(const Http::HeaderMap& headers) const PURE;
|
||||||
|
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ virtual ScopeKeyPtr computeScopeKey(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info,
|
||||||
|
+ std::function<ScopeKeyPtr()>& recompute) const PURE;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
protected:
|
||||||
|
const ScopedRoutes::ScopeKeyBuilder config_;
|
||||||
|
};
|
||||||
|
@@ -74,6 +134,11 @@
|
||||||
|
|
||||||
|
ScopeKeyPtr computeScopeKey(const Http::HeaderMap& headers) const override;
|
||||||
|
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ ScopeKeyPtr computeScopeKey(const Http::HeaderMap& headers, const StreamInfo::StreamInfo& info,
|
||||||
|
+ std::function<ScopeKeyPtr()>& recompute) const override;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
private:
|
||||||
|
std::vector<std::unique_ptr<FragmentBuilderBase>> fragment_builders_;
|
||||||
|
};
|
||||||
|
@@ -118,10 +183,20 @@
|
||||||
|
void removeRoutingScopes(const std::vector<std::string>& scope_names);
|
||||||
|
|
||||||
|
// Envoy::Router::ScopedConfig
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ Router::ConfigConstSharedPtr getRouteConfig(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info) const override;
|
||||||
|
+#else
|
||||||
|
Router::ConfigConstSharedPtr getRouteConfig(const Http::HeaderMap& headers) const override;
|
||||||
|
+#endif
|
||||||
|
// The return value is not null only if the scope corresponding to the header exists.
|
||||||
|
ScopeKeyPtr computeScopeKey(const Http::HeaderMap& headers) const override;
|
||||||
|
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ ScopeKeyPtr computeScopeKey(const Http::HeaderMap& headers,
|
||||||
|
+ const StreamInfo::StreamInfo& info) const override;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
private:
|
||||||
|
ScopeKeyBuilderImpl scope_key_builder_;
|
||||||
|
// From scope name to cached ScopedRouteInfo.
|
||||||
|
@@ -135,9 +210,16 @@
|
||||||
|
*/
|
||||||
|
class NullScopedConfigImpl : public ScopedConfig {
|
||||||
|
public:
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+ Router::ConfigConstSharedPtr getRouteConfig(const Http::HeaderMap&,
|
||||||
|
+ const StreamInfo::StreamInfo&) const override {
|
||||||
|
+ return std::make_shared<const NullConfigImpl>();
|
||||||
|
+ }
|
||||||
|
+#else
|
||||||
|
Router::ConfigConstSharedPtr getRouteConfig(const Http::HeaderMap&) const override {
|
||||||
|
return std::make_shared<const NullConfigImpl>();
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Router
|
||||||
|
diff -Naur envoy/source/extensions/filters/http/on_demand/on_demand_update.cc envoy-new/source/extensions/filters/http/on_demand/on_demand_update.cc
|
||||||
|
--- envoy/source/extensions/filters/http/on_demand/on_demand_update.cc 2024-01-04 21:07:33.000000000 +0800
|
||||||
|
+++ envoy-new/source/extensions/filters/http/on_demand/on_demand_update.cc 2024-01-04 21:09:13.000000000 +0800
|
||||||
|
@@ -50,7 +50,11 @@
|
||||||
|
// This is the callback which is called when an update requested in requestRouteConfigUpdate()
|
||||||
|
// has been propagated to workers, at which point the request processing is restarted from the
|
||||||
|
// beginning.
|
||||||
|
+#if defined(ALIMESH)
|
||||||
|
+void OnDemandRouteUpdate::onRouteConfigUpdateCompletion(bool) {
|
||||||
|
+#else
|
||||||
|
void OnDemandRouteUpdate::onRouteConfigUpdateCompletion(bool route_exists) {
|
||||||
|
+#endif
|
||||||
|
filter_iteration_state_ = Http::FilterHeadersStatus::Continue;
|
||||||
|
|
||||||
|
// Don't call continueDecoding in the middle of decodeHeaders()
|
||||||
|
@@ -58,12 +62,14 @@
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if !defined(ALIMESH)
|
||||||
|
if (route_exists && // route can be resolved after an on-demand
|
||||||
|
// VHDS update
|
||||||
|
!callbacks_->decodingBuffer() && // Redirects with body not yet supported.
|
||||||
|
callbacks_->recreateStream(/*headers=*/nullptr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
// route cannot be resolved after an on-demand VHDS update or
|
||||||
|
// recreating stream failed, continue the filter-chain
|
||||||
931
envoy/1.20/patches/go-control-plane/20240104-enhance-srds.patch
Normal file
931
envoy/1.20/patches/go-control-plane/20240104-enhance-srds.patch
Normal file
@@ -0,0 +1,931 @@
|
|||||||
|
diff -Naur go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.go go-control-plane-new/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.go
|
||||||
|
--- go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.go 2024-01-04 21:07:22.000000000 +0800
|
||||||
|
+++ go-control-plane-new/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.go 2024-01-04 21:02:10.000000000 +0800
|
||||||
|
@@ -2286,6 +2286,8 @@
|
||||||
|
|
||||||
|
// Types that are assignable to Type:
|
||||||
|
// *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_
|
||||||
|
+ // *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor_
|
||||||
|
+ // *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor_
|
||||||
|
Type isScopedRoutes_ScopeKeyBuilder_FragmentBuilder_Type `protobuf_oneof:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2335,6 +2337,20 @@
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder) GetHostValueExtractor() *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor {
|
||||||
|
+ if x, ok := x.GetType().(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor_); ok {
|
||||||
|
+ return x.HostValueExtractor
|
||||||
|
+ }
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder) GetLocalPortValueExtractor() *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor {
|
||||||
|
+ if x, ok := x.GetType().(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor_); ok {
|
||||||
|
+ return x.LocalPortValueExtractor
|
||||||
|
+ }
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
type isScopedRoutes_ScopeKeyBuilder_FragmentBuilder_Type interface {
|
||||||
|
isScopedRoutes_ScopeKeyBuilder_FragmentBuilder_Type()
|
||||||
|
}
|
||||||
|
@@ -2344,9 +2360,23 @@
|
||||||
|
HeaderValueExtractor *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor `protobuf:"bytes,1,opt,name=header_value_extractor,json=headerValueExtractor,proto3,oneof"`
|
||||||
|
}
|
||||||
|
|
||||||
|
+type ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor_ struct {
|
||||||
|
+ HostValueExtractor *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor `protobuf:"bytes,101,opt,name=host_value_extractor,json=hostValueExtractor,proto3,oneof"`
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+type ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor_ struct {
|
||||||
|
+ LocalPortValueExtractor *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor `protobuf:"bytes,102,opt,name=local_port_value_extractor,json=localPortValueExtractor,proto3,oneof"`
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_) isScopedRoutes_ScopeKeyBuilder_FragmentBuilder_Type() {
|
||||||
|
}
|
||||||
|
|
||||||
|
+func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor_) isScopedRoutes_ScopeKeyBuilder_FragmentBuilder_Type() {
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor_) isScopedRoutes_ScopeKeyBuilder_FragmentBuilder_Type() {
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// Specifies how the value of a header should be extracted.
|
||||||
|
// The following example maps the structure of a header to the fields in this message.
|
||||||
|
//
|
||||||
|
@@ -2475,6 +2505,92 @@
|
||||||
|
func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_Element) isScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_ExtractType() {
|
||||||
|
}
|
||||||
|
|
||||||
|
+type ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor struct {
|
||||||
|
+ state protoimpl.MessageState
|
||||||
|
+ sizeCache protoimpl.SizeCache
|
||||||
|
+ unknownFields protoimpl.UnknownFields
|
||||||
|
+
|
||||||
|
+ // The maximum number of host superset recomputes. If not specified, defaults to 100.
|
||||||
|
+ MaxRecomputeNum *wrappers.UInt32Value `protobuf:"bytes,1,opt,name=max_recompute_num,json=maxRecomputeNum,proto3" json:"max_recompute_num,omitempty"`
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor) Reset() {
|
||||||
|
+ *x = ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor{}
|
||||||
|
+ if protoimpl.UnsafeEnabled {
|
||||||
|
+ mi := &file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[18]
|
||||||
|
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
+ ms.StoreMessageInfo(mi)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor) String() string {
|
||||||
|
+ return protoimpl.X.MessageStringOf(x)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor) ProtoMessage() {}
|
||||||
|
+
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor) ProtoReflect() protoreflect.Message {
|
||||||
|
+ mi := &file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[18]
|
||||||
|
+ if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
+ if ms.LoadMessageInfo() == nil {
|
||||||
|
+ ms.StoreMessageInfo(mi)
|
||||||
|
+ }
|
||||||
|
+ return ms
|
||||||
|
+ }
|
||||||
|
+ return mi.MessageOf(x)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Deprecated: Use ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor.ProtoReflect.Descriptor instead.
|
||||||
|
+func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor) Descriptor() ([]byte, []int) {
|
||||||
|
+ return file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_rawDescGZIP(), []int{5, 0, 0, 1}
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor) GetMaxRecomputeNum() *wrappers.UInt32Value {
|
||||||
|
+ if x != nil {
|
||||||
|
+ return x.MaxRecomputeNum
|
||||||
|
+ }
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+type ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor struct {
|
||||||
|
+ state protoimpl.MessageState
|
||||||
|
+ sizeCache protoimpl.SizeCache
|
||||||
|
+ unknownFields protoimpl.UnknownFields
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor) Reset() {
|
||||||
|
+ *x = ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor{}
|
||||||
|
+ if protoimpl.UnsafeEnabled {
|
||||||
|
+ mi := &file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[19]
|
||||||
|
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
+ ms.StoreMessageInfo(mi)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor) String() string {
|
||||||
|
+ return protoimpl.X.MessageStringOf(x)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor) ProtoMessage() {}
|
||||||
|
+
|
||||||
|
+func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor) ProtoReflect() protoreflect.Message {
|
||||||
|
+ mi := &file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[19]
|
||||||
|
+ if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
+ if ms.LoadMessageInfo() == nil {
|
||||||
|
+ ms.StoreMessageInfo(mi)
|
||||||
|
+ }
|
||||||
|
+ return ms
|
||||||
|
+ }
|
||||||
|
+ return mi.MessageOf(x)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Deprecated: Use ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor.ProtoReflect.Descriptor instead.
|
||||||
|
+func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor) Descriptor() ([]byte, []int) {
|
||||||
|
+ return file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_rawDescGZIP(), []int{5, 0, 0, 2}
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// Specifies a header field's key value pair to match on.
|
||||||
|
type ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
@@ -2494,7 +2610,7 @@
|
||||||
|
func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement) Reset() {
|
||||||
|
*x = ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
- mi := &file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[18]
|
||||||
|
+ mi := &file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[20]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
@@ -2507,7 +2623,7 @@
|
||||||
|
func (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement) ProtoReflect() protoreflect.Message {
|
||||||
|
- mi := &file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[18]
|
||||||
|
+ mi := &file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[20]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
@@ -3079,7 +3195,7 @@
|
||||||
|
0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61,
|
||||||
|
0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52,
|
||||||
|
0x6f, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
|
||||||
|
- 0x6e, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x22, 0xe9, 0x0e, 0x0a, 0x0c, 0x53, 0x63, 0x6f, 0x70, 0x65,
|
||||||
|
+ 0x6e, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x22, 0xe1, 0x14, 0x0a, 0x0c, 0x53, 0x63, 0x6f, 0x70, 0x65,
|
||||||
|
0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
|
||||||
|
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04,
|
||||||
|
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x11, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x6b,
|
||||||
|
@@ -3114,7 +3230,7 @@
|
||||||
|
0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
|
||||||
|
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65,
|
||||||
|
0x64, 0x52, 0x64, 0x73, 0x48, 0x00, 0x52, 0x09, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x64,
|
||||||
|
- 0x73, 0x1a, 0xd9, 0x09, 0x0a, 0x0f, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75,
|
||||||
|
+ 0x73, 0x1a, 0xd1, 0x0f, 0x0a, 0x0f, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75,
|
||||||
|
0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x91, 0x01, 0x0a, 0x09, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65,
|
||||||
|
0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x69, 0x2e, 0x65, 0x6e, 0x76, 0x6f,
|
||||||
|
0x79, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c,
|
||||||
|
@@ -3124,7 +3240,7 @@
|
||||||
|
0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69,
|
||||||
|
0x6c, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69,
|
||||||
|
0x6c, 0x64, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x09,
|
||||||
|
- 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0xd5, 0x07, 0x0a, 0x0f, 0x46, 0x72,
|
||||||
|
+ 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0xcd, 0x0d, 0x0a, 0x0f, 0x46, 0x72,
|
||||||
|
0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0xb6, 0x01,
|
||||||
|
0x0a, 0x16, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x65,
|
||||||
|
0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x7e,
|
||||||
|
@@ -3137,131 +3253,178 @@
|
||||||
|
0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
|
||||||
|
0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x48, 0x00,
|
||||||
|
0x52, 0x14, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74,
|
||||||
|
- 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x1a, 0x8f, 0x05, 0x0a, 0x14, 0x48, 0x65, 0x61, 0x64, 0x65,
|
||||||
|
- 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12,
|
||||||
|
- 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa,
|
||||||
|
- 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x11,
|
||||||
|
- 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f,
|
||||||
|
- 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||||
|
- 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x05, 0x69, 0x6e, 0x64,
|
||||||
|
- 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65,
|
||||||
|
- 0x78, 0x12, 0xa5, 0x01, 0x0a, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20,
|
||||||
|
- 0x01, 0x28, 0x0b, 0x32, 0x88, 0x01, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x65, 0x78, 0x74,
|
||||||
|
- 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x2e,
|
||||||
|
+ 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0xb0, 0x01, 0x0a, 0x14, 0x68, 0x6f, 0x73, 0x74, 0x5f,
|
||||||
|
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18,
|
||||||
|
+ 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x7c, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x65, 0x78,
|
||||||
|
+ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73,
|
||||||
|
+ 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f,
|
||||||
|
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||||
|
+ 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73,
|
||||||
|
+ 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72,
|
||||||
|
+ 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72,
|
||||||
|
+ 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63,
|
||||||
|
+ 0x74, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x12, 0x68, 0x6f, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
|
||||||
|
+ 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0xc1, 0x01, 0x0a, 0x1a, 0x6c, 0x6f,
|
||||||
|
+ 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x65,
|
||||||
|
+ 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x81,
|
||||||
|
+ 0x01, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
|
||||||
|
+ 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f,
|
||||||
|
+ 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
|
||||||
|
+ 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63,
|
||||||
|
+ 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65,
|
||||||
|
+ 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d,
|
||||||
|
+ 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
|
||||||
|
+ 0x50, 0x6f, 0x72, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74,
|
||||||
|
+ 0x6f, 0x72, 0x48, 0x00, 0x52, 0x17, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x56,
|
||||||
|
+ 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x1a, 0x8f, 0x05,
|
||||||
|
+ 0x0a, 0x14, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74,
|
||||||
|
+ 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
||||||
|
+ 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e,
|
||||||
|
+ 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73,
|
||||||
|
+ 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10,
|
||||||
|
+ 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72,
|
||||||
|
+ 0x12, 0x16, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48,
|
||||||
|
+ 0x00, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0xa5, 0x01, 0x0a, 0x07, 0x65, 0x6c, 0x65,
|
||||||
|
+ 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x88, 0x01, 0x2e, 0x65, 0x6e,
|
||||||
|
+ 0x76, 0x6f, 0x79, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66,
|
||||||
|
+ 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68,
|
||||||
|
+ 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d,
|
||||||
|
+ 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64,
|
||||||
|
+ 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42,
|
||||||
|
+ 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42,
|
||||||
|
+ 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c,
|
||||||
|
+ 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x4b, 0x76, 0x45, 0x6c,
|
||||||
|
+ 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||||
|
+ 0x1a, 0xdb, 0x01, 0x0a, 0x09, 0x4b, 0x76, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x25,
|
||||||
|
+ 0x0a, 0x09, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
|
+ 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x73, 0x65, 0x70, 0x61,
|
||||||
|
+ 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01,
|
||||||
|
+ 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||||
|
+ 0x3a, 0x8b, 0x01, 0x9a, 0xc5, 0x88, 0x1e, 0x85, 0x01, 0x0a, 0x82, 0x01, 0x65, 0x6e, 0x76, 0x6f,
|
||||||
|
+ 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e,
|
||||||
|
0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e,
|
||||||
|
0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e,
|
||||||
|
- 0x76, 0x33, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e,
|
||||||
|
+ 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e,
|
||||||
|
0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e,
|
||||||
|
0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e,
|
||||||
|
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61,
|
||||||
|
- 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x4b, 0x76, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00,
|
||||||
|
- 0x52, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0xdb, 0x01, 0x0a, 0x09, 0x4b, 0x76,
|
||||||
|
- 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x09, 0x73, 0x65, 0x70, 0x61, 0x72,
|
||||||
|
- 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72,
|
||||||
|
- 0x02, 0x10, 0x01, 0x52, 0x09, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x19,
|
||||||
|
- 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04,
|
||||||
|
- 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x3a, 0x8b, 0x01, 0x9a, 0xc5, 0x88, 0x1e,
|
||||||
|
- 0x85, 0x01, 0x0a, 0x82, 0x01, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||||
|
+ 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x4b, 0x76, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x7f,
|
||||||
|
+ 0x9a, 0xc5, 0x88, 0x1e, 0x7a, 0x0a, 0x78, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e,
|
||||||
|
+ 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f,
|
||||||
|
+ 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
|
||||||
|
+ 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63,
|
||||||
|
+ 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65,
|
||||||
|
+ 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d,
|
||||||
|
+ 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65,
|
||||||
|
+ 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x42,
|
||||||
|
+ 0x0e, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x1a,
|
||||||
|
+ 0xdd, 0x01, 0x0a, 0x12, 0x48, 0x6f, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74,
|
||||||
|
+ 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x48, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65,
|
||||||
|
+ 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
|
+ 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
|
+ 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
|
||||||
|
+ 0x0f, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x4e, 0x75, 0x6d,
|
||||||
|
+ 0x3a, 0x7d, 0x9a, 0xc5, 0x88, 0x1e, 0x78, 0x0a, 0x76, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63,
|
||||||
|
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74,
|
||||||
|
+ 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
|
||||||
|
+ 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e,
|
||||||
|
+ 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f,
|
||||||
|
+ 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61,
|
||||||
|
+ 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x48, 0x6f, 0x73,
|
||||||
|
+ 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x1a,
|
||||||
|
+ 0x9e, 0x01, 0x0a, 0x17, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x61, 0x6c,
|
||||||
|
+ 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x3a, 0x82, 0x01, 0x9a, 0xc5,
|
||||||
|
+ 0x88, 0x1e, 0x7d, 0x0a, 0x7b, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||||
|
0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
|
||||||
|
0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
|
0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f, 0x70,
|
||||||
|
0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65,
|
||||||
|
0x79, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e,
|
||||||
|
- 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56,
|
||||||
|
- 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x4b, 0x76,
|
||||||
|
- 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x7f, 0x9a, 0xc5, 0x88, 0x1e, 0x7a, 0x0a, 0x78,
|
||||||
|
- 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c,
|
||||||
|
- 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70,
|
||||||
|
- 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61,
|
||||||
|
- 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75,
|
||||||
|
- 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69, 0x6c,
|
||||||
|
- 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c,
|
||||||
|
- 0x64, 0x65, 0x72, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45,
|
||||||
|
- 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x42, 0x0e, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x72,
|
||||||
|
- 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x6a, 0x9a, 0xc5, 0x88, 0x1e, 0x65, 0x0a,
|
||||||
|
- 0x63, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69,
|
||||||
|
- 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74,
|
||||||
|
- 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e,
|
||||||
|
- 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f,
|
||||||
|
- 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69,
|
||||||
|
- 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69,
|
||||||
|
- 0x6c, 0x64, 0x65, 0x72, 0x42, 0x0b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42,
|
||||||
|
- 0x01, 0x3a, 0x5a, 0x9a, 0xc5, 0x88, 0x1e, 0x55, 0x0a, 0x53, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e,
|
||||||
|
- 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65,
|
||||||
|
- 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
|
||||||
|
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32,
|
||||||
|
- 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63,
|
||||||
|
- 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x3a, 0x4a, 0x9a,
|
||||||
|
- 0xc5, 0x88, 0x1e, 0x45, 0x0a, 0x43, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
|
||||||
|
- 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
||||||
|
- 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||||
|
- 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f,
|
||||||
|
- 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x42, 0x17, 0x0a, 0x10, 0x63, 0x6f, 0x6e,
|
||||||
|
- 0x66, 0x69, 0x67, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x03, 0xf8,
|
||||||
|
- 0x42, 0x01, 0x22, 0xf1, 0x01, 0x0a, 0x09, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73,
|
||||||
|
- 0x12, 0x65, 0x0a, 0x18, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x5f, 0x72, 0x64, 0x73, 0x5f, 0x63,
|
||||||
|
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||||
|
- 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||||
|
- 0x67, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||||
|
- 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01,
|
||||||
|
- 0x52, 0x15, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||||
|
- 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x72, 0x64, 0x73, 0x5f,
|
||||||
|
- 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f,
|
||||||
|
- 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73,
|
||||||
|
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x3a, 0x47, 0x9a,
|
||||||
|
- 0xc5, 0x88, 0x1e, 0x42, 0x0a, 0x40, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
|
||||||
|
- 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
||||||
|
- 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||||
|
- 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f,
|
||||||
|
- 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x22, 0xcc, 0x02, 0x0a, 0x0a, 0x48, 0x74, 0x74, 0x70, 0x46,
|
||||||
|
- 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
|
||||||
|
- 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61,
|
||||||
|
- 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
|
||||||
|
- 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||||
|
- 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x48, 0x00,
|
||||||
|
- 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x58, 0x0a,
|
||||||
|
- 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72,
|
||||||
|
- 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e,
|
||||||
|
- 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x45,
|
||||||
|
- 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x6f,
|
||||||
|
- 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69,
|
||||||
|
- 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x6f, 0x70,
|
||||||
|
- 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73,
|
||||||
|
- 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x3a, 0x48, 0x9a, 0xc5, 0x88, 0x1e, 0x43, 0x0a,
|
||||||
|
- 0x41, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69,
|
||||||
|
- 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74,
|
||||||
|
- 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e,
|
||||||
|
- 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x46, 0x69, 0x6c, 0x74,
|
||||||
|
- 0x65, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x74, 0x79, 0x70,
|
||||||
|
- 0x65, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x06, 0x63,
|
||||||
|
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x9f, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||||
|
- 0x74, 0x49, 0x44, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0c,
|
||||||
|
- 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01,
|
||||||
|
- 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
- 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x43,
|
||||||
|
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x50, 0x9a, 0xc5, 0x88, 0x1e, 0x4b, 0x0a, 0x49, 0x65, 0x6e,
|
||||||
|
+ 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f,
|
||||||
|
+ 0x72, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72,
|
||||||
|
+ 0x3a, 0x6a, 0x9a, 0xc5, 0x88, 0x1e, 0x65, 0x0a, 0x63, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63,
|
||||||
|
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74,
|
||||||
|
+ 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
|
||||||
|
+ 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e,
|
||||||
|
+ 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f,
|
||||||
|
+ 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x46, 0x72, 0x61,
|
||||||
|
+ 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x42, 0x0b, 0x0a, 0x04,
|
||||||
|
+ 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x3a, 0x5a, 0x9a, 0xc5, 0x88, 0x1e, 0x55,
|
||||||
|
+ 0x0a, 0x53, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66,
|
||||||
|
+ 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74,
|
||||||
|
+ 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61,
|
||||||
|
+ 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52,
|
||||||
|
+ 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x75,
|
||||||
|
+ 0x69, 0x6c, 0x64, 0x65, 0x72, 0x3a, 0x4a, 0x9a, 0xc5, 0x88, 0x1e, 0x45, 0x0a, 0x43, 0x65, 0x6e,
|
||||||
|
0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65,
|
||||||
|
0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63,
|
||||||
|
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||||
|
- 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x45, 0x78,
|
||||||
|
- 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8e, 0x01, 0x0a, 0x20, 0x45, 0x6e, 0x76, 0x6f,
|
||||||
|
- 0x79, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x48, 0x74, 0x74, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
|
||||||
|
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x6a, 0x0a, 0x06,
|
||||||
|
- 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x52, 0x2e, 0x65,
|
||||||
|
- 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
|
||||||
|
- 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e,
|
||||||
|
- 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
|
||||||
|
- 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43,
|
||||||
|
- 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
|
||||||
|
- 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x71, 0x0a, 0x49, 0x69, 0x6f, 0x2e, 0x65,
|
||||||
|
- 0x6e, 0x76, 0x6f, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e,
|
||||||
|
- 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65,
|
||||||
|
- 0x72, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f,
|
||||||
|
- 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||||
|
- 0x65, 0x72, 0x2e, 0x76, 0x33, 0x42, 0x1a, 0x48, 0x74, 0x74, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
|
||||||
|
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74,
|
||||||
|
- 0x6f, 0x50, 0x01, 0xba, 0x80, 0xc8, 0xd1, 0x06, 0x02, 0x10, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||||
|
- 0x74, 0x6f, 0x33,
|
||||||
|
+ 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||||
|
+ 0x73, 0x42, 0x17, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x70, 0x65, 0x63,
|
||||||
|
+ 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0xf1, 0x01, 0x0a, 0x09, 0x53,
|
||||||
|
+ 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x12, 0x65, 0x0a, 0x18, 0x73, 0x63, 0x6f, 0x70,
|
||||||
|
+ 0x65, 0x64, 0x5f, 0x72, 0x64, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x6f,
|
||||||
|
+ 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x6e, 0x76,
|
||||||
|
+ 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76,
|
||||||
|
+ 0x33, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x08,
|
||||||
|
+ 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x15, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64,
|
||||||
|
+ 0x52, 0x64, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,
|
||||||
|
+ 0x34, 0x0a, 0x16, 0x73, 0x72, 0x64, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||||
|
+ 0x73, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
|
+ 0x14, 0x73, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x4c, 0x6f,
|
||||||
|
+ 0x63, 0x61, 0x74, 0x6f, 0x72, 0x3a, 0x47, 0x9a, 0xc5, 0x88, 0x1e, 0x42, 0x0a, 0x40, 0x65, 0x6e,
|
||||||
|
+ 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65,
|
||||||
|
+ 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63,
|
||||||
|
+ 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||||
|
+ 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x22, 0xcc,
|
||||||
|
+ 0x02, 0x0a, 0x0a, 0x48, 0x74, 0x74, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a,
|
||||||
|
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04,
|
||||||
|
+ 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x74, 0x79,
|
||||||
|
+ 0x70, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
|
||||||
|
+ 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||||
|
+ 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x43,
|
||||||
|
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x58, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
|
||||||
|
+ 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||||
|
+ 0x2b, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x63,
|
||||||
|
+ 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
|
||||||
|
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0f,
|
||||||
|
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x12,
|
||||||
|
+ 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x06,
|
||||||
|
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
|
||||||
|
+ 0x3a, 0x48, 0x9a, 0xc5, 0x88, 0x1e, 0x43, 0x0a, 0x41, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63,
|
||||||
|
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74,
|
||||||
|
+ 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
|
||||||
|
+ 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e,
|
||||||
|
+ 0x48, 0x74, 0x74, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x63, 0x6f,
|
||||||
|
+ 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a,
|
||||||
|
+ 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x9f, 0x01,
|
||||||
|
+ 0x0a, 0x12, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x45, 0x78, 0x74, 0x65, 0x6e,
|
||||||
|
+ 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x63, 0x6f,
|
||||||
|
+ 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f,
|
||||||
|
+ 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79,
|
||||||
|
+ 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x50, 0x9a,
|
||||||
|
+ 0xc5, 0x88, 0x1e, 0x4b, 0x0a, 0x49, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
|
||||||
|
+ 0x69, 0x67, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
||||||
|
+ 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||||
|
+ 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x71,
|
||||||
|
+ 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22,
|
||||||
|
+ 0x8e, 0x01, 0x0a, 0x20, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x48,
|
||||||
|
+ 0x74, 0x74, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e,
|
||||||
|
+ 0x61, 0x67, 0x65, 0x72, 0x12, 0x6a, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01,
|
||||||
|
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x52, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x65, 0x78, 0x74,
|
||||||
|
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x2e,
|
||||||
|
+ 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e,
|
||||||
|
+ 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e,
|
||||||
|
+ 0x76, 0x33, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||||
|
+ 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||||
|
+ 0x42, 0x71, 0x0a, 0x49, 0x69, 0x6f, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x70, 0x72, 0x6f, 0x78,
|
||||||
|
+ 0x79, 0x2e, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
|
||||||
|
+ 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f,
|
||||||
|
+ 0x72, 0x6b, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
|
||||||
|
+ 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x42, 0x1a, 0x48,
|
||||||
|
+ 0x74, 0x74, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e,
|
||||||
|
+ 0x61, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0xba, 0x80, 0xc8, 0xd1, 0x06,
|
||||||
|
+ 0x02, 0x10, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
@@ -3277,7 +3440,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
|
||||||
|
-var file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
|
||||||
|
+var file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
|
||||||
|
var file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_goTypes = []interface{}{
|
||||||
|
(HttpConnectionManager_CodecType)(0), // 0: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.CodecType
|
||||||
|
(HttpConnectionManager_ServerHeaderTransformation)(0), // 1: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.ServerHeaderTransformation
|
||||||
|
@@ -3302,102 +3465,107 @@
|
||||||
|
(*ScopedRoutes_ScopeKeyBuilder)(nil), // 20: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder
|
||||||
|
(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder)(nil), // 21: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder
|
||||||
|
(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor)(nil), // 22: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HeaderValueExtractor
|
||||||
|
- (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement)(nil), // 23: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HeaderValueExtractor.KvElement
|
||||||
|
- (*v32.RouteConfiguration)(nil), // 24: envoy.config.route.v3.RouteConfiguration
|
||||||
|
- (*wrappers.BoolValue)(nil), // 25: google.protobuf.BoolValue
|
||||||
|
- (*v3.HttpProtocolOptions)(nil), // 26: envoy.config.core.v3.HttpProtocolOptions
|
||||||
|
- (*v3.Http1ProtocolOptions)(nil), // 27: envoy.config.core.v3.Http1ProtocolOptions
|
||||||
|
- (*v3.Http2ProtocolOptions)(nil), // 28: envoy.config.core.v3.Http2ProtocolOptions
|
||||||
|
- (*v3.Http3ProtocolOptions)(nil), // 29: envoy.config.core.v3.Http3ProtocolOptions
|
||||||
|
- (*v3.SchemeHeaderTransformation)(nil), // 30: envoy.config.core.v3.SchemeHeaderTransformation
|
||||||
|
- (*wrappers.UInt32Value)(nil), // 31: google.protobuf.UInt32Value
|
||||||
|
- (*duration.Duration)(nil), // 32: google.protobuf.Duration
|
||||||
|
- (*v31.AccessLog)(nil), // 33: envoy.config.accesslog.v3.AccessLog
|
||||||
|
- (*v3.TypedExtensionConfig)(nil), // 34: envoy.config.core.v3.TypedExtensionConfig
|
||||||
|
- (*v3.SubstitutionFormatString)(nil), // 35: envoy.config.core.v3.SubstitutionFormatString
|
||||||
|
- (*v31.AccessLogFilter)(nil), // 36: envoy.config.accesslog.v3.AccessLogFilter
|
||||||
|
- (*v3.DataSource)(nil), // 37: envoy.config.core.v3.DataSource
|
||||||
|
- (*v3.HeaderValueOption)(nil), // 38: envoy.config.core.v3.HeaderValueOption
|
||||||
|
- (*v3.ConfigSource)(nil), // 39: envoy.config.core.v3.ConfigSource
|
||||||
|
- (*v32.ScopedRouteConfiguration)(nil), // 40: envoy.config.route.v3.ScopedRouteConfiguration
|
||||||
|
- (*any.Any)(nil), // 41: google.protobuf.Any
|
||||||
|
- (*v3.ExtensionConfigSource)(nil), // 42: envoy.config.core.v3.ExtensionConfigSource
|
||||||
|
- (*v33.Percent)(nil), // 43: envoy.type.v3.Percent
|
||||||
|
- (*v34.CustomTag)(nil), // 44: envoy.type.tracing.v3.CustomTag
|
||||||
|
- (*v35.Tracing_Http)(nil), // 45: envoy.config.trace.v3.Tracing.Http
|
||||||
|
- (*v36.PathTransformation)(nil), // 46: envoy.type.http.v3.PathTransformation
|
||||||
|
+ (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor)(nil), // 23: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HostValueExtractor
|
||||||
|
+ (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor)(nil), // 24: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.LocalPortValueExtractor
|
||||||
|
+ (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement)(nil), // 25: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HeaderValueExtractor.KvElement
|
||||||
|
+ (*v32.RouteConfiguration)(nil), // 26: envoy.config.route.v3.RouteConfiguration
|
||||||
|
+ (*wrappers.BoolValue)(nil), // 27: google.protobuf.BoolValue
|
||||||
|
+ (*v3.HttpProtocolOptions)(nil), // 28: envoy.config.core.v3.HttpProtocolOptions
|
||||||
|
+ (*v3.Http1ProtocolOptions)(nil), // 29: envoy.config.core.v3.Http1ProtocolOptions
|
||||||
|
+ (*v3.Http2ProtocolOptions)(nil), // 30: envoy.config.core.v3.Http2ProtocolOptions
|
||||||
|
+ (*v3.Http3ProtocolOptions)(nil), // 31: envoy.config.core.v3.Http3ProtocolOptions
|
||||||
|
+ (*v3.SchemeHeaderTransformation)(nil), // 32: envoy.config.core.v3.SchemeHeaderTransformation
|
||||||
|
+ (*wrappers.UInt32Value)(nil), // 33: google.protobuf.UInt32Value
|
||||||
|
+ (*duration.Duration)(nil), // 34: google.protobuf.Duration
|
||||||
|
+ (*v31.AccessLog)(nil), // 35: envoy.config.accesslog.v3.AccessLog
|
||||||
|
+ (*v3.TypedExtensionConfig)(nil), // 36: envoy.config.core.v3.TypedExtensionConfig
|
||||||
|
+ (*v3.SubstitutionFormatString)(nil), // 37: envoy.config.core.v3.SubstitutionFormatString
|
||||||
|
+ (*v31.AccessLogFilter)(nil), // 38: envoy.config.accesslog.v3.AccessLogFilter
|
||||||
|
+ (*v3.DataSource)(nil), // 39: envoy.config.core.v3.DataSource
|
||||||
|
+ (*v3.HeaderValueOption)(nil), // 40: envoy.config.core.v3.HeaderValueOption
|
||||||
|
+ (*v3.ConfigSource)(nil), // 41: envoy.config.core.v3.ConfigSource
|
||||||
|
+ (*v32.ScopedRouteConfiguration)(nil), // 42: envoy.config.route.v3.ScopedRouteConfiguration
|
||||||
|
+ (*any.Any)(nil), // 43: google.protobuf.Any
|
||||||
|
+ (*v3.ExtensionConfigSource)(nil), // 44: envoy.config.core.v3.ExtensionConfigSource
|
||||||
|
+ (*v33.Percent)(nil), // 45: envoy.type.v3.Percent
|
||||||
|
+ (*v34.CustomTag)(nil), // 46: envoy.type.tracing.v3.CustomTag
|
||||||
|
+ (*v35.Tracing_Http)(nil), // 47: envoy.config.trace.v3.Tracing.Http
|
||||||
|
+ (*v36.PathTransformation)(nil), // 48: envoy.type.http.v3.PathTransformation
|
||||||
|
}
|
||||||
|
var file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_depIdxs = []int32{
|
||||||
|
0, // 0: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.codec_type:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.CodecType
|
||||||
|
8, // 1: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.rds:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.Rds
|
||||||
|
- 24, // 2: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.route_config:type_name -> envoy.config.route.v3.RouteConfiguration
|
||||||
|
+ 26, // 2: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.route_config:type_name -> envoy.config.route.v3.RouteConfiguration
|
||||||
|
10, // 3: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.scoped_routes:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes
|
||||||
|
12, // 4: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.http_filters:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter
|
||||||
|
- 25, // 5: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.add_user_agent:type_name -> google.protobuf.BoolValue
|
||||||
|
+ 27, // 5: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.add_user_agent:type_name -> google.protobuf.BoolValue
|
||||||
|
15, // 6: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.tracing:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing
|
||||||
|
- 26, // 7: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.common_http_protocol_options:type_name -> envoy.config.core.v3.HttpProtocolOptions
|
||||||
|
- 27, // 8: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.http_protocol_options:type_name -> envoy.config.core.v3.Http1ProtocolOptions
|
||||||
|
- 28, // 9: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.http2_protocol_options:type_name -> envoy.config.core.v3.Http2ProtocolOptions
|
||||||
|
- 29, // 10: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.http3_protocol_options:type_name -> envoy.config.core.v3.Http3ProtocolOptions
|
||||||
|
+ 28, // 7: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.common_http_protocol_options:type_name -> envoy.config.core.v3.HttpProtocolOptions
|
||||||
|
+ 29, // 8: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.http_protocol_options:type_name -> envoy.config.core.v3.Http1ProtocolOptions
|
||||||
|
+ 30, // 9: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.http2_protocol_options:type_name -> envoy.config.core.v3.Http2ProtocolOptions
|
||||||
|
+ 31, // 10: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.http3_protocol_options:type_name -> envoy.config.core.v3.Http3ProtocolOptions
|
||||||
|
1, // 11: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.server_header_transformation:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.ServerHeaderTransformation
|
||||||
|
- 30, // 12: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.scheme_header_transformation:type_name -> envoy.config.core.v3.SchemeHeaderTransformation
|
||||||
|
- 31, // 13: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.max_request_headers_kb:type_name -> google.protobuf.UInt32Value
|
||||||
|
- 32, // 14: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.stream_idle_timeout:type_name -> google.protobuf.Duration
|
||||||
|
- 32, // 15: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.request_timeout:type_name -> google.protobuf.Duration
|
||||||
|
- 32, // 16: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.request_headers_timeout:type_name -> google.protobuf.Duration
|
||||||
|
- 32, // 17: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.drain_timeout:type_name -> google.protobuf.Duration
|
||||||
|
- 32, // 18: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.delayed_close_timeout:type_name -> google.protobuf.Duration
|
||||||
|
- 33, // 19: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.access_log:type_name -> envoy.config.accesslog.v3.AccessLog
|
||||||
|
- 25, // 20: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.use_remote_address:type_name -> google.protobuf.BoolValue
|
||||||
|
- 34, // 21: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.original_ip_detection_extensions:type_name -> envoy.config.core.v3.TypedExtensionConfig
|
||||||
|
+ 32, // 12: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.scheme_header_transformation:type_name -> envoy.config.core.v3.SchemeHeaderTransformation
|
||||||
|
+ 33, // 13: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.max_request_headers_kb:type_name -> google.protobuf.UInt32Value
|
||||||
|
+ 34, // 14: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.stream_idle_timeout:type_name -> google.protobuf.Duration
|
||||||
|
+ 34, // 15: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.request_timeout:type_name -> google.protobuf.Duration
|
||||||
|
+ 34, // 16: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.request_headers_timeout:type_name -> google.protobuf.Duration
|
||||||
|
+ 34, // 17: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.drain_timeout:type_name -> google.protobuf.Duration
|
||||||
|
+ 34, // 18: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.delayed_close_timeout:type_name -> google.protobuf.Duration
|
||||||
|
+ 35, // 19: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.access_log:type_name -> envoy.config.accesslog.v3.AccessLog
|
||||||
|
+ 27, // 20: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.use_remote_address:type_name -> google.protobuf.BoolValue
|
||||||
|
+ 36, // 21: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.original_ip_detection_extensions:type_name -> envoy.config.core.v3.TypedExtensionConfig
|
||||||
|
16, // 22: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.internal_address_config:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.InternalAddressConfig
|
||||||
|
- 25, // 23: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.generate_request_id:type_name -> google.protobuf.BoolValue
|
||||||
|
+ 27, // 23: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.generate_request_id:type_name -> google.protobuf.BoolValue
|
||||||
|
2, // 24: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.forward_client_cert_details:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.ForwardClientCertDetails
|
||||||
|
17, // 25: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.set_current_client_cert_details:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.SetCurrentClientCertDetails
|
||||||
|
18, // 26: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.upgrade_configs:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig
|
||||||
|
- 25, // 27: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.normalize_path:type_name -> google.protobuf.BoolValue
|
||||||
|
+ 27, // 27: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.normalize_path:type_name -> google.protobuf.BoolValue
|
||||||
|
3, // 28: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.path_with_escaped_slashes_action:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.PathWithEscapedSlashesAction
|
||||||
|
13, // 29: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.request_id_extension:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.RequestIDExtension
|
||||||
|
6, // 30: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.local_reply_config:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.LocalReplyConfig
|
||||||
|
- 25, // 31: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.stream_error_on_invalid_http_message:type_name -> google.protobuf.BoolValue
|
||||||
|
+ 27, // 31: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.stream_error_on_invalid_http_message:type_name -> google.protobuf.BoolValue
|
||||||
|
19, // 32: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.path_normalization_options:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.PathNormalizationOptions
|
||||||
|
7, // 33: envoy.extensions.filters.network.http_connection_manager.v3.LocalReplyConfig.mappers:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper
|
||||||
|
- 35, // 34: envoy.extensions.filters.network.http_connection_manager.v3.LocalReplyConfig.body_format:type_name -> envoy.config.core.v3.SubstitutionFormatString
|
||||||
|
- 36, // 35: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.filter:type_name -> envoy.config.accesslog.v3.AccessLogFilter
|
||||||
|
- 31, // 36: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.status_code:type_name -> google.protobuf.UInt32Value
|
||||||
|
- 37, // 37: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.body:type_name -> envoy.config.core.v3.DataSource
|
||||||
|
- 35, // 38: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.body_format_override:type_name -> envoy.config.core.v3.SubstitutionFormatString
|
||||||
|
- 38, // 39: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.headers_to_add:type_name -> envoy.config.core.v3.HeaderValueOption
|
||||||
|
- 39, // 40: envoy.extensions.filters.network.http_connection_manager.v3.Rds.config_source:type_name -> envoy.config.core.v3.ConfigSource
|
||||||
|
- 40, // 41: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRouteConfigurationsList.scoped_route_configurations:type_name -> envoy.config.route.v3.ScopedRouteConfiguration
|
||||||
|
+ 37, // 34: envoy.extensions.filters.network.http_connection_manager.v3.LocalReplyConfig.body_format:type_name -> envoy.config.core.v3.SubstitutionFormatString
|
||||||
|
+ 38, // 35: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.filter:type_name -> envoy.config.accesslog.v3.AccessLogFilter
|
||||||
|
+ 33, // 36: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.status_code:type_name -> google.protobuf.UInt32Value
|
||||||
|
+ 39, // 37: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.body:type_name -> envoy.config.core.v3.DataSource
|
||||||
|
+ 37, // 38: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.body_format_override:type_name -> envoy.config.core.v3.SubstitutionFormatString
|
||||||
|
+ 40, // 39: envoy.extensions.filters.network.http_connection_manager.v3.ResponseMapper.headers_to_add:type_name -> envoy.config.core.v3.HeaderValueOption
|
||||||
|
+ 41, // 40: envoy.extensions.filters.network.http_connection_manager.v3.Rds.config_source:type_name -> envoy.config.core.v3.ConfigSource
|
||||||
|
+ 42, // 41: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRouteConfigurationsList.scoped_route_configurations:type_name -> envoy.config.route.v3.ScopedRouteConfiguration
|
||||||
|
20, // 42: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.scope_key_builder:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder
|
||||||
|
- 39, // 43: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.rds_config_source:type_name -> envoy.config.core.v3.ConfigSource
|
||||||
|
+ 41, // 43: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.rds_config_source:type_name -> envoy.config.core.v3.ConfigSource
|
||||||
|
9, // 44: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.scoped_route_configurations_list:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRouteConfigurationsList
|
||||||
|
11, // 45: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.scoped_rds:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRds
|
||||||
|
- 39, // 46: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRds.scoped_rds_config_source:type_name -> envoy.config.core.v3.ConfigSource
|
||||||
|
- 41, // 47: envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter.typed_config:type_name -> google.protobuf.Any
|
||||||
|
- 42, // 48: envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter.config_discovery:type_name -> envoy.config.core.v3.ExtensionConfigSource
|
||||||
|
- 41, // 49: envoy.extensions.filters.network.http_connection_manager.v3.RequestIDExtension.typed_config:type_name -> google.protobuf.Any
|
||||||
|
+ 41, // 46: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRds.scoped_rds_config_source:type_name -> envoy.config.core.v3.ConfigSource
|
||||||
|
+ 43, // 47: envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter.typed_config:type_name -> google.protobuf.Any
|
||||||
|
+ 44, // 48: envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter.config_discovery:type_name -> envoy.config.core.v3.ExtensionConfigSource
|
||||||
|
+ 43, // 49: envoy.extensions.filters.network.http_connection_manager.v3.RequestIDExtension.typed_config:type_name -> google.protobuf.Any
|
||||||
|
5, // 50: envoy.extensions.filters.network.http_connection_manager.v3.EnvoyMobileHttpConnectionManager.config:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
|
||||||
|
- 43, // 51: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.client_sampling:type_name -> envoy.type.v3.Percent
|
||||||
|
- 43, // 52: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.random_sampling:type_name -> envoy.type.v3.Percent
|
||||||
|
- 43, // 53: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.overall_sampling:type_name -> envoy.type.v3.Percent
|
||||||
|
- 31, // 54: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.max_path_tag_length:type_name -> google.protobuf.UInt32Value
|
||||||
|
- 44, // 55: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.custom_tags:type_name -> envoy.type.tracing.v3.CustomTag
|
||||||
|
- 45, // 56: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.provider:type_name -> envoy.config.trace.v3.Tracing.Http
|
||||||
|
- 25, // 57: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.SetCurrentClientCertDetails.subject:type_name -> google.protobuf.BoolValue
|
||||||
|
+ 45, // 51: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.client_sampling:type_name -> envoy.type.v3.Percent
|
||||||
|
+ 45, // 52: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.random_sampling:type_name -> envoy.type.v3.Percent
|
||||||
|
+ 45, // 53: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.overall_sampling:type_name -> envoy.type.v3.Percent
|
||||||
|
+ 33, // 54: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.max_path_tag_length:type_name -> google.protobuf.UInt32Value
|
||||||
|
+ 46, // 55: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.custom_tags:type_name -> envoy.type.tracing.v3.CustomTag
|
||||||
|
+ 47, // 56: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.Tracing.provider:type_name -> envoy.config.trace.v3.Tracing.Http
|
||||||
|
+ 27, // 57: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.SetCurrentClientCertDetails.subject:type_name -> google.protobuf.BoolValue
|
||||||
|
12, // 58: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig.filters:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter
|
||||||
|
- 25, // 59: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig.enabled:type_name -> google.protobuf.BoolValue
|
||||||
|
- 46, // 60: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.PathNormalizationOptions.forwarding_transformation:type_name -> envoy.type.http.v3.PathTransformation
|
||||||
|
- 46, // 61: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.PathNormalizationOptions.http_filter_transformation:type_name -> envoy.type.http.v3.PathTransformation
|
||||||
|
+ 27, // 59: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig.enabled:type_name -> google.protobuf.BoolValue
|
||||||
|
+ 48, // 60: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.PathNormalizationOptions.forwarding_transformation:type_name -> envoy.type.http.v3.PathTransformation
|
||||||
|
+ 48, // 61: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.PathNormalizationOptions.http_filter_transformation:type_name -> envoy.type.http.v3.PathTransformation
|
||||||
|
21, // 62: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.fragments:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder
|
||||||
|
22, // 63: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.header_value_extractor:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HeaderValueExtractor
|
||||||
|
- 23, // 64: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HeaderValueExtractor.element:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HeaderValueExtractor.KvElement
|
||||||
|
- 65, // [65:65] is the sub-list for method output_type
|
||||||
|
- 65, // [65:65] is the sub-list for method input_type
|
||||||
|
- 65, // [65:65] is the sub-list for extension type_name
|
||||||
|
- 65, // [65:65] is the sub-list for extension extendee
|
||||||
|
- 0, // [0:65] is the sub-list for field type_name
|
||||||
|
+ 23, // 64: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.host_value_extractor:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HostValueExtractor
|
||||||
|
+ 24, // 65: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.local_port_value_extractor:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.LocalPortValueExtractor
|
||||||
|
+ 25, // 66: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HeaderValueExtractor.element:type_name -> envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HeaderValueExtractor.KvElement
|
||||||
|
+ 33, // 67: envoy.extensions.filters.network.http_connection_manager.v3.ScopedRoutes.ScopeKeyBuilder.FragmentBuilder.HostValueExtractor.max_recompute_num:type_name -> google.protobuf.UInt32Value
|
||||||
|
+ 68, // [68:68] is the sub-list for method output_type
|
||||||
|
+ 68, // [68:68] is the sub-list for method input_type
|
||||||
|
+ 68, // [68:68] is the sub-list for extension type_name
|
||||||
|
+ 68, // [68:68] is the sub-list for extension extendee
|
||||||
|
+ 0, // [0:68] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
@@ -3625,6 +3793,30 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
+ switch v := v.(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor); i {
|
||||||
|
+ case 0:
|
||||||
|
+ return &v.state
|
||||||
|
+ case 1:
|
||||||
|
+ return &v.sizeCache
|
||||||
|
+ case 2:
|
||||||
|
+ return &v.unknownFields
|
||||||
|
+ default:
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
+ switch v := v.(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor); i {
|
||||||
|
+ case 0:
|
||||||
|
+ return &v.state
|
||||||
|
+ case 1:
|
||||||
|
+ return &v.sizeCache
|
||||||
|
+ case 2:
|
||||||
|
+ return &v.unknownFields
|
||||||
|
+ default:
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
@@ -3653,6 +3845,8 @@
|
||||||
|
}
|
||||||
|
file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[16].OneofWrappers = []interface{}{
|
||||||
|
(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_)(nil),
|
||||||
|
+ (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor_)(nil),
|
||||||
|
+ (*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor_)(nil),
|
||||||
|
}
|
||||||
|
file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_msgTypes[17].OneofWrappers = []interface{}{
|
||||||
|
(*ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_Index)(nil),
|
||||||
|
@@ -3664,7 +3858,7 @@
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: file_envoy_extensions_filters_network_http_connection_manager_v3_http_connection_manager_proto_rawDesc,
|
||||||
|
NumEnums: 5,
|
||||||
|
- NumMessages: 19,
|
||||||
|
+ NumMessages: 21,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 0,
|
||||||
|
},
|
||||||
|
diff -Naur go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.validate.go go-control-plane-new/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.validate.go
|
||||||
|
--- go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.validate.go 2024-01-04 21:07:22.000000000 +0800
|
||||||
|
+++ go-control-plane-new/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.validate.go 2024-01-04 21:02:10.000000000 +0800
|
||||||
|
@@ -1986,6 +1986,30 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ case *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor_:
|
||||||
|
+
|
||||||
|
+ if v, ok := interface{}(m.GetHostValueExtractor()).(interface{ Validate() error }); ok {
|
||||||
|
+ if err := v.Validate(); err != nil {
|
||||||
|
+ return ScopedRoutes_ScopeKeyBuilder_FragmentBuilderValidationError{
|
||||||
|
+ field: "HostValueExtractor",
|
||||||
|
+ reason: "embedded message failed validation",
|
||||||
|
+ cause: err,
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ case *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor_:
|
||||||
|
+
|
||||||
|
+ if v, ok := interface{}(m.GetLocalPortValueExtractor()).(interface{ Validate() error }); ok {
|
||||||
|
+ if err := v.Validate(); err != nil {
|
||||||
|
+ return ScopedRoutes_ScopeKeyBuilder_FragmentBuilderValidationError{
|
||||||
|
+ field: "LocalPortValueExtractor",
|
||||||
|
+ reason: "embedded message failed validation",
|
||||||
|
+ cause: err,
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
default:
|
||||||
|
return ScopedRoutes_ScopeKeyBuilder_FragmentBuilderValidationError{
|
||||||
|
field: "Type",
|
||||||
|
@@ -2162,6 +2186,172 @@
|
||||||
|
} = ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractorValidationError{}
|
||||||
|
|
||||||
|
// Validate checks the field values on
|
||||||
|
+// ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor with the
|
||||||
|
+// rules defined in the proto definition for this message. If any rules are
|
||||||
|
+// violated, an error is returned.
|
||||||
|
+func (m *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor) Validate() error {
|
||||||
|
+ if m == nil {
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if v, ok := interface{}(m.GetMaxRecomputeNum()).(interface{ Validate() error }); ok {
|
||||||
|
+ if err := v.Validate(); err != nil {
|
||||||
|
+ return ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError{
|
||||||
|
+ field: "MaxRecomputeNum",
|
||||||
|
+ reason: "embedded message failed validation",
|
||||||
|
+ cause: err,
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError
|
||||||
|
+// is the validation error returned by
|
||||||
|
+// ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor.Validate if
|
||||||
|
+// the designated constraints aren't met.
|
||||||
|
+type ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError struct {
|
||||||
|
+ field string
|
||||||
|
+ reason string
|
||||||
|
+ cause error
|
||||||
|
+ key bool
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Field function returns field value.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError) Field() string {
|
||||||
|
+ return e.field
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Reason function returns reason value.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError) Reason() string {
|
||||||
|
+ return e.reason
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Cause function returns cause value.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError) Cause() error {
|
||||||
|
+ return e.cause
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Key function returns key value.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError) Key() bool {
|
||||||
|
+ return e.key
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// ErrorName returns error name.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError) ErrorName() string {
|
||||||
|
+ return "ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Error satisfies the builtin error interface
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError) Error() string {
|
||||||
|
+ cause := ""
|
||||||
|
+ if e.cause != nil {
|
||||||
|
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ key := ""
|
||||||
|
+ if e.key {
|
||||||
|
+ key = "key for "
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return fmt.Sprintf(
|
||||||
|
+ "invalid %sScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor.%s: %s%s",
|
||||||
|
+ key,
|
||||||
|
+ e.field,
|
||||||
|
+ e.reason,
|
||||||
|
+ cause)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+var _ error = ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError{}
|
||||||
|
+
|
||||||
|
+var _ interface {
|
||||||
|
+ Field() string
|
||||||
|
+ Reason() string
|
||||||
|
+ Key() bool
|
||||||
|
+ Cause() error
|
||||||
|
+ ErrorName() string
|
||||||
|
+} = ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractorValidationError{}
|
||||||
|
+
|
||||||
|
+// Validate checks the field values on
|
||||||
|
+// ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor with
|
||||||
|
+// the rules defined in the proto definition for this message. If any rules
|
||||||
|
+// are violated, an error is returned.
|
||||||
|
+func (m *ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor) Validate() error {
|
||||||
|
+ if m == nil {
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError
|
||||||
|
+// is the validation error returned by
|
||||||
|
+// ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor.Validate
|
||||||
|
+// if the designated constraints aren't met.
|
||||||
|
+type ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError struct {
|
||||||
|
+ field string
|
||||||
|
+ reason string
|
||||||
|
+ cause error
|
||||||
|
+ key bool
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Field function returns field value.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError) Field() string {
|
||||||
|
+ return e.field
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Reason function returns reason value.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError) Reason() string {
|
||||||
|
+ return e.reason
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Cause function returns cause value.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError) Cause() error {
|
||||||
|
+ return e.cause
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Key function returns key value.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError) Key() bool {
|
||||||
|
+ return e.key
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// ErrorName returns error name.
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError) ErrorName() string {
|
||||||
|
+ return "ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Error satisfies the builtin error interface
|
||||||
|
+func (e ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError) Error() string {
|
||||||
|
+ cause := ""
|
||||||
|
+ if e.cause != nil {
|
||||||
|
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ key := ""
|
||||||
|
+ if e.key {
|
||||||
|
+ key = "key for "
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return fmt.Sprintf(
|
||||||
|
+ "invalid %sScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor.%s: %s%s",
|
||||||
|
+ key,
|
||||||
|
+ e.field,
|
||||||
|
+ e.reason,
|
||||||
|
+ cause)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+var _ error = ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError{}
|
||||||
|
+
|
||||||
|
+var _ interface {
|
||||||
|
+ Field() string
|
||||||
|
+ Reason() string
|
||||||
|
+ Key() bool
|
||||||
|
+ Cause() error
|
||||||
|
+ ErrorName() string
|
||||||
|
+} = ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractorValidationError{}
|
||||||
|
+
|
||||||
|
+// Validate checks the field values on
|
||||||
|
// ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement
|
||||||
|
// with the rules defined in the proto definition for this message. If any
|
||||||
|
// rules are violated, an error is returned.
|
||||||
3
go.mod
3
go.mod
@@ -238,6 +238,8 @@ require (
|
|||||||
github.com/spf13/cast v1.3.1 // indirect
|
github.com/spf13/cast v1.3.1 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||||
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
github.com/tonistiigi/fsutil v0.0.0-20220930225714-4638ad635be5 // indirect
|
github.com/tonistiigi/fsutil v0.0.0-20220930225714-4638ad635be5 // indirect
|
||||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||||
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect
|
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect
|
||||||
@@ -302,6 +304,7 @@ require (
|
|||||||
github.com/evanphx/json-patch/v5 v5.6.0
|
github.com/evanphx/json-patch/v5 v5.6.0
|
||||||
github.com/google/yamlfmt v0.10.0
|
github.com/google/yamlfmt v0.10.0
|
||||||
github.com/kylelemons/godebug v1.1.0
|
github.com/kylelemons/godebug v1.1.0
|
||||||
|
github.com/tidwall/gjson v1.17.0
|
||||||
helm.sh/helm/v3 v3.7.1
|
helm.sh/helm/v3 v3.7.1
|
||||||
k8s.io/apiextensions-apiserver v0.25.4
|
k8s.io/apiextensions-apiserver v0.25.4
|
||||||
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165
|
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165
|
||||||
|
|||||||
6
go.sum
6
go.sum
@@ -1582,6 +1582,12 @@ github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIU
|
|||||||
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
|
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
|
||||||
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
|
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
|
||||||
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
|
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
|
||||||
|
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
|
||||||
|
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
appVersion: 1.3.2
|
appVersion: 1.3.3
|
||||||
description: Helm chart for deploying higress gateways
|
description: Helm chart for deploying higress gateways
|
||||||
icon: https://higress.io/img/higress_logo_small.png
|
icon: https://higress.io/img/higress_logo_small.png
|
||||||
home: http://higress.io/
|
home: http://higress.io/
|
||||||
@@ -10,4 +10,4 @@ name: higress-core
|
|||||||
sources:
|
sources:
|
||||||
- http://github.com/alibaba/higress
|
- http://github.com/alibaba/higress
|
||||||
type: application
|
type: application
|
||||||
version: 1.3.2
|
version: 1.3.3
|
||||||
|
|||||||
@@ -70,6 +70,12 @@ spec:
|
|||||||
periodSeconds: 3
|
periodSeconds: 3
|
||||||
timeoutSeconds: 5
|
timeoutSeconds: 5
|
||||||
env:
|
env:
|
||||||
|
- name: ENBALE_SCOPED_RDS
|
||||||
|
value: "{{ .Values.global.enableSRDS }}"
|
||||||
|
- name: ON_DEMAND_RDS
|
||||||
|
value: "{{ .Values.global.onDemandRDS }}"
|
||||||
|
- name: HOST_RDS_MERGE_SUBSET
|
||||||
|
value: "{{ .Values.global.hostRDSMergeSubset }}"
|
||||||
- name: PILOT_FILTER_GATEWAY_CLUSTER_CONFIG
|
- name: PILOT_FILTER_GATEWAY_CLUSTER_CONFIG
|
||||||
value: "{{ .Values.global.onlyPushRouteCluster }}"
|
value: "{{ .Values.global.onlyPushRouteCluster }}"
|
||||||
- name: HIGRESS_CONTROLLER_SVC
|
- name: HIGRESS_CONTROLLER_SVC
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
revision: ""
|
revision: ""
|
||||||
global:
|
global:
|
||||||
|
enableSRDS: false
|
||||||
|
onDemandRDS: true
|
||||||
|
hostRDSMergeSubset: true
|
||||||
onlyPushRouteCluster: true
|
onlyPushRouteCluster: true
|
||||||
# IngressClass filters which ingress resources the higress controller watches.
|
# IngressClass filters which ingress resources the higress controller watches.
|
||||||
# The default ingress class is higress.
|
# The default ingress class is higress.
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
- name: higress-core
|
- name: higress-core
|
||||||
repository: file://../core
|
repository: file://../core
|
||||||
version: 1.3.2
|
version: 1.3.3
|
||||||
- name: higress-console
|
- name: higress-console
|
||||||
repository: https://higress.io/helm-charts/
|
repository: https://higress.io/helm-charts/
|
||||||
version: 1.3.1
|
version: 1.3.1
|
||||||
digest: sha256:cf9b5f572f8e47348b3081a5620ad0165b400e4823a4ed36bd0597f3c794cbf3
|
digest: sha256:585666df5da403450c5e586a71388bc0d029354b1100b20a50616f56711fa171
|
||||||
generated: "2023-12-20T19:57:57.037118+08:00"
|
generated: "2024-01-08T21:40:10.446936+08:00"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
appVersion: 1.3.2
|
appVersion: 1.3.3
|
||||||
description: Helm chart for deploying Higress gateways
|
description: Helm chart for deploying Higress gateways
|
||||||
icon: https://higress.io/img/higress_logo_small.png
|
icon: https://higress.io/img/higress_logo_small.png
|
||||||
home: http://higress.io/
|
home: http://higress.io/
|
||||||
@@ -12,9 +12,9 @@ sources:
|
|||||||
dependencies:
|
dependencies:
|
||||||
- name: higress-core
|
- name: higress-core
|
||||||
repository: "file://../core"
|
repository: "file://../core"
|
||||||
version: 1.3.2
|
version: 1.3.3
|
||||||
- name: higress-console
|
- name: higress-console
|
||||||
repository: "https://higress.io/helm-charts/"
|
repository: "https://higress.io/helm-charts/"
|
||||||
version: 1.3.1
|
version: 1.3.1
|
||||||
type: application
|
type: application
|
||||||
version: 1.3.2
|
version: 1.3.3
|
||||||
|
|||||||
633
istio/1.12/patches/istio/20240104-enhance-srds.patch
Normal file
633
istio/1.12/patches/istio/20240104-enhance-srds.patch
Normal file
@@ -0,0 +1,633 @@
|
|||||||
|
diff -Naur istio/pilot/pkg/features/pilot.go istio-new/pilot/pkg/features/pilot.go
|
||||||
|
--- istio/pilot/pkg/features/pilot.go 2024-01-05 17:58:08.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/features/pilot.go 2024-01-04 21:20:00.000000000 +0800
|
||||||
|
@@ -569,6 +569,12 @@
|
||||||
|
// Added by ingress
|
||||||
|
CustomCACertConfigMapName = env.RegisterStringVar("CUSTOM_CA_CERT_NAME", "",
|
||||||
|
"Defines the configmap's name of istio's root ca certificate").Get()
|
||||||
|
+ HostRDSMergeSubset = env.RegisterBoolVar("HOST_RDS_MERGE_SUBSET", true,
|
||||||
|
+ "If enabled, if host A is a subset of B, then we merge B's routes into A's hostRDS").Get()
|
||||||
|
+ EnableScopedRDS = env.RegisterBoolVar("ENBALE_SCOPED_RDS", true,
|
||||||
|
+ "If enabled, each host in virtualservice will have an independent RDS, which is used with SRDS").Get()
|
||||||
|
+ OnDemandRDS = env.RegisterBoolVar("ON_DEMAND_RDS", false,
|
||||||
|
+ "If enabled, the on demand filter will be added to the HCM filters").Get()
|
||||||
|
// End added by ingress
|
||||||
|
)
|
||||||
|
|
||||||
|
diff -Naur istio/pilot/pkg/networking/core/configgen.go istio-new/pilot/pkg/networking/core/configgen.go
|
||||||
|
--- istio/pilot/pkg/networking/core/configgen.go 2024-01-05 17:58:02.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/networking/core/configgen.go 2024-01-04 21:20:00.000000000 +0800
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
import (
|
||||||
|
core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
||||||
|
listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||||
|
+ route "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
|
||||||
|
discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
|
||||||
|
|
||||||
|
meshconfig "istio.io/api/mesh/v1alpha1"
|
||||||
|
@@ -44,6 +45,10 @@
|
||||||
|
// BuildHTTPRoutes returns the list of HTTP routes for the given proxy. This is the RDS output
|
||||||
|
BuildHTTPRoutes(node *model.Proxy, req *model.PushRequest, routeNames []string) ([]*discovery.Resource, model.XdsLogDetails)
|
||||||
|
|
||||||
|
+ // Added by ingress
|
||||||
|
+ BuildScopedRoutes(node *model.Proxy, push *model.PushContext) []*route.ScopedRouteConfiguration
|
||||||
|
+ // End added by ingress
|
||||||
|
+
|
||||||
|
// BuildNameTable returns list of hostnames and the associated IPs
|
||||||
|
BuildNameTable(node *model.Proxy, push *model.PushContext) *dnsProto.NameTable
|
||||||
|
|
||||||
|
diff -Naur istio/pilot/pkg/networking/core/v1alpha3/gateway.go istio-new/pilot/pkg/networking/core/v1alpha3/gateway.go
|
||||||
|
--- istio/pilot/pkg/networking/core/v1alpha3/gateway.go 2024-01-05 17:58:07.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/networking/core/v1alpha3/gateway.go 2024-01-05 11:19:54.000000000 +0800
|
||||||
|
@@ -41,7 +41,9 @@
|
||||||
|
"istio.io/istio/pilot/pkg/networking/plugin"
|
||||||
|
"istio.io/istio/pilot/pkg/networking/util"
|
||||||
|
authn_model "istio.io/istio/pilot/pkg/security/model"
|
||||||
|
+ "istio.io/istio/pilot/pkg/util/sets"
|
||||||
|
"istio.io/istio/pkg/config"
|
||||||
|
+ "istio.io/istio/pkg/config/constants"
|
||||||
|
"istio.io/istio/pkg/config/gateway"
|
||||||
|
"istio.io/istio/pkg/config/host"
|
||||||
|
"istio.io/istio/pkg/config/protocol"
|
||||||
|
@@ -104,10 +106,15 @@
|
||||||
|
// We can also have QUIC on a given port along with HTTPS/TLS on a given port. It does not
|
||||||
|
// cause port-conflict as they use different transport protocols
|
||||||
|
opts := &buildListenerOpts{
|
||||||
|
- push: builder.push,
|
||||||
|
- proxy: builder.node,
|
||||||
|
- bind: bind,
|
||||||
|
- port: &model.Port{Port: int(port.Number)},
|
||||||
|
+ push: builder.push,
|
||||||
|
+ proxy: builder.node,
|
||||||
|
+ bind: bind,
|
||||||
|
+ port: &model.Port{
|
||||||
|
+ Port: int(port.Number),
|
||||||
|
+ // Added by ingress
|
||||||
|
+ Protocol: protocol.Parse(port.Protocol),
|
||||||
|
+ // End added by ingress
|
||||||
|
+ },
|
||||||
|
bindToPort: true,
|
||||||
|
class: istionetworking.ListenerClassGateway,
|
||||||
|
transport: transport,
|
||||||
|
@@ -340,6 +347,269 @@
|
||||||
|
return nameToServiceMap
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Added by ingress
|
||||||
|
+func (configgen *ConfigGeneratorImpl) BuildScopedRoutes(node *model.Proxy, push *model.PushContext) []*route.ScopedRouteConfiguration {
|
||||||
|
+ if node.MergedGateway == nil {
|
||||||
|
+ log.Warnf("buildScopedRoutes: no gateways for router %v", node.ID)
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+ merged := node.MergedGateway
|
||||||
|
+ var out []*route.ScopedRouteConfiguration
|
||||||
|
+ gatewayVirtualServices := make(map[string][]config.Config)
|
||||||
|
+ serverIterator := func(listenerPort int, mergedServers map[model.ServerPort]*model.MergedServers) sets.Set {
|
||||||
|
+ hostSet := sets.NewSet()
|
||||||
|
+ for port, servers := range mergedServers {
|
||||||
|
+ if port.Number != uint32(listenerPort) {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ for _, server := range servers.Servers {
|
||||||
|
+ gatewayName := merged.GatewayNameForServer[server]
|
||||||
|
+
|
||||||
|
+ var virtualServices []config.Config
|
||||||
|
+ var exists bool
|
||||||
|
+
|
||||||
|
+ if virtualServices, exists = gatewayVirtualServices[gatewayName]; !exists {
|
||||||
|
+ virtualServices = push.VirtualServicesForGateway(node, gatewayName)
|
||||||
|
+ gatewayVirtualServices[gatewayName] = virtualServices
|
||||||
|
+ }
|
||||||
|
+ for _, virtualService := range virtualServices {
|
||||||
|
+ for _, host := range virtualService.Spec.(*networking.VirtualService).Hosts {
|
||||||
|
+ hostSet.Insert(host)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return hostSet
|
||||||
|
+ }
|
||||||
|
+ buildPortHostScopedRoute := func(listenerPort model.ServerPort) {
|
||||||
|
+ p := protocol.Parse(listenerPort.Protocol)
|
||||||
|
+ if !p.IsHTTP() && p != protocol.HTTPS {
|
||||||
|
+ return
|
||||||
|
+ }
|
||||||
|
+ port := strconv.Itoa(int(listenerPort.Number))
|
||||||
|
+ hostSet := serverIterator(int(listenerPort.Number), merged.MergedServers).
|
||||||
|
+ Union(serverIterator(int(listenerPort.Number), merged.MergedQUICTransportServers))
|
||||||
|
+ for host, _ := range hostSet {
|
||||||
|
+ portKey := &route.ScopedRouteConfiguration_Key_Fragment{
|
||||||
|
+ Type: &route.ScopedRouteConfiguration_Key_Fragment_StringKey{
|
||||||
|
+ StringKey: port,
|
||||||
|
+ },
|
||||||
|
+ }
|
||||||
|
+ hostKey := &route.ScopedRouteConfiguration_Key_Fragment{
|
||||||
|
+ Type: &route.ScopedRouteConfiguration_Key_Fragment_StringKey{
|
||||||
|
+ StringKey: host,
|
||||||
|
+ },
|
||||||
|
+ }
|
||||||
|
+ name := strings.Join([]string{port, host}, ".")
|
||||||
|
+ out = append(out, &route.ScopedRouteConfiguration{
|
||||||
|
+ OnDemand: features.OnDemandRDS,
|
||||||
|
+ Name: name,
|
||||||
|
+ RouteConfigurationName: constants.HigressHostRDSNamePrefix + name,
|
||||||
|
+ Key: &route.ScopedRouteConfiguration_Key{
|
||||||
|
+ Fragments: []*route.ScopedRouteConfiguration_Key_Fragment{portKey, hostKey},
|
||||||
|
+ },
|
||||||
|
+ })
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ for _, port := range merged.ServerPorts {
|
||||||
|
+ buildPortHostScopedRoute(port)
|
||||||
|
+ }
|
||||||
|
+ return out
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+type virtualServiceContext struct {
|
||||||
|
+ virtualService config.Config
|
||||||
|
+ server *networking.Server
|
||||||
|
+ gatewayName string
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (configgen *ConfigGeneratorImpl) buildHostRDSConfig(node *model.Proxy, push *model.PushContext,
|
||||||
|
+ routeName string) *route.RouteConfiguration {
|
||||||
|
+ var (
|
||||||
|
+ hostRDSPort string
|
||||||
|
+ hostRDSHost string
|
||||||
|
+ )
|
||||||
|
+ portAndHost := strings.SplitN(strings.TrimPrefix(routeName, constants.HigressHostRDSNamePrefix), ".", 2)
|
||||||
|
+ if len(portAndHost) != 2 {
|
||||||
|
+ log.Errorf("Invalid route %s when using Higress hostRDS", routeName)
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+ hostRDSPort = portAndHost[0]
|
||||||
|
+ hostRDSHost = portAndHost[1]
|
||||||
|
+ merged := node.MergedGateway
|
||||||
|
+ log.Debugf("buildGatewayRoutes: gateways after merging: %v", merged)
|
||||||
|
+ rdsPort, err := strconv.Atoi(hostRDSPort)
|
||||||
|
+ if err != nil {
|
||||||
|
+ log.Errorf("Invalid port %s of route %s when using Higress hostRDS", hostRDSPort, routeName)
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+ listenerPort := uint32(rdsPort)
|
||||||
|
+ globalHTTPFilters := mseingress.ExtractGlobalHTTPFilters(node, push)
|
||||||
|
+
|
||||||
|
+ isH3DiscoveryNeeded := false
|
||||||
|
+
|
||||||
|
+ // When this is true, we add alt-svc header to the response to tell the client
|
||||||
|
+ // that HTTP/3 over QUIC is available on the same port for this host. This is
|
||||||
|
+ // very important for discovering HTTP/3 services
|
||||||
|
+ for port, servers := range merged.MergedQUICTransportServers {
|
||||||
|
+ if port.Number == listenerPort && len(servers.Servers) > 0 {
|
||||||
|
+ isH3DiscoveryNeeded = true
|
||||||
|
+ break
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ gatewayRoutes := make(map[string]map[string][]*route.Route)
|
||||||
|
+ gatewayVirtualServices := make(map[string][]config.Config)
|
||||||
|
+ var selectedVirtualServices []virtualServiceContext
|
||||||
|
+ var vHost *route.VirtualHost
|
||||||
|
+ serverIterator := func(mergedServers map[model.ServerPort]*model.MergedServers) {
|
||||||
|
+ for port, servers := range mergedServers {
|
||||||
|
+ if port.Number != listenerPort {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ for _, server := range servers.Servers {
|
||||||
|
+ gatewayName := merged.GatewayNameForServer[server]
|
||||||
|
+
|
||||||
|
+ var virtualServices []config.Config
|
||||||
|
+ var exists bool
|
||||||
|
+
|
||||||
|
+ if virtualServices, exists = gatewayVirtualServices[gatewayName]; !exists {
|
||||||
|
+ virtualServices = push.VirtualServicesForGateway(node, gatewayName)
|
||||||
|
+ gatewayVirtualServices[gatewayName] = virtualServices
|
||||||
|
+ }
|
||||||
|
+ for _, virtualService := range virtualServices {
|
||||||
|
+ hostMatch := false
|
||||||
|
+ var selectHost string
|
||||||
|
+ virtualServiceHosts := host.NewNames(virtualService.Spec.(*networking.VirtualService).Hosts)
|
||||||
|
+ for _, hostname := range virtualServiceHosts {
|
||||||
|
+ // exact match
|
||||||
|
+ if hostname == host.Name(hostRDSHost) {
|
||||||
|
+ hostMatch = true
|
||||||
|
+ selectHost = hostRDSHost
|
||||||
|
+ break
|
||||||
|
+ }
|
||||||
|
+ if features.HostRDSMergeSubset {
|
||||||
|
+ // subset match
|
||||||
|
+ if host.Name(hostRDSHost).SubsetOf(hostname) {
|
||||||
|
+ hostMatch = true
|
||||||
|
+ selectHost = string(hostname)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if !hostMatch {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ copiedVS := virtualService.DeepCopy()
|
||||||
|
+ copiedVS.Spec.(*networking.VirtualService).Hosts = []string{selectHost}
|
||||||
|
+ selectedVirtualServices = append(selectedVirtualServices, virtualServiceContext{
|
||||||
|
+ virtualService: copiedVS,
|
||||||
|
+ server: server,
|
||||||
|
+ gatewayName: gatewayName,
|
||||||
|
+ })
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ serverIterator(merged.MergedServers)
|
||||||
|
+ serverIterator(merged.MergedQUICTransportServers)
|
||||||
|
+ // Sort by subset
|
||||||
|
+ // before: ["*.abc.com", "*.com", "www.abc.com"]
|
||||||
|
+ // after: ["www.abc.com", "*.abc.com", "*.com"]
|
||||||
|
+ sort.SliceStable(selectedVirtualServices, func(i, j int) bool {
|
||||||
|
+ return host.Name(selectedVirtualServices[i].virtualService.Spec.(*networking.VirtualService).Hosts[0]).SubsetOf(
|
||||||
|
+ host.Name(selectedVirtualServices[j].virtualService.Spec.(*networking.VirtualService).Hosts[0]))
|
||||||
|
+ })
|
||||||
|
+ port := int(listenerPort)
|
||||||
|
+ for _, ctx := range selectedVirtualServices {
|
||||||
|
+ virtualService := ctx.virtualService
|
||||||
|
+ server := ctx.server
|
||||||
|
+ gatewayName := ctx.gatewayName
|
||||||
|
+ // Make sure we can obtain services which are visible to this virtualService as much as possible.
|
||||||
|
+ nameToServiceMap := buildNameToServiceMapForHTTPRoutes(node, push, virtualService)
|
||||||
|
+
|
||||||
|
+ var routes []*route.Route
|
||||||
|
+ var exists bool
|
||||||
|
+ var err error
|
||||||
|
+ if _, exists = gatewayRoutes[gatewayName]; !exists {
|
||||||
|
+ gatewayRoutes[gatewayName] = make(map[string][]*route.Route)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ vskey := virtualService.Name + "/" + virtualService.Namespace
|
||||||
|
+
|
||||||
|
+ if routes, exists = gatewayRoutes[gatewayName][vskey]; !exists {
|
||||||
|
+ hashByDestination := istio_route.GetConsistentHashForVirtualService(push, node, virtualService, nameToServiceMap)
|
||||||
|
+ routes, err = istio_route.BuildHTTPRoutesForVirtualServiceWithHTTPFilters(node, virtualService, nameToServiceMap,
|
||||||
|
+ hashByDestination, port, map[string]bool{gatewayName: true}, isH3DiscoveryNeeded, push.Mesh, globalHTTPFilters)
|
||||||
|
+ if err != nil {
|
||||||
|
+ log.Debugf("%s omitting routes for virtual service %v/%v due to error: %v", node.ID, virtualService.Namespace, virtualService.Name, err)
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ gatewayRoutes[gatewayName][vskey] = routes
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if vHost != nil {
|
||||||
|
+ vHost.Routes = append(vHost.Routes, routes...)
|
||||||
|
+ if server.Tls != nil && server.Tls.HttpsRedirect {
|
||||||
|
+ vHost.RequireTls = route.VirtualHost_ALL
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ vHost = &route.VirtualHost{
|
||||||
|
+ Name: util.DomainName(hostRDSHost, port),
|
||||||
|
+ Domains: buildGatewayVirtualHostDomains(hostRDSHost, port),
|
||||||
|
+ Routes: routes,
|
||||||
|
+ IncludeRequestAttemptCount: true,
|
||||||
|
+ TypedPerFilterConfig: mseingress.ConstructTypedPerFilterConfigForVHost(globalHTTPFilters, virtualService),
|
||||||
|
+ }
|
||||||
|
+ if server.Tls != nil && server.Tls.HttpsRedirect {
|
||||||
|
+ vHost.RequireTls = route.VirtualHost_ALL
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // check all hostname if is not exist with HttpsRedirect set to true
|
||||||
|
+ // create VirtualHost to redirect
|
||||||
|
+ for _, hostname := range server.Hosts {
|
||||||
|
+ if !server.GetTls().GetHttpsRedirect() {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ if vHost != nil && host.Name(hostname) == host.Name(hostRDSHost) {
|
||||||
|
+ vHost.RequireTls = route.VirtualHost_ALL
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ vHost = &route.VirtualHost{
|
||||||
|
+ Name: util.DomainName(hostname, port),
|
||||||
|
+ Domains: buildGatewayVirtualHostDomains(hostname, port),
|
||||||
|
+ IncludeRequestAttemptCount: true,
|
||||||
|
+ RequireTls: route.VirtualHost_ALL,
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+ var virtualHosts []*route.VirtualHost
|
||||||
|
+ if vHost == nil {
|
||||||
|
+ log.Warnf("constructed http route config for route %s on port %d with no vhosts; Setting up a default 404 vhost", routeName, port)
|
||||||
|
+ virtualHosts = []*route.VirtualHost{{
|
||||||
|
+ Name: util.DomainName("blackhole", port),
|
||||||
|
+ Domains: []string{"*"},
|
||||||
|
+ // Empty route list will cause Envoy to 404 NR any requests
|
||||||
|
+ Routes: []*route.Route{},
|
||||||
|
+ }}
|
||||||
|
+ } else {
|
||||||
|
+ vHost.Routes = istio_route.CombineVHostRoutes(vHost.Routes)
|
||||||
|
+ virtualHosts = append(virtualHosts, vHost)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ routeCfg := &route.RouteConfiguration{
|
||||||
|
+ // Retain the routeName as its used by EnvoyFilter patching logic
|
||||||
|
+ Name: routeName,
|
||||||
|
+ VirtualHosts: virtualHosts,
|
||||||
|
+ ValidateClusters: proto.BoolFalse,
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return routeCfg
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// End added by ingress
|
||||||
|
+
|
||||||
|
func (configgen *ConfigGeneratorImpl) buildGatewayHTTPRouteConfig(node *model.Proxy, push *model.PushContext,
|
||||||
|
routeName string) *route.RouteConfiguration {
|
||||||
|
if node.MergedGateway == nil {
|
||||||
|
@@ -351,6 +621,12 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Added by ingress
|
||||||
|
+ if strings.HasPrefix(routeName, constants.HigressHostRDSNamePrefix) {
|
||||||
|
+ return configgen.buildHostRDSConfig(node, push, routeName)
|
||||||
|
+ }
|
||||||
|
+ // End added by ingress
|
||||||
|
+
|
||||||
|
merged := node.MergedGateway
|
||||||
|
log.Debugf("buildGatewayRoutes: gateways after merging: %v", merged)
|
||||||
|
|
||||||
|
@@ -670,7 +946,9 @@
|
||||||
|
// TLS mode | Mesh-wide SDS | Ingress SDS | Resulting Configuration
|
||||||
|
// SIMPLE/MUTUAL | ENABLED | ENABLED | support SDS at ingress gateway to terminate SSL communication outside the mesh
|
||||||
|
// ISTIO_MUTUAL | ENABLED | DISABLED | support SDS at gateway to terminate workload mTLS, with internal workloads
|
||||||
|
-// | for egress or with another trusted cluster for ingress)
|
||||||
|
+//
|
||||||
|
+// | for egress or with another trusted cluster for ingress)
|
||||||
|
+//
|
||||||
|
// ISTIO_MUTUAL | DISABLED | DISABLED | use file-mounted secret paths to terminate workload mTLS from gateway
|
||||||
|
//
|
||||||
|
// Note that ISTIO_MUTUAL TLS mode and ingressSds should not be used simultaneously on the same ingress gateway.
|
||||||
|
diff -Naur istio/pilot/pkg/networking/core/v1alpha3/listener.go istio-new/pilot/pkg/networking/core/v1alpha3/listener.go
|
||||||
|
--- istio/pilot/pkg/networking/core/v1alpha3/listener.go 2024-01-05 17:58:07.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/networking/core/v1alpha3/listener.go 2024-01-05 17:31:10.000000000 +0800
|
||||||
|
@@ -1279,8 +1279,48 @@
|
||||||
|
|
||||||
|
notimeout := durationpb.New(0 * time.Second)
|
||||||
|
connectionManager.StreamIdleTimeout = notimeout
|
||||||
|
-
|
||||||
|
- if httpOpts.rds != "" {
|
||||||
|
+ // Added by ingress
|
||||||
|
+ enableSRDS := false
|
||||||
|
+ if features.EnableScopedRDS &&
|
||||||
|
+ (listenerOpts.port.Protocol.IsHTTP() || (listenerOpts.port.Protocol == protocol.HTTPS)) {
|
||||||
|
+ enableSRDS = true
|
||||||
|
+ portFragment := &hcm.ScopedRoutes_ScopeKeyBuilder_FragmentBuilder{
|
||||||
|
+ Type: &hcm.ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor_{
|
||||||
|
+ LocalPortValueExtractor: &hcm.ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_LocalPortValueExtractor{},
|
||||||
|
+ }}
|
||||||
|
+ hostFragment := &hcm.ScopedRoutes_ScopeKeyBuilder_FragmentBuilder{
|
||||||
|
+ Type: &hcm.ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor_{
|
||||||
|
+ HostValueExtractor: &hcm.ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HostValueExtractor{},
|
||||||
|
+ }}
|
||||||
|
+ scopedRoutes := &hcm.HttpConnectionManager_ScopedRoutes{
|
||||||
|
+ ScopedRoutes: &hcm.ScopedRoutes{
|
||||||
|
+ Name: constants.DefaultScopedRouteName,
|
||||||
|
+ ScopeKeyBuilder: &hcm.ScopedRoutes_ScopeKeyBuilder{
|
||||||
|
+ Fragments: []*hcm.ScopedRoutes_ScopeKeyBuilder_FragmentBuilder{portFragment, hostFragment},
|
||||||
|
+ },
|
||||||
|
+ RdsConfigSource: &core.ConfigSource{
|
||||||
|
+ ConfigSourceSpecifier: &core.ConfigSource_Ads{
|
||||||
|
+ Ads: &core.AggregatedConfigSource{},
|
||||||
|
+ },
|
||||||
|
+ InitialFetchTimeout: durationpb.New(0),
|
||||||
|
+ ResourceApiVersion: core.ApiVersion_V3,
|
||||||
|
+ },
|
||||||
|
+ ConfigSpecifier: &hcm.ScopedRoutes_ScopedRds{
|
||||||
|
+ ScopedRds: &hcm.ScopedRds{
|
||||||
|
+ ScopedRdsConfigSource: &core.ConfigSource{
|
||||||
|
+ ConfigSourceSpecifier: &core.ConfigSource_Ads{
|
||||||
|
+ Ads: &core.AggregatedConfigSource{},
|
||||||
|
+ },
|
||||||
|
+ InitialFetchTimeout: durationpb.New(0),
|
||||||
|
+ ResourceApiVersion: core.ApiVersion_V3,
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ }
|
||||||
|
+ connectionManager.RouteSpecifier = scopedRoutes
|
||||||
|
+ } else if httpOpts.rds != "" {
|
||||||
|
+ // End added by ingress
|
||||||
|
rds := &hcm.HttpConnectionManager_Rds{
|
||||||
|
Rds: &hcm.Rds{
|
||||||
|
ConfigSource: &core.ConfigSource{
|
||||||
|
@@ -1304,8 +1344,15 @@
|
||||||
|
|
||||||
|
filters := make([]*hcm.HttpFilter, len(httpFilters))
|
||||||
|
copy(filters, httpFilters)
|
||||||
|
- // Make sure cors filter always in the first.
|
||||||
|
- filters = append([]*hcm.HttpFilter{xdsfilters.Cors}, filters...)
|
||||||
|
+ // Added by ingress
|
||||||
|
+ // Now only support onDemandRDS when enable SRDS
|
||||||
|
+ if features.OnDemandRDS && enableSRDS {
|
||||||
|
+ filters = append([]*hcm.HttpFilter{xdsfilters.OnDemand, xdsfilters.Cors}, filters...)
|
||||||
|
+ } else {
|
||||||
|
+ // End added by ingress
|
||||||
|
+ // Make sure cors filter always in the first.
|
||||||
|
+ filters = append([]*hcm.HttpFilter{xdsfilters.Cors}, filters...)
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if features.MetadataExchange {
|
||||||
|
filters = append(filters, xdsfilters.HTTPMx)
|
||||||
|
diff -Naur istio/pilot/pkg/xds/ads.go istio-new/pilot/pkg/xds/ads.go
|
||||||
|
--- istio/pilot/pkg/xds/ads.go 2024-01-05 17:58:08.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/xds/ads.go 2024-01-05 17:31:44.000000000 +0800
|
||||||
|
@@ -797,15 +797,18 @@
|
||||||
|
|
||||||
|
// PushOrder defines the order that updates will be pushed in. Any types not listed here will be pushed in random
|
||||||
|
// order after the types listed here
|
||||||
|
-var PushOrder = []string{v3.ClusterType, v3.EndpointType, v3.ListenerType, v3.RouteType, v3.SecretType}
|
||||||
|
+var PushOrder = []string{v3.ClusterType, v3.EndpointType, v3.ListenerType, v3.ScopedRouteType, v3.RouteType, v3.SecretType}
|
||||||
|
|
||||||
|
// KnownOrderedTypeUrls has typeUrls for which we know the order of push.
|
||||||
|
var KnownOrderedTypeUrls = map[string]struct{}{
|
||||||
|
v3.ClusterType: {},
|
||||||
|
v3.EndpointType: {},
|
||||||
|
v3.ListenerType: {},
|
||||||
|
- v3.RouteType: {},
|
||||||
|
- v3.SecretType: {},
|
||||||
|
+ // Added by ingress
|
||||||
|
+ v3.ScopedRouteType: {},
|
||||||
|
+ // End added by ingress
|
||||||
|
+ v3.RouteType: {},
|
||||||
|
+ v3.SecretType: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// orderWatchedResources orders the resources in accordance with known push order.
|
||||||
|
diff -Naur istio/pilot/pkg/xds/discovery.go istio-new/pilot/pkg/xds/discovery.go
|
||||||
|
--- istio/pilot/pkg/xds/discovery.go 2024-01-05 17:58:07.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/xds/discovery.go 2024-01-04 21:20:00.000000000 +0800
|
||||||
|
@@ -589,6 +589,9 @@
|
||||||
|
s.Generators[v3.ClusterType] = &CdsGenerator{Server: s}
|
||||||
|
s.Generators[v3.ListenerType] = &LdsGenerator{Server: s}
|
||||||
|
s.Generators[v3.RouteType] = &RdsGenerator{Server: s}
|
||||||
|
+ // Added by ingress
|
||||||
|
+ s.Generators[v3.ScopedRouteType] = &SrdsGenerator{Server: s}
|
||||||
|
+ // End added by ingress
|
||||||
|
s.Generators[v3.EndpointType] = edsGen
|
||||||
|
s.Generators[v3.NameTableType] = &NdsGenerator{Server: s}
|
||||||
|
s.Generators[v3.ExtensionConfigurationType] = &EcdsGenerator{Server: s}
|
||||||
|
diff -Naur istio/pilot/pkg/xds/filters/filters.go istio-new/pilot/pkg/xds/filters/filters.go
|
||||||
|
--- istio/pilot/pkg/xds/filters/filters.go 2024-01-05 17:58:03.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/xds/filters/filters.go 2024-01-04 21:20:00.000000000 +0800
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
fault "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/fault/v3"
|
||||||
|
grpcstats "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/grpc_stats/v3"
|
||||||
|
grpcweb "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/grpc_web/v3"
|
||||||
|
+ ondemand "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/on_demand/v3"
|
||||||
|
router "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3"
|
||||||
|
httpwasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3"
|
||||||
|
httpinspector "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/http_inspector/v3"
|
||||||
|
@@ -54,6 +55,14 @@
|
||||||
|
// Define static filters to be reused across the codebase. This avoids duplicate marshaling/unmarshaling
|
||||||
|
// This should not be used for filters that will be mutated
|
||||||
|
var (
|
||||||
|
+ // Added by ingress
|
||||||
|
+ OnDemand = &hcm.HttpFilter{
|
||||||
|
+ Name: "envoy.filters.http.on_demand.v3.OnDemand",
|
||||||
|
+ ConfigType: &hcm.HttpFilter_TypedConfig{
|
||||||
|
+ TypedConfig: util.MessageToAny(&ondemand.OnDemand{}),
|
||||||
|
+ },
|
||||||
|
+ }
|
||||||
|
+ // End added by ingress
|
||||||
|
Cors = &hcm.HttpFilter{
|
||||||
|
Name: wellknown.CORS,
|
||||||
|
ConfigType: &hcm.HttpFilter_TypedConfig{
|
||||||
|
diff -Naur istio/pilot/pkg/xds/srds.go istio-new/pilot/pkg/xds/srds.go
|
||||||
|
--- istio/pilot/pkg/xds/srds.go 1970-01-01 08:00:00.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/xds/srds.go 2024-01-05 13:45:49.000000000 +0800
|
||||||
|
@@ -0,0 +1,79 @@
|
||||||
|
+// Copyright Istio Authors
|
||||||
|
+//
|
||||||
|
+// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
+// you may not use this file except in compliance with the License.
|
||||||
|
+// You may obtain a copy of the License at
|
||||||
|
+//
|
||||||
|
+// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
+//
|
||||||
|
+// Unless required by applicable law or agreed to in writing, software
|
||||||
|
+// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
+// See the License for the specific language governing permissions and
|
||||||
|
+// limitations under the License.
|
||||||
|
+
|
||||||
|
+package xds
|
||||||
|
+
|
||||||
|
+import (
|
||||||
|
+ discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
|
||||||
|
+ "istio.io/istio/pilot/pkg/features"
|
||||||
|
+ "istio.io/istio/pilot/pkg/model"
|
||||||
|
+ "istio.io/istio/pilot/pkg/networking/util"
|
||||||
|
+ "istio.io/istio/pkg/config"
|
||||||
|
+ "istio.io/istio/pkg/config/schema/gvk"
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+type SrdsGenerator struct {
|
||||||
|
+ Server *DiscoveryServer
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+var _ model.XdsResourceGenerator = &SrdsGenerator{}
|
||||||
|
+
|
||||||
|
+// Map of all configs that do not impact SRDS
|
||||||
|
+var skippedSrdsConfigs = map[config.GroupVersionKind]struct{}{
|
||||||
|
+ gvk.WorkloadEntry: {},
|
||||||
|
+ gvk.WorkloadGroup: {},
|
||||||
|
+ gvk.RequestAuthentication: {},
|
||||||
|
+ gvk.PeerAuthentication: {},
|
||||||
|
+ gvk.Secret: {},
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func srdsNeedsPush(req *model.PushRequest) bool {
|
||||||
|
+ if !features.EnableScopedRDS {
|
||||||
|
+ return false
|
||||||
|
+ }
|
||||||
|
+ if req == nil {
|
||||||
|
+ return true
|
||||||
|
+ }
|
||||||
|
+ if !req.Full {
|
||||||
|
+ // SRDS only handles full push
|
||||||
|
+ return false
|
||||||
|
+ }
|
||||||
|
+ // If none set, we will always push
|
||||||
|
+ if len(req.ConfigsUpdated) == 0 {
|
||||||
|
+ return true
|
||||||
|
+ }
|
||||||
|
+ for config := range req.ConfigsUpdated {
|
||||||
|
+ if _, f := skippedSrdsConfigs[config.Kind]; !f {
|
||||||
|
+ return true
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return false
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (s SrdsGenerator) Generate(proxy *model.Proxy, push *model.PushContext, w *model.WatchedResource,
|
||||||
|
+ req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
|
||||||
|
+ if !srdsNeedsPush(req) {
|
||||||
|
+ return nil, model.DefaultXdsLogDetails, nil
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ scopedRoutes := s.Server.ConfigGenerator.BuildScopedRoutes(proxy, push)
|
||||||
|
+ resources := model.Resources{}
|
||||||
|
+ for _, sr := range scopedRoutes {
|
||||||
|
+ resources = append(resources, &discovery.Resource{
|
||||||
|
+ Name: sr.Name,
|
||||||
|
+ Resource: util.MessageToAny(sr),
|
||||||
|
+ })
|
||||||
|
+ }
|
||||||
|
+ return resources, model.DefaultXdsLogDetails, nil
|
||||||
|
+}
|
||||||
|
diff -Naur istio/pilot/pkg/xds/v3/model.go istio-new/pilot/pkg/xds/v3/model.go
|
||||||
|
--- istio/pilot/pkg/xds/v3/model.go 2024-01-05 17:58:03.000000000 +0800
|
||||||
|
+++ istio-new/pilot/pkg/xds/v3/model.go 2024-01-05 16:55:49.000000000 +0800
|
||||||
|
@@ -31,6 +31,10 @@
|
||||||
|
SecretType = resource.SecretType
|
||||||
|
ExtensionConfigurationType = resource.ExtensionConfigType
|
||||||
|
|
||||||
|
+ // Added by ingress
|
||||||
|
+ ScopedRouteType = apiTypePrefix + "envoy.config.route.v3.ScopedRouteConfiguration"
|
||||||
|
+ // End added by ingress
|
||||||
|
+
|
||||||
|
NameTableType = apiTypePrefix + "istio.networking.nds.v1.NameTable"
|
||||||
|
HealthInfoType = apiTypePrefix + "istio.v1.HealthInformation"
|
||||||
|
ProxyConfigType = apiTypePrefix + "istio.mesh.v1alpha1.ProxyConfig"
|
||||||
|
@@ -61,6 +65,10 @@
|
||||||
|
return "PCDS"
|
||||||
|
case ExtensionConfigurationType:
|
||||||
|
return "ECDS"
|
||||||
|
+ // Added by ingress
|
||||||
|
+ case ScopedRouteType:
|
||||||
|
+ return "SRDS"
|
||||||
|
+ // End added by ingress
|
||||||
|
default:
|
||||||
|
return typeURL
|
||||||
|
}
|
||||||
|
@@ -87,6 +95,10 @@
|
||||||
|
return "ecds"
|
||||||
|
case BootstrapType:
|
||||||
|
return "bds"
|
||||||
|
+ // Added by ingress
|
||||||
|
+ case ScopedRouteType:
|
||||||
|
+ return "srds"
|
||||||
|
+ // End added by ingress
|
||||||
|
default:
|
||||||
|
return typeURL
|
||||||
|
}
|
||||||
|
diff -Naur istio/pkg/config/constants/constants.go istio-new/pkg/config/constants/constants.go
|
||||||
|
--- istio/pkg/config/constants/constants.go 2024-01-05 17:58:08.000000000 +0800
|
||||||
|
+++ istio-new/pkg/config/constants/constants.go 2024-01-04 21:20:00.000000000 +0800
|
||||||
|
@@ -143,4 +143,9 @@
|
||||||
|
// CertProviderNone does not create any certificates for the control plane. It is assumed that some external
|
||||||
|
// load balancer, such as an Istio Gateway, is terminating the TLS.
|
||||||
|
CertProviderNone = "none"
|
||||||
|
+
|
||||||
|
+ // Added by ingress
|
||||||
|
+ HigressHostRDSNamePrefix = "higress-rds-"
|
||||||
|
+ DefaultScopedRouteName = "scoped-route"
|
||||||
|
+ // End added by ingress
|
||||||
|
)
|
||||||
338
pkg/cmd/hgctl/code_debug.go
Normal file
338
pkg/cmd/hgctl/code_debug.go
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package hgctl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/pkg/cmd/hgctl/helm"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultIp = "127.0.0.1"
|
||||||
|
DefaultPort = ":15051"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newCodeDebugCmd() *cobra.Command {
|
||||||
|
codeDebugCmd := &cobra.Command{
|
||||||
|
Use: "code-debug",
|
||||||
|
Short: "Start or stop code debug",
|
||||||
|
}
|
||||||
|
|
||||||
|
codeDebugCmd.AddCommand(getStartCodeDebugCmd())
|
||||||
|
codeDebugCmd.AddCommand(getStopCodeDebugCmd())
|
||||||
|
|
||||||
|
return codeDebugCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStartCodeDebugCmd() *cobra.Command {
|
||||||
|
homeDir, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("fail to get user home dir: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
kubeConfigDir := homeDir + "/.kube/config"
|
||||||
|
|
||||||
|
startCodeDebugCmd := &cobra.Command{
|
||||||
|
Use: "start",
|
||||||
|
Aliases: []string{"start"},
|
||||||
|
Short: "Start code debug",
|
||||||
|
Example: "hgctl code-debug start",
|
||||||
|
RunE: func(c *cobra.Command, args []string) error {
|
||||||
|
writer := c.OutOrStdout()
|
||||||
|
|
||||||
|
// wait for user to confirm
|
||||||
|
if !promptCodeDebug(writer, "local grpc address") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// check profile type is local or not
|
||||||
|
fmt.Fprintf(writer, "Checking profile type...\n")
|
||||||
|
profiles, err := getAllProfiles()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("fail to get all profiles: %v", err)
|
||||||
|
}
|
||||||
|
if len(profiles) == 0 {
|
||||||
|
fmt.Fprintf(writer, "Higress hasn't been installed yet!\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, profile := range profiles {
|
||||||
|
if profile.Install != helm.InstallLocalK8s {
|
||||||
|
fmt.Fprintf(writer, "\nHigress needs to be installed locally!\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get kubernetes clientSet
|
||||||
|
fmt.Fprintf(writer, "Getting kubernetes clientset...\n")
|
||||||
|
config, err := clientcmd.BuildConfigFromFlags("", kubeConfigDir)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(writer, "fail to build config from kubeconfig: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
clientSet, err := kubernetes.NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(writer, "fail to create kubernetes clientset: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// get non-loopback IPv4 address
|
||||||
|
fmt.Fprintf(writer, "Getting non-loopback IPv4 address...\n")
|
||||||
|
ip, err := getNonLoopbackIPv4()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(writer, "fail to get non-loopback IPv4 address: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the xds address in higress-config ConfigMap
|
||||||
|
// and trigger rollout for higress-controller and higress-gateway deployments
|
||||||
|
fmt.Fprintf(writer, "Updating xds address in higress-config ConfigMap "+
|
||||||
|
"and triggering rollout for higress-controller and higress-gateway deployments...\n")
|
||||||
|
err = updateXdsIpAndRollout(clientSet, ip, DefaultPort)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(writer, "fail to update xds address in higress-config ConfigMap: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(writer, "Code debug started!\n")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
startCodeDebugCmd.PersistentFlags().StringVar(&kubeConfigDir, "kubeconfig", kubeConfigDir,
|
||||||
|
"Use a Kubernetes configuration file instead of in-cluster configuration")
|
||||||
|
|
||||||
|
return startCodeDebugCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStopCodeDebugCmd() *cobra.Command {
|
||||||
|
homeDir, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("fail to get user home dir: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
kubeConfigDir := homeDir + "/.kube/config"
|
||||||
|
|
||||||
|
stopCodeDebugCmd := &cobra.Command{
|
||||||
|
Use: "stop",
|
||||||
|
Aliases: []string{"stop"},
|
||||||
|
Short: "Stop code debug",
|
||||||
|
Example: "hgctl code-debug stop",
|
||||||
|
RunE: func(c *cobra.Command, args []string) error {
|
||||||
|
// wait for user to confirm
|
||||||
|
writer := c.OutOrStdout()
|
||||||
|
if !promptCodeDebug(writer, "default grpc address") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// check profile type is local or not
|
||||||
|
fmt.Fprintf(writer, "Checking profile type...\n")
|
||||||
|
profiles, err := getAllProfiles()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("fail to get all profiles: %v", err)
|
||||||
|
}
|
||||||
|
if len(profiles) == 0 {
|
||||||
|
fmt.Fprintf(writer, "Higress hasn't been installed yet!\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, profile := range profiles {
|
||||||
|
if profile.Install != helm.InstallLocalK8s {
|
||||||
|
fmt.Fprintf(writer, "\nHigress needs to be installed locally!\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get kubernetes clientSet
|
||||||
|
fmt.Fprintf(writer, "Getting kubernetes clientset...\n")
|
||||||
|
config, err := clientcmd.BuildConfigFromFlags("", kubeConfigDir)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(writer, "fail to build config from kubeconfig: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
clientSet, err := kubernetes.NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(writer, "fail to create kubernetes clientset: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// recover the xds address in higress-config ConfigMap
|
||||||
|
// and trigger rollout for higress-controller and higress-gateway deployments
|
||||||
|
fmt.Fprintf(writer, "Recovering xds address in higress-config ConfigMap "+
|
||||||
|
"and triggering rollout for higress-controller and higress-gateway deployments...\n")
|
||||||
|
err = updateXdsIpAndRollout(clientSet, DefaultIp, DefaultPort)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(writer, "fail to recover xds address in higress-config ConfigMap: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(writer, "Code debug stopped!\n")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
stopCodeDebugCmd.PersistentFlags().StringVar(&kubeConfigDir, "kubeconfig", kubeConfigDir,
|
||||||
|
"Use a Kubernetes configuration file instead of in-cluster configuration")
|
||||||
|
|
||||||
|
return stopCodeDebugCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// getNonLoopbackIPv4 returns the first non-loopback IPv4 address of the host.
|
||||||
|
func getNonLoopbackIPv4() (string, error) {
|
||||||
|
// get all network interfaces
|
||||||
|
interfaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// traverse all network interfaces
|
||||||
|
for _, i := range interfaces {
|
||||||
|
// exclude loopback interface and virtual interface
|
||||||
|
if i.Flags&net.FlagLoopback == 0 && i.Flags&net.FlagUp != 0 {
|
||||||
|
// get all addresses of the interface
|
||||||
|
addrs, err := i.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// traverse all addresses of the interface
|
||||||
|
for _, addr := range addrs {
|
||||||
|
// check the type of the address is IP address
|
||||||
|
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||||
|
// check the IP address is IPv4 address
|
||||||
|
if ipnet.IP.To4() != nil {
|
||||||
|
return ipnet.IP.String(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("Non-loopback IPv4 address not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateXdsIpAndRollout updates the xds address in higress-config ConfigMap
|
||||||
|
// and triggers rollout for higress-controller and higress-gateway deployments
|
||||||
|
// also can recover the xds address in higress-config ConfigMap
|
||||||
|
func updateXdsIpAndRollout(c *kubernetes.Clientset, ip string, port string) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Get higress-config ConfigMap
|
||||||
|
cm, err := c.CoreV1().ConfigMaps("higress-system").Get(ctx, "higress-config", metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update mesh field in higress-config ConfigMap
|
||||||
|
if _, ok := cm.Data["mesh"]; !ok {
|
||||||
|
return fmt.Errorf("mesh not found in configmap higress-config")
|
||||||
|
}
|
||||||
|
mesh := cm.Data["mesh"]
|
||||||
|
newMesh, err := replaceXDSAddress(mesh, ip, port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cm.Data["mesh"] = newMesh
|
||||||
|
|
||||||
|
// Update higress-config ConfigMap
|
||||||
|
_, err = c.CoreV1().ConfigMaps("higress-system").Update(ctx, cm, metav1.UpdateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger rollout for higress-controller deployment
|
||||||
|
err = triggerRollout(c, "higress-controller")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger rollout for higress-gateway deployment
|
||||||
|
err = triggerRollout(c, "higress-gateway")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// triggerRollout triggers rollout for the specified deployment
|
||||||
|
func triggerRollout(clientset *kubernetes.Clientset, deploymentName string) error {
|
||||||
|
deploymentsClient := clientset.AppsV1().Deployments("higress-system")
|
||||||
|
|
||||||
|
// Get the deployment
|
||||||
|
deployment, err := deploymentsClient.Get(context.TODO(), deploymentName, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the deployment's revision to trigger a rollout
|
||||||
|
deployment.Spec.Template.ObjectMeta.Labels["version"] = time.Now().Format("20060102150405")
|
||||||
|
|
||||||
|
// Update the deployment
|
||||||
|
_, err = deploymentsClient.Update(context.TODO(), deployment, metav1.UpdateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// replaceXDSAddress replaces the xds address in the config string with new IP and Port
|
||||||
|
func replaceXDSAddress(configString, newIP, newPort string) (string, error) {
|
||||||
|
// define the regular expression to match xds address
|
||||||
|
xdsRegex := regexp.MustCompile(`xds://[0-9.:]+`)
|
||||||
|
|
||||||
|
// find the first match
|
||||||
|
match := xdsRegex.FindString(configString)
|
||||||
|
if match == "" {
|
||||||
|
// if no match, return error
|
||||||
|
return "", fmt.Errorf("no xds address found in config string")
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace xds address with new IP and Port
|
||||||
|
newXDSAddress := fmt.Sprintf("xds://%s%s", newIP, newPort)
|
||||||
|
result := xdsRegex.ReplaceAllString(configString, newXDSAddress)
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// promptCodeDebug prompts user to confirm code debug
|
||||||
|
func promptCodeDebug(writer io.Writer, t string) bool {
|
||||||
|
answer := ""
|
||||||
|
for {
|
||||||
|
fmt.Fprintf(writer, "This will start set xds address to %s in higress-config ConfigMap "+
|
||||||
|
"and trigger rollout for higress-controller and higress-gateway deployments. \nProceed? (y/N)", t)
|
||||||
|
fmt.Scanln(&answer)
|
||||||
|
if answer == "y" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if answer == "N" {
|
||||||
|
fmt.Fprintf(writer, "Cancelled.\n")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ package hgctl
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/cmd/hgctl/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
)
|
)
|
||||||
@@ -45,21 +46,20 @@ func bootstrapConfigCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runBootstrapConfig(c *cobra.Command, args []string) error {
|
func runBootstrapConfig(c *cobra.Command, args []string) error {
|
||||||
configDump, err := retrieveConfigDump(args, false)
|
if len(args) != 0 {
|
||||||
|
podName = args[0]
|
||||||
|
}
|
||||||
|
envoyConfig, err := config.GetEnvoyConfig(&config.GetEnvoyConfigOptions{
|
||||||
|
PodName: podName,
|
||||||
|
PodNamespace: podNamespace,
|
||||||
|
BindAddress: bindAddress,
|
||||||
|
Output: output,
|
||||||
|
EnvoyConfigType: config.BootstrapEnvoyConfigType,
|
||||||
|
IncludeEds: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
_, err = fmt.Fprintln(c.OutOrStdout(), string(envoyConfig))
|
||||||
bootstrap, err := GetXDSResource(BootstrapEnvoyConfigType, configDump)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := formatGatewayConfig(bootstrap, output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintln(c.OutOrStdout(), string(out))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,13 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package hgctl
|
package hgctl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/cmd/hgctl/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
)
|
)
|
||||||
@@ -44,21 +46,20 @@ func clusterConfigCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runClusterConfig(c *cobra.Command, args []string) error {
|
func runClusterConfig(c *cobra.Command, args []string) error {
|
||||||
configDump, err := retrieveConfigDump(args, false)
|
if len(args) != 0 {
|
||||||
|
podName = args[0]
|
||||||
|
}
|
||||||
|
envoyConfig, err := config.GetEnvoyConfig(&config.GetEnvoyConfigOptions{
|
||||||
|
PodName: podName,
|
||||||
|
PodNamespace: podNamespace,
|
||||||
|
BindAddress: bindAddress,
|
||||||
|
Output: output,
|
||||||
|
EnvoyConfigType: config.ClusterEnvoyConfigType,
|
||||||
|
IncludeEds: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
_, err = fmt.Fprintln(c.OutOrStdout(), string(envoyConfig))
|
||||||
cluster, err := GetXDSResource(ClusterEnvoyConfigType, configDump)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := formatGatewayConfig(cluster, output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintln(c.OutOrStdout(), string(out))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,23 @@ package hgctl
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/cmd/hgctl/config"
|
||||||
"github.com/alibaba/higress/pkg/cmd/options"
|
"github.com/alibaba/higress/pkg/cmd/options"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
output string
|
||||||
|
podName string
|
||||||
|
podNamespace string
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultProxyAdminPort = 15000
|
||||||
|
containerName = "envoy"
|
||||||
|
)
|
||||||
|
|
||||||
func newConfigCommand() *cobra.Command {
|
func newConfigCommand() *cobra.Command {
|
||||||
cfgCommand := &cobra.Command{
|
cfgCommand := &cobra.Command{
|
||||||
Use: "gateway-config",
|
Use: "gateway-config",
|
||||||
@@ -69,11 +81,20 @@ func allConfigCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runAllConfig(c *cobra.Command, args []string) error {
|
func runAllConfig(c *cobra.Command, args []string) error {
|
||||||
configDump, err := retrieveConfigDump(args, true)
|
if len(args) != 0 {
|
||||||
|
podName = args[0]
|
||||||
|
}
|
||||||
|
envoyConfig, err := config.GetEnvoyConfig(&config.GetEnvoyConfigOptions{
|
||||||
|
PodName: podName,
|
||||||
|
PodNamespace: podNamespace,
|
||||||
|
BindAddress: bindAddress,
|
||||||
|
Output: output,
|
||||||
|
EnvoyConfigType: config.AllEnvoyConfigType,
|
||||||
|
IncludeEds: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
_, err = fmt.Fprintln(c.OutOrStdout(), string(envoyConfig))
|
||||||
_, err = fmt.Fprintln(c.OutOrStdout(), string(configDump))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package hgctl
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/cmd/hgctl/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
)
|
)
|
||||||
@@ -45,21 +46,20 @@ func endpointConfigCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runEndpointConfig(c *cobra.Command, args []string) error {
|
func runEndpointConfig(c *cobra.Command, args []string) error {
|
||||||
configDump, err := retrieveConfigDump(args, true)
|
if len(args) != 0 {
|
||||||
|
podName = args[0]
|
||||||
|
}
|
||||||
|
envoyConfig, err := config.GetEnvoyConfig(&config.GetEnvoyConfigOptions{
|
||||||
|
PodName: podName,
|
||||||
|
PodNamespace: podNamespace,
|
||||||
|
BindAddress: bindAddress,
|
||||||
|
Output: output,
|
||||||
|
EnvoyConfigType: config.EndpointEnvoyConfigType,
|
||||||
|
IncludeEds: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
_, err = fmt.Fprintln(c.OutOrStdout(), string(envoyConfig))
|
||||||
endpoint, err := GetXDSResource(EndpointEnvoyConfigType, configDump)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := formatGatewayConfig(endpoint, output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintln(c.OutOrStdout(), string(out))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package hgctl
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/cmd/hgctl/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
)
|
)
|
||||||
@@ -45,21 +46,20 @@ func listenerConfigCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runListenerConfig(c *cobra.Command, args []string) error {
|
func runListenerConfig(c *cobra.Command, args []string) error {
|
||||||
configDump, err := retrieveConfigDump(args, false)
|
if len(args) != 0 {
|
||||||
|
podName = args[0]
|
||||||
|
}
|
||||||
|
envoyConfig, err := config.GetEnvoyConfig(&config.GetEnvoyConfigOptions{
|
||||||
|
PodName: podName,
|
||||||
|
PodNamespace: podNamespace,
|
||||||
|
BindAddress: bindAddress,
|
||||||
|
Output: output,
|
||||||
|
EnvoyConfigType: config.ListenerEnvoyConfigType,
|
||||||
|
IncludeEds: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
_, err = fmt.Fprintln(c.OutOrStdout(), string(envoyConfig))
|
||||||
listener, err := GetXDSResource(ListenerEnvoyConfigType, configDump)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := formatGatewayConfig(listener, output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintln(c.OutOrStdout(), string(out))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package hgctl
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/cmd/hgctl/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
)
|
)
|
||||||
@@ -45,21 +46,20 @@ func routeConfigCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runRouteConfig(c *cobra.Command, args []string) error {
|
func runRouteConfig(c *cobra.Command, args []string) error {
|
||||||
configDump, err := retrieveConfigDump(args, false)
|
if len(args) != 0 {
|
||||||
|
podName = args[0]
|
||||||
|
}
|
||||||
|
envoyConfig, err := config.GetEnvoyConfig(&config.GetEnvoyConfigOptions{
|
||||||
|
PodName: podName,
|
||||||
|
PodNamespace: podNamespace,
|
||||||
|
BindAddress: bindAddress,
|
||||||
|
Output: output,
|
||||||
|
EnvoyConfigType: config.RouteEnvoyConfigType,
|
||||||
|
IncludeEds: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
_, err = fmt.Fprintln(c.OutOrStdout(), string(envoyConfig))
|
||||||
route, err := GetXDSResource(RouteEnvoyConfigType, configDump)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := formatGatewayConfig(route, output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintln(c.OutOrStdout(), string(out))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
|
||||||
"os/user"
|
"os/user"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/alibaba/higress/pkg/cmd/hgctl/plugin/option"
|
"github.com/alibaba/higress/pkg/cmd/hgctl/plugin/option"
|
||||||
ptypes "github.com/alibaba/higress/pkg/cmd/hgctl/plugin/types"
|
ptypes "github.com/alibaba/higress/pkg/cmd/hgctl/plugin/types"
|
||||||
@@ -633,11 +631,7 @@ func (b *Builder) config(f ConfigFunc) (err error) {
|
|||||||
b.w = os.Stdout
|
b.w = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
b.sig = make(chan os.Signal, 1)
|
signalNotify(b)
|
||||||
b.stop = make(chan struct{}, 1)
|
|
||||||
b.done = make(chan struct{}, 1)
|
|
||||||
signal.Notify(b.sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM,
|
|
||||||
syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGQUIT, syscall.SIGTSTP)
|
|
||||||
|
|
||||||
if b.Debugger == nil {
|
if b.Debugger == nil {
|
||||||
b.Debugger = utils.NewDefaultDebugger(b.Debug, b.w)
|
b.Debugger = utils.NewDefaultDebugger(b.Debug, b.w)
|
||||||
|
|||||||
31
pkg/cmd/hgctl/plugin/build/signal.go
Normal file
31
pkg/cmd/hgctl/plugin/build/signal.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:build linux || darwin || bsd
|
||||||
|
|
||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func signalNotify(b *Builder) {
|
||||||
|
b.sig = make(chan os.Signal, 1)
|
||||||
|
b.stop = make(chan struct{}, 1)
|
||||||
|
b.done = make(chan struct{}, 1)
|
||||||
|
signal.Notify(b.sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM,
|
||||||
|
syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGQUIT, syscall.SIGTSTP)
|
||||||
|
}
|
||||||
31
pkg/cmd/hgctl/plugin/build/signal_windows.go
Normal file
31
pkg/cmd/hgctl/plugin/build/signal_windows.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func signalNotify(b *Builder) {
|
||||||
|
b.sig = make(chan os.Signal, 1)
|
||||||
|
b.stop = make(chan struct{}, 1)
|
||||||
|
b.done = make(chan struct{}, 1)
|
||||||
|
signal.Notify(b.sig, syscall.SIGHUP, syscall.SIGINT,
|
||||||
|
syscall.SIGTERM, syscall.SIGQUIT)
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ func GetRootCommand() *cobra.Command {
|
|||||||
rootCmd.AddCommand(newManifestCmd())
|
rootCmd.AddCommand(newManifestCmd())
|
||||||
rootCmd.AddCommand(plugin.NewCommand())
|
rootCmd.AddCommand(plugin.NewCommand())
|
||||||
rootCmd.AddCommand(newCompletionCmd(os.Stdout))
|
rootCmd.AddCommand(newCompletionCmd(os.Stdout))
|
||||||
|
rootCmd.AddCommand(newCodeDebugCmd())
|
||||||
|
|
||||||
return rootCmd
|
return rootCmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func getServerCommand() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
serveCmd.PersistentFlags().StringVar(&serverArgs.GatewaySelectorKey, "gatewaySelectorKey", "higress", "gateway resource selector label key")
|
serveCmd.PersistentFlags().StringVar(&serverArgs.GatewaySelectorKey, "gatewaySelectorKey", "higress", "gateway resource selector label key")
|
||||||
serveCmd.PersistentFlags().StringVar(&serverArgs.GatewaySelectorValue, "gatewaySelectorValue", "higress-gateway", "gateway resource selector label value")
|
serveCmd.PersistentFlags().StringVar(&serverArgs.GatewaySelectorValue, "gatewaySelectorValue", "higress-system-higress-gateway", "gateway resource selector label value")
|
||||||
serveCmd.PersistentFlags().BoolVar(&serverArgs.EnableStatus, "enableStatus", true, "enable the ingress status syncer which use to update the ip in ingress's status")
|
serveCmd.PersistentFlags().BoolVar(&serverArgs.EnableStatus, "enableStatus", true, "enable the ingress status syncer which use to update the ip in ingress's status")
|
||||||
serveCmd.PersistentFlags().StringVar(&serverArgs.IngressClass, "ingressClass", innerconstants.DefaultIngressClass, "if not empty, only watch the ingresses have the specified class, otherwise watch all ingresses")
|
serveCmd.PersistentFlags().StringVar(&serverArgs.IngressClass, "ingressClass", innerconstants.DefaultIngressClass, "if not empty, only watch the ingresses have the specified class, otherwise watch all ingresses")
|
||||||
serveCmd.PersistentFlags().StringVar(&serverArgs.WatchNamespace, "watchNamespace", "", "if not empty, only wath the ingresses in the specified namespace, otherwise watch in all namespacees")
|
serveCmd.PersistentFlags().StringVar(&serverArgs.WatchNamespace, "watchNamespace", "", "if not empty, only wath the ingresses in the specified namespace, otherwise watch in all namespacees")
|
||||||
|
|||||||
@@ -1265,12 +1265,21 @@ func (m *IngressConfig) constructHttp2RpcMethods(dubbo *higressv1.DubboService)
|
|||||||
var method = make(map[string]interface{})
|
var method = make(map[string]interface{})
|
||||||
method["name"] = serviceMethod.GetServiceMethod()
|
method["name"] = serviceMethod.GetServiceMethod()
|
||||||
var params []interface{}
|
var params []interface{}
|
||||||
for _, methodParam := range serviceMethod.GetParams() {
|
// paramFromEntireBody is for methods with single parameter. So when paramFromEntireBody exists, we just ignore parmas.
|
||||||
|
var paramFromEntireBody = serviceMethod.GetParamFromEntireBody()
|
||||||
|
if paramFromEntireBody != nil {
|
||||||
var param = make(map[string]interface{})
|
var param = make(map[string]interface{})
|
||||||
param["extract_key"] = methodParam.GetParamKey()
|
param["extract_key_spec"] = Http2RpcParamSourceMap()["BODY"]
|
||||||
param["extract_key_spec"] = Http2RpcParamSourceMap()[methodParam.GetParamSource()]
|
param["mapping_type"] = paramFromEntireBody.GetParamType()
|
||||||
param["mapping_type"] = methodParam.GetParamType()
|
|
||||||
params = append(params, param)
|
params = append(params, param)
|
||||||
|
} else {
|
||||||
|
for _, methodParam := range serviceMethod.GetParams() {
|
||||||
|
var param = make(map[string]interface{})
|
||||||
|
param["extract_key"] = methodParam.GetParamKey()
|
||||||
|
param["extract_key_spec"] = Http2RpcParamSourceMap()[methodParam.GetParamSource()]
|
||||||
|
param["mapping_type"] = methodParam.GetParamType()
|
||||||
|
params = append(params, param)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
method["parameter_mapping"] = params
|
method["parameter_mapping"] = params
|
||||||
var path_matcher = make(map[string]interface{})
|
var path_matcher = make(map[string]interface{})
|
||||||
|
|||||||
@@ -34,14 +34,21 @@ const (
|
|||||||
type ItemEventHandler = func(name string)
|
type ItemEventHandler = func(name string)
|
||||||
|
|
||||||
type HigressConfig struct {
|
type HigressConfig struct {
|
||||||
Tracing *Tracing `json:"tracing,omitempty"`
|
Tracing *Tracing `json:"tracing,omitempty"`
|
||||||
Gzip *Gzip `json:"gzip,omitempty"`
|
Gzip *Gzip `json:"gzip,omitempty"`
|
||||||
|
Downstream *Downstream `json:"downstream,omitempty"`
|
||||||
|
DisableXEnvoyHeaders bool `json:"disableXEnvoyHeaders,omitempty"`
|
||||||
|
AddXRealIpHeader bool `json:"addXRealIpHeader,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultHigressConfig() *HigressConfig {
|
func NewDefaultHigressConfig() *HigressConfig {
|
||||||
|
globalOption := NewDefaultGlobalOption()
|
||||||
higressConfig := &HigressConfig{
|
higressConfig := &HigressConfig{
|
||||||
Tracing: NewDefaultTracing(),
|
Tracing: NewDefaultTracing(),
|
||||||
Gzip: NewDefaultGzip(),
|
Gzip: NewDefaultGzip(),
|
||||||
|
Downstream: globalOption.Downstream,
|
||||||
|
DisableXEnvoyHeaders: globalOption.DisableXEnvoyHeaders,
|
||||||
|
AddXRealIpHeader: globalOption.AddXRealIpHeader,
|
||||||
}
|
}
|
||||||
return higressConfig
|
return higressConfig
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,9 +73,14 @@ func NewConfigmapMgr(XDSUpdater model.XDSUpdater, namespace string, higressConfi
|
|||||||
configmapMgr.SetHigressConfig(NewDefaultHigressConfig())
|
configmapMgr.SetHigressConfig(NewDefaultHigressConfig())
|
||||||
|
|
||||||
tracingController := NewTracingController(namespace)
|
tracingController := NewTracingController(namespace)
|
||||||
gzipController := NewGzipController(namespace)
|
|
||||||
configmapMgr.AddItemControllers(tracingController)
|
configmapMgr.AddItemControllers(tracingController)
|
||||||
|
|
||||||
|
gzipController := NewGzipController(namespace)
|
||||||
configmapMgr.AddItemControllers(gzipController)
|
configmapMgr.AddItemControllers(gzipController)
|
||||||
|
|
||||||
|
globalOptionController := NewGlobalOptionController(namespace)
|
||||||
|
configmapMgr.AddItemControllers(globalOptionController)
|
||||||
|
|
||||||
configmapMgr.initEventHandlers()
|
configmapMgr.initEventHandlers()
|
||||||
|
|
||||||
return configmapMgr
|
return configmapMgr
|
||||||
|
|||||||
502
pkg/ingress/kube/configmap/global.go
Normal file
502
pkg/ingress/kube/configmap/global.go
Normal file
@@ -0,0 +1,502 @@
|
|||||||
|
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package configmap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||||
|
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||||
|
networking "istio.io/api/networking/v1alpha3"
|
||||||
|
"istio.io/istio/pkg/config"
|
||||||
|
"istio.io/istio/pkg/config/schema/gvk"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
higressGlobalEnvoyFilterName = "global-option"
|
||||||
|
|
||||||
|
maxMaxRequestHeadersKb = 8192
|
||||||
|
minMaxConcurrentStreams = 1
|
||||||
|
maxMaxConcurrentStreams = 2147483647
|
||||||
|
minInitialStreamWindowSize = 65535
|
||||||
|
maxInitialStreamWindowSize = 2147483647
|
||||||
|
minInitialConnectionWindowSize = 65535
|
||||||
|
maxInitialConnectionWindowSize = 2147483647
|
||||||
|
|
||||||
|
defaultIdleTimeout = 180
|
||||||
|
defaultMaxRequestHeadersKb = 60
|
||||||
|
defaultConnectionBufferLimits = 32768
|
||||||
|
defaultMaxConcurrentStreams = 100
|
||||||
|
defaultInitialStreamWindowSize = 65535
|
||||||
|
defaultInitialConnectionWindowSize = 1048576
|
||||||
|
defaultAddXRealIpHeader = false
|
||||||
|
defaultDisableXEnvoyHeaders = false
|
||||||
|
)
|
||||||
|
|
||||||
|
// Global configures the behavior of the downstream connection, x-real-ip header and x-envoy headers.
|
||||||
|
type Global struct {
|
||||||
|
Downstream *Downstream `json:"downstream,omitempty"`
|
||||||
|
AddXRealIpHeader bool `json:"addXRealIpHeader,omitempty"`
|
||||||
|
DisableXEnvoyHeaders bool `json:"disableXEnvoyHeaders,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Downstream configures the behavior of the downstream connection.
|
||||||
|
type Downstream struct {
|
||||||
|
// IdleTimeout limits the time that a connection may be idle and stream idle.
|
||||||
|
IdleTimeout uint32 `json:"idleTimeout,omitempty"`
|
||||||
|
// MaxRequestHeadersKb limits the size of request headers allowed.
|
||||||
|
MaxRequestHeadersKb uint32 `json:"maxRequestHeadersKb,omitempty"`
|
||||||
|
// ConnectionBufferLimits configures the buffer size limits for connections.
|
||||||
|
ConnectionBufferLimits uint32 `json:"connectionBufferLimits,omitempty"`
|
||||||
|
// Http2 configures HTTP/2 specific options.
|
||||||
|
Http2 *Http2 `json:"http2,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Http2 configures HTTP/2 specific options.
|
||||||
|
type Http2 struct {
|
||||||
|
// MaxConcurrentStreams limits the number of concurrent streams allowed.
|
||||||
|
MaxConcurrentStreams uint32 `json:"maxConcurrentStreams,omitempty"`
|
||||||
|
// InitialStreamWindowSize limits the initial window size of stream.
|
||||||
|
InitialStreamWindowSize uint32 `json:"initialStreamWindowSize,omitempty"`
|
||||||
|
// InitialConnectionWindowSize limits the initial window size of connection.
|
||||||
|
InitialConnectionWindowSize uint32 `json:"initialConnectionWindowSize,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// validGlobal validates the global config.
|
||||||
|
func validGlobal(global *Global) error {
|
||||||
|
if global == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if global.Downstream == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
downStream := global.Downstream
|
||||||
|
|
||||||
|
// check maxRequestHeadersKb
|
||||||
|
if downStream.MaxRequestHeadersKb > maxMaxRequestHeadersKb {
|
||||||
|
return fmt.Errorf("maxRequestHeadersKb must be less than or equal to 8192")
|
||||||
|
}
|
||||||
|
// check http2
|
||||||
|
if downStream.Http2 != nil {
|
||||||
|
// check maxConcurrentStreams
|
||||||
|
if downStream.Http2.MaxConcurrentStreams < minMaxConcurrentStreams ||
|
||||||
|
downStream.Http2.MaxConcurrentStreams > maxMaxConcurrentStreams {
|
||||||
|
return fmt.Errorf("http2.maxConcurrentStreams must be between 1 and 2147483647")
|
||||||
|
}
|
||||||
|
// check initialStreamWindowSize
|
||||||
|
if downStream.Http2.InitialStreamWindowSize < minInitialStreamWindowSize ||
|
||||||
|
downStream.Http2.InitialStreamWindowSize > maxInitialStreamWindowSize {
|
||||||
|
return fmt.Errorf("http2.initialStreamWindowSize must be between 65535 and 2147483647")
|
||||||
|
}
|
||||||
|
// check initialConnectionWindowSize
|
||||||
|
if downStream.Http2.InitialConnectionWindowSize < minInitialConnectionWindowSize ||
|
||||||
|
downStream.Http2.InitialConnectionWindowSize > maxInitialConnectionWindowSize {
|
||||||
|
return fmt.Errorf("http2.initialConnectionWindowSize must be between 65535 and 2147483647")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// compareGlobal compares the old and new global option.
|
||||||
|
func compareGlobal(old *Global, new *Global) (Result, error) {
|
||||||
|
if old == nil && new == nil {
|
||||||
|
return ResultNothing, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if new == nil {
|
||||||
|
return ResultDelete, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if new.Downstream == nil && !new.AddXRealIpHeader && !new.DisableXEnvoyHeaders {
|
||||||
|
return ResultDelete, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(old, new) {
|
||||||
|
return ResultReplace, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultNothing, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// deepCopyGlobal deep copies the global option.
|
||||||
|
func deepCopyGlobal(global *Global) (*Global, error) {
|
||||||
|
newGlobal := NewDefaultGlobalOption()
|
||||||
|
bytes, err := json.Marshal(global)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(bytes, newGlobal)
|
||||||
|
return newGlobal, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultGlobalOption returns a default global config.
|
||||||
|
func NewDefaultGlobalOption() *Global {
|
||||||
|
return &Global{
|
||||||
|
Downstream: NewDefaultDownstream(),
|
||||||
|
AddXRealIpHeader: defaultAddXRealIpHeader,
|
||||||
|
DisableXEnvoyHeaders: defaultDisableXEnvoyHeaders,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultDownstream returns a default downstream config.
|
||||||
|
func NewDefaultDownstream() *Downstream {
|
||||||
|
return &Downstream{
|
||||||
|
IdleTimeout: defaultIdleTimeout,
|
||||||
|
MaxRequestHeadersKb: defaultMaxRequestHeadersKb,
|
||||||
|
ConnectionBufferLimits: defaultConnectionBufferLimits,
|
||||||
|
Http2: NewDefaultHttp2(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultHttp2 returns a default http2 config.
|
||||||
|
func NewDefaultHttp2() *Http2 {
|
||||||
|
return &Http2{
|
||||||
|
MaxConcurrentStreams: defaultMaxConcurrentStreams,
|
||||||
|
InitialStreamWindowSize: defaultInitialStreamWindowSize,
|
||||||
|
InitialConnectionWindowSize: defaultInitialConnectionWindowSize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalOptionController is the controller of downstream config.
|
||||||
|
type GlobalOptionController struct {
|
||||||
|
Namespace string
|
||||||
|
global atomic.Value
|
||||||
|
Name string
|
||||||
|
eventHandler ItemEventHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGlobalOptionController returns a GlobalOptionController.
|
||||||
|
func NewGlobalOptionController(namespace string) *GlobalOptionController {
|
||||||
|
globalOptionController := &GlobalOptionController{
|
||||||
|
Namespace: namespace,
|
||||||
|
global: atomic.Value{},
|
||||||
|
Name: "global-option",
|
||||||
|
}
|
||||||
|
globalOptionController.SetGlobal(NewDefaultGlobalOption())
|
||||||
|
return globalOptionController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GlobalOptionController) SetGlobal(global *Global) {
|
||||||
|
g.global.Store(global)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GlobalOptionController) GetGlobal() *Global {
|
||||||
|
value := g.global.Load()
|
||||||
|
if value != nil {
|
||||||
|
if global, ok := value.(*Global); ok {
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GlobalOptionController) GetName() string {
|
||||||
|
return g.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GlobalOptionController) AddOrUpdateHigressConfig(name util.ClusterNamespacedName, old *HigressConfig, new *HigressConfig) error {
|
||||||
|
newGlobal := &Global{
|
||||||
|
Downstream: new.Downstream,
|
||||||
|
AddXRealIpHeader: new.AddXRealIpHeader,
|
||||||
|
DisableXEnvoyHeaders: new.DisableXEnvoyHeaders,
|
||||||
|
}
|
||||||
|
|
||||||
|
oldGlobal := &Global{
|
||||||
|
Downstream: old.Downstream,
|
||||||
|
AddXRealIpHeader: old.AddXRealIpHeader,
|
||||||
|
DisableXEnvoyHeaders: old.DisableXEnvoyHeaders,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := validGlobal(newGlobal)
|
||||||
|
if err != nil {
|
||||||
|
IngressLog.Errorf("data:%+v convert to global-option config error, error: %+v", newGlobal, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
result, _ := compareGlobal(oldGlobal, newGlobal)
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case ResultReplace:
|
||||||
|
if newGlobalCopy, err := deepCopyGlobal(newGlobal); err != nil {
|
||||||
|
IngressLog.Infof("global-option config deepcopy error:%v", err)
|
||||||
|
} else {
|
||||||
|
g.SetGlobal(newGlobalCopy)
|
||||||
|
IngressLog.Infof("AddOrUpdate Higress config global-option")
|
||||||
|
g.eventHandler(higressGlobalEnvoyFilterName)
|
||||||
|
IngressLog.Infof("send event with filter name:%s", higressGlobalEnvoyFilterName)
|
||||||
|
}
|
||||||
|
case ResultDelete:
|
||||||
|
g.SetGlobal(NewDefaultGlobalOption())
|
||||||
|
IngressLog.Infof("Delete Higress config global-option")
|
||||||
|
g.eventHandler(higressGlobalEnvoyFilterName)
|
||||||
|
IngressLog.Infof("send event with filter name:%s", higressGlobalEnvoyFilterName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GlobalOptionController) ValidHigressConfig(higressConfig *HigressConfig) error {
|
||||||
|
if higressConfig == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if higressConfig.Downstream == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
global := &Global{
|
||||||
|
Downstream: higressConfig.Downstream,
|
||||||
|
AddXRealIpHeader: higressConfig.AddXRealIpHeader,
|
||||||
|
DisableXEnvoyHeaders: higressConfig.DisableXEnvoyHeaders,
|
||||||
|
}
|
||||||
|
|
||||||
|
return validGlobal(global)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GlobalOptionController) ConstructEnvoyFilters() ([]*config.Config, error) {
|
||||||
|
configPatch := make([]*networking.EnvoyFilter_EnvoyConfigObjectPatch, 0)
|
||||||
|
global := g.GetGlobal()
|
||||||
|
if global == nil {
|
||||||
|
configs := make([]*config.Config, 0)
|
||||||
|
return configs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace := g.Namespace
|
||||||
|
|
||||||
|
if global.AddXRealIpHeader {
|
||||||
|
addXRealIpStruct := g.constructAddXRealIpHeader()
|
||||||
|
addXRealIpHeaderConfig := g.generateAddXRealIpHeaderEnvoyFilter(addXRealIpStruct, namespace)
|
||||||
|
configPatch = append(configPatch, addXRealIpHeaderConfig...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if global.DisableXEnvoyHeaders {
|
||||||
|
disableXEnvoyHeadersStruct := g.constructDisableXEnvoyHeaders()
|
||||||
|
disableXEnvoyHeadersConfig := g.generateDisableXEnvoyHeadersEnvoyFilter(disableXEnvoyHeadersStruct, namespace)
|
||||||
|
configPatch = append(configPatch, disableXEnvoyHeadersConfig...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if global.Downstream == nil {
|
||||||
|
return generateEnvoyFilter(namespace, configPatch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
downstreamStruct := g.constructDownstream(global.Downstream)
|
||||||
|
bufferLimitStruct := g.constructBufferLimit(global.Downstream)
|
||||||
|
if len(downstreamStruct) == 0 && len(bufferLimitStruct) == 0 {
|
||||||
|
return generateEnvoyFilter(namespace, configPatch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
downstreamConfig := g.generateDownstreamEnvoyFilter(downstreamStruct, bufferLimitStruct, namespace)
|
||||||
|
configPatch = append(configPatch, downstreamConfig...)
|
||||||
|
|
||||||
|
return generateEnvoyFilter(namespace, configPatch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateEnvoyFilter(namespace string, configPatch []*networking.EnvoyFilter_EnvoyConfigObjectPatch) []*config.Config {
|
||||||
|
configs := make([]*config.Config, 0)
|
||||||
|
envoyConfig := &config.Config{
|
||||||
|
Meta: config.Meta{
|
||||||
|
GroupVersionKind: gvk.EnvoyFilter,
|
||||||
|
Name: higressGlobalEnvoyFilterName,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Spec: &networking.EnvoyFilter{
|
||||||
|
ConfigPatches: configPatch,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
configs = append(configs, envoyConfig)
|
||||||
|
return configs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GlobalOptionController) RegisterItemEventHandler(eventHandler ItemEventHandler) {
|
||||||
|
g.eventHandler = eventHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateDownstreamEnvoyFilter generates the downstream envoy filter.
|
||||||
|
func (g *GlobalOptionController) generateDownstreamEnvoyFilter(downstreamValueStruct string, bufferLimitStruct string, namespace string) []*networking.EnvoyFilter_EnvoyConfigObjectPatch {
|
||||||
|
downstreamConfig := []*networking.EnvoyFilter_EnvoyConfigObjectPatch{
|
||||||
|
{
|
||||||
|
ApplyTo: networking.EnvoyFilter_NETWORK_FILTER,
|
||||||
|
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||||
|
Context: networking.EnvoyFilter_GATEWAY,
|
||||||
|
ObjectTypes: &networking.EnvoyFilter_EnvoyConfigObjectMatch_Listener{
|
||||||
|
Listener: &networking.EnvoyFilter_ListenerMatch{
|
||||||
|
FilterChain: &networking.EnvoyFilter_ListenerMatch_FilterChainMatch{
|
||||||
|
Filter: &networking.EnvoyFilter_ListenerMatch_FilterMatch{
|
||||||
|
Name: "envoy.filters.network.http_connection_manager",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Patch: &networking.EnvoyFilter_Patch{
|
||||||
|
Operation: networking.EnvoyFilter_Patch_MERGE,
|
||||||
|
Value: util.BuildPatchStruct(downstreamValueStruct),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ApplyTo: networking.EnvoyFilter_LISTENER,
|
||||||
|
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||||
|
Context: networking.EnvoyFilter_GATEWAY,
|
||||||
|
},
|
||||||
|
Patch: &networking.EnvoyFilter_Patch{
|
||||||
|
Operation: networking.EnvoyFilter_Patch_MERGE,
|
||||||
|
Value: util.BuildPatchStruct(bufferLimitStruct),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return downstreamConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateAddXRealIpHeaderEnvoyFilter generates the add x-real-ip header envoy filter.
|
||||||
|
func (g *GlobalOptionController) generateAddXRealIpHeaderEnvoyFilter(addXRealIpHeaderStruct string, namespace string) []*networking.EnvoyFilter_EnvoyConfigObjectPatch {
|
||||||
|
addXRealIpHeaderConfig := []*networking.EnvoyFilter_EnvoyConfigObjectPatch{
|
||||||
|
{
|
||||||
|
ApplyTo: networking.EnvoyFilter_ROUTE_CONFIGURATION,
|
||||||
|
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||||
|
Context: networking.EnvoyFilter_GATEWAY,
|
||||||
|
},
|
||||||
|
Patch: &networking.EnvoyFilter_Patch{
|
||||||
|
Operation: networking.EnvoyFilter_Patch_MERGE,
|
||||||
|
Value: util.BuildPatchStruct(addXRealIpHeaderStruct),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return addXRealIpHeaderConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateDisableXEnvoyHeadersEnvoyFilter generates the disable x-envoy headers envoy filter.
|
||||||
|
func (g *GlobalOptionController) generateDisableXEnvoyHeadersEnvoyFilter(disableXEnvoyStruct string, namespace string) []*networking.EnvoyFilter_EnvoyConfigObjectPatch {
|
||||||
|
disableXEnvoyHeadersConfig := []*networking.EnvoyFilter_EnvoyConfigObjectPatch{
|
||||||
|
{
|
||||||
|
ApplyTo: networking.EnvoyFilter_HTTP_FILTER,
|
||||||
|
Match: &networking.EnvoyFilter_EnvoyConfigObjectMatch{
|
||||||
|
Context: networking.EnvoyFilter_GATEWAY,
|
||||||
|
ObjectTypes: &networking.EnvoyFilter_EnvoyConfigObjectMatch_Listener{
|
||||||
|
Listener: &networking.EnvoyFilter_ListenerMatch{
|
||||||
|
FilterChain: &networking.EnvoyFilter_ListenerMatch_FilterChainMatch{
|
||||||
|
Filter: &networking.EnvoyFilter_ListenerMatch_FilterMatch{
|
||||||
|
Name: "envoy.filters.network.http_connection_manager",
|
||||||
|
SubFilter: &networking.EnvoyFilter_ListenerMatch_SubFilterMatch{
|
||||||
|
Name: "envoy.filters.http.router",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Patch: &networking.EnvoyFilter_Patch{
|
||||||
|
Operation: networking.EnvoyFilter_Patch_REPLACE,
|
||||||
|
Value: util.BuildPatchStruct(disableXEnvoyStruct),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return disableXEnvoyHeadersConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructDownstream constructs the downstream config.
|
||||||
|
func (g *GlobalOptionController) constructDownstream(downstream *Downstream) string {
|
||||||
|
downstreamConfig := ""
|
||||||
|
idleTimeout := downstream.IdleTimeout
|
||||||
|
maxRequestHeadersKb := downstream.MaxRequestHeadersKb
|
||||||
|
|
||||||
|
if downstream.Http2 != nil {
|
||||||
|
maxConcurrentStreams := downstream.Http2.MaxConcurrentStreams
|
||||||
|
initialStreamWindowSize := downstream.Http2.InitialStreamWindowSize
|
||||||
|
initialConnectionWindowSize := downstream.Http2.InitialConnectionWindowSize
|
||||||
|
|
||||||
|
downstreamConfig = fmt.Sprintf(`
|
||||||
|
{
|
||||||
|
"name": "envoy.filters.network.http_connection_manager",
|
||||||
|
"typed_config": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"common_http_protocol_options": {
|
||||||
|
"idleTimeout": "%ds"
|
||||||
|
},
|
||||||
|
"http2_protocol_options": {
|
||||||
|
"maxConcurrentStreams": %d,
|
||||||
|
"initialStreamWindowSize": %d,
|
||||||
|
"initialConnectionWindowSize": %d
|
||||||
|
},
|
||||||
|
"maxRequestHeadersKb": %d,
|
||||||
|
"streamIdleTimeout": "%ds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, idleTimeout, maxConcurrentStreams, initialStreamWindowSize, initialConnectionWindowSize, maxRequestHeadersKb, idleTimeout)
|
||||||
|
return downstreamConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
downstreamConfig = fmt.Sprintf(`
|
||||||
|
{
|
||||||
|
"name": "envoy.filters.network.http_connection_manager",
|
||||||
|
"typed_config": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"common_http_protocol_options": {
|
||||||
|
"idleTimeout": "%ds"
|
||||||
|
},
|
||||||
|
"maxRequestHeadersKb": %d,
|
||||||
|
"streamIdleTimeout": "%ds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, idleTimeout, maxRequestHeadersKb, idleTimeout)
|
||||||
|
|
||||||
|
return downstreamConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructAddXRealIpHeader constructs the add x-real-ip header config.
|
||||||
|
func (g *GlobalOptionController) constructAddXRealIpHeader() string {
|
||||||
|
addXRealIpHeaderStruct := fmt.Sprintf(`
|
||||||
|
{
|
||||||
|
"request_headers_to_add": [
|
||||||
|
{
|
||||||
|
"append": false,
|
||||||
|
"header": {
|
||||||
|
"key": "x-real-ip",
|
||||||
|
"value": "%%REQ(X-ENVOY-EXTERNAL-ADDRESS)%%"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
return addXRealIpHeaderStruct
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructDisableXEnvoyHeaders constructs the disable x-envoy headers config.
|
||||||
|
func (g *GlobalOptionController) constructDisableXEnvoyHeaders() string {
|
||||||
|
disableXEnvoyHeadersStruct := fmt.Sprintf(`
|
||||||
|
{
|
||||||
|
"name": "envoy.filters.http.router",
|
||||||
|
"typed_config": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router",
|
||||||
|
"suppress_envoy_headers": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
return disableXEnvoyHeadersStruct
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructBufferLimit constructs the buffer limit config.
|
||||||
|
func (g *GlobalOptionController) constructBufferLimit(downstream *Downstream) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
{
|
||||||
|
"per_connection_buffer_limit_bytes": %d
|
||||||
|
}
|
||||||
|
`, downstream.ConnectionBufferLimits)
|
||||||
|
}
|
||||||
252
pkg/ingress/kube/configmap/global_test.go
Normal file
252
pkg/ingress/kube/configmap/global_test.go
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package configmap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_validGlobal(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
global *Global
|
||||||
|
wantErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "default",
|
||||||
|
global: NewDefaultGlobalOption(),
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nil",
|
||||||
|
global: nil,
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "downstream nil",
|
||||||
|
global: &Global{
|
||||||
|
Downstream: nil,
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
err := validGlobal(tt.global)
|
||||||
|
assert.Equal(t, tt.wantErr, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_compareGlobal(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
old *Global
|
||||||
|
new *Global
|
||||||
|
want Result
|
||||||
|
wantErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "compare both nil",
|
||||||
|
old: nil,
|
||||||
|
new: nil,
|
||||||
|
want: ResultNothing,
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "compare new nil 1",
|
||||||
|
old: NewDefaultGlobalOption(),
|
||||||
|
new: nil,
|
||||||
|
want: ResultDelete,
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "compare new nil 2",
|
||||||
|
old: NewDefaultGlobalOption(),
|
||||||
|
new: &Global{},
|
||||||
|
want: ResultDelete,
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "compare result equal",
|
||||||
|
old: NewDefaultGlobalOption(),
|
||||||
|
new: NewDefaultGlobalOption(),
|
||||||
|
want: ResultNothing,
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "compare result not equal",
|
||||||
|
old: NewDefaultGlobalOption(),
|
||||||
|
new: &Global{
|
||||||
|
Downstream: &Downstream{
|
||||||
|
IdleTimeout: 1,
|
||||||
|
},
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
want: ResultReplace,
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result, err := compareGlobal(tt.old, tt.new)
|
||||||
|
assert.Equal(t, tt.wantErr, err)
|
||||||
|
assert.Equal(t, tt.want, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_deepCopyGlobal(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
global *Global
|
||||||
|
want *Global
|
||||||
|
wantErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "deep copy 1",
|
||||||
|
global: NewDefaultGlobalOption(),
|
||||||
|
want: NewDefaultGlobalOption(),
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deep copy 2",
|
||||||
|
global: &Global{
|
||||||
|
Downstream: &Downstream{
|
||||||
|
IdleTimeout: 1,
|
||||||
|
MaxRequestHeadersKb: 9600,
|
||||||
|
ConnectionBufferLimits: 4096,
|
||||||
|
Http2: NewDefaultHttp2(),
|
||||||
|
},
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
want: &Global{
|
||||||
|
Downstream: &Downstream{
|
||||||
|
IdleTimeout: 1,
|
||||||
|
MaxRequestHeadersKb: 9600,
|
||||||
|
ConnectionBufferLimits: 4096,
|
||||||
|
Http2: NewDefaultHttp2(),
|
||||||
|
},
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deep copy 3",
|
||||||
|
global: &Global{
|
||||||
|
Downstream: &Downstream{},
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
want: &Global{
|
||||||
|
Downstream: NewDefaultDownstream(),
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
global, err := deepCopyGlobal(tt.global)
|
||||||
|
assert.Equal(t, tt.wantErr, err)
|
||||||
|
assert.Equal(t, tt.want, global)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_AddOrUpdateHigressConfig(t *testing.T) {
|
||||||
|
eventPush := "default"
|
||||||
|
defaultHandler := func(name string) {
|
||||||
|
eventPush = "push"
|
||||||
|
}
|
||||||
|
defaultName := util.ClusterNamespacedName{}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
old *HigressConfig
|
||||||
|
new *HigressConfig
|
||||||
|
wantErr error
|
||||||
|
wantEventPush string
|
||||||
|
wantGlobal *Global
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "default",
|
||||||
|
new: NewDefaultHigressConfig(),
|
||||||
|
old: NewDefaultHigressConfig(),
|
||||||
|
wantErr: nil,
|
||||||
|
wantEventPush: "default",
|
||||||
|
wantGlobal: NewDefaultGlobalOption(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "replace and push",
|
||||||
|
old: NewDefaultHigressConfig(),
|
||||||
|
new: &HigressConfig{
|
||||||
|
Downstream: &Downstream{
|
||||||
|
IdleTimeout: 1,
|
||||||
|
},
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
wantErr: nil,
|
||||||
|
wantEventPush: "push",
|
||||||
|
wantGlobal: &Global{
|
||||||
|
Downstream: &Downstream{
|
||||||
|
IdleTimeout: 1,
|
||||||
|
MaxRequestHeadersKb: defaultMaxRequestHeadersKb,
|
||||||
|
ConnectionBufferLimits: defaultConnectionBufferLimits,
|
||||||
|
Http2: NewDefaultHttp2(),
|
||||||
|
},
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "delete and push",
|
||||||
|
old: &HigressConfig{
|
||||||
|
Downstream: NewDefaultDownstream(),
|
||||||
|
AddXRealIpHeader: defaultAddXRealIpHeader,
|
||||||
|
DisableXEnvoyHeaders: defaultDisableXEnvoyHeaders,
|
||||||
|
},
|
||||||
|
new: &HigressConfig{},
|
||||||
|
wantErr: nil,
|
||||||
|
wantEventPush: "push",
|
||||||
|
wantGlobal: &Global{
|
||||||
|
Downstream: NewDefaultDownstream(),
|
||||||
|
AddXRealIpHeader: defaultAddXRealIpHeader,
|
||||||
|
DisableXEnvoyHeaders: defaultDisableXEnvoyHeaders,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
g := NewGlobalOptionController("higress-namespace")
|
||||||
|
g.eventHandler = defaultHandler
|
||||||
|
eventPush = "default"
|
||||||
|
err := g.AddOrUpdateHigressConfig(defaultName, tt.old, tt.new)
|
||||||
|
assert.Equal(t, tt.wantErr, err)
|
||||||
|
assert.Equal(t, tt.wantEventPush, eventPush)
|
||||||
|
assert.Equal(t, tt.wantGlobal, g.GetGlobal())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
package configmap
|
package configmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -130,12 +129,17 @@ func compareGzip(old *Gzip, new *Gzip) (Result, error) {
|
|||||||
|
|
||||||
func deepCopyGzip(gzip *Gzip) (*Gzip, error) {
|
func deepCopyGzip(gzip *Gzip) (*Gzip, error) {
|
||||||
newGzip := NewDefaultGzip()
|
newGzip := NewDefaultGzip()
|
||||||
bytes, err := json.Marshal(gzip)
|
newGzip.Enable = gzip.Enable
|
||||||
if err != nil {
|
newGzip.MinContentLength = gzip.MinContentLength
|
||||||
return nil, err
|
newGzip.ContentType = make([]string, 0, len(gzip.ContentType))
|
||||||
}
|
newGzip.ContentType = append(newGzip.ContentType, gzip.ContentType...)
|
||||||
err = json.Unmarshal(bytes, newGzip)
|
newGzip.DisableOnEtagHeader = gzip.DisableOnEtagHeader
|
||||||
return newGzip, err
|
newGzip.MemoryLevel = gzip.MemoryLevel
|
||||||
|
newGzip.WindowBits = gzip.WindowBits
|
||||||
|
newGzip.ChunkSize = gzip.ChunkSize
|
||||||
|
newGzip.CompressionLevel = gzip.CompressionLevel
|
||||||
|
newGzip.CompressionStrategy = gzip.CompressionStrategy
|
||||||
|
return newGzip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultGzip() *Gzip {
|
func NewDefaultGzip() *Gzip {
|
||||||
@@ -263,7 +267,7 @@ func (g *GzipController) ConstructEnvoyFilters() ([]*config.Config, error) {
|
|||||||
Filter: &networking.EnvoyFilter_ListenerMatch_FilterMatch{
|
Filter: &networking.EnvoyFilter_ListenerMatch_FilterMatch{
|
||||||
Name: "envoy.filters.network.http_connection_manager",
|
Name: "envoy.filters.network.http_connection_manager",
|
||||||
SubFilter: &networking.EnvoyFilter_ListenerMatch_SubFilterMatch{
|
SubFilter: &networking.EnvoyFilter_ListenerMatch_SubFilterMatch{
|
||||||
Name: "envoy.filters.http.router",
|
Name: "envoy.filters.http.cors",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -305,9 +309,9 @@ func (g *GzipController) constructGzipStruct(gzip *Gzip, namespace string) strin
|
|||||||
"response_direction_config": {
|
"response_direction_config": {
|
||||||
"common_config": {
|
"common_config": {
|
||||||
"min_content_length": %d,
|
"min_content_length": %d,
|
||||||
"content_type": [%s],
|
"content_type": [%s]
|
||||||
"disable_on_etag_header": %t
|
},
|
||||||
}
|
"disable_on_etag_header": %t
|
||||||
},
|
},
|
||||||
"request_direction_config": {
|
"request_direction_config": {
|
||||||
"common_config": {
|
"common_config": {
|
||||||
|
|||||||
@@ -277,27 +277,54 @@ func Test_deepCopyGzip(t *testing.T) {
|
|||||||
wantErr error
|
wantErr error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "deep copy",
|
name: "deep copy case 1",
|
||||||
gzip: &Gzip{
|
gzip: &Gzip{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
MinContentLength: 1024,
|
MinContentLength: 102,
|
||||||
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
ContentType: []string{"text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
||||||
DisableOnEtagHeader: true,
|
DisableOnEtagHeader: false,
|
||||||
MemoryLevel: 5,
|
MemoryLevel: 6,
|
||||||
WindowBits: 12,
|
WindowBits: 11,
|
||||||
ChunkSize: 4096,
|
ChunkSize: 4096,
|
||||||
CompressionLevel: "BEST_COMPRESSION",
|
CompressionLevel: "BEST_SPEED",
|
||||||
CompressionStrategy: "DEFAULT_STRATEGY",
|
CompressionStrategy: "DEFAULT_STRATEGY",
|
||||||
},
|
},
|
||||||
wantGzip: &Gzip{
|
wantGzip: &Gzip{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
MinContentLength: 1024,
|
MinContentLength: 102,
|
||||||
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
ContentType: []string{"text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
||||||
DisableOnEtagHeader: true,
|
DisableOnEtagHeader: false,
|
||||||
MemoryLevel: 5,
|
MemoryLevel: 6,
|
||||||
WindowBits: 12,
|
WindowBits: 11,
|
||||||
ChunkSize: 4096,
|
ChunkSize: 4096,
|
||||||
CompressionLevel: "BEST_COMPRESSION",
|
CompressionLevel: "BEST_SPEED",
|
||||||
|
CompressionStrategy: "DEFAULT_STRATEGY",
|
||||||
|
},
|
||||||
|
wantErr: nil,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "deep copy case 2",
|
||||||
|
gzip: &Gzip{
|
||||||
|
Enable: true,
|
||||||
|
MinContentLength: 102,
|
||||||
|
ContentType: []string{"text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
||||||
|
DisableOnEtagHeader: true,
|
||||||
|
MemoryLevel: 6,
|
||||||
|
WindowBits: 11,
|
||||||
|
ChunkSize: 4096,
|
||||||
|
CompressionLevel: "BEST_SPEED",
|
||||||
|
CompressionStrategy: "DEFAULT_STRATEGY",
|
||||||
|
},
|
||||||
|
wantGzip: &Gzip{
|
||||||
|
Enable: true,
|
||||||
|
MinContentLength: 102,
|
||||||
|
ContentType: []string{"text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
||||||
|
DisableOnEtagHeader: true,
|
||||||
|
MemoryLevel: 6,
|
||||||
|
WindowBits: 11,
|
||||||
|
ChunkSize: 4096,
|
||||||
|
CompressionLevel: "BEST_SPEED",
|
||||||
CompressionStrategy: "DEFAULT_STRATEGY",
|
CompressionStrategy: "DEFAULT_STRATEGY",
|
||||||
},
|
},
|
||||||
wantErr: nil,
|
wantErr: nil,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||||
@@ -292,19 +293,19 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config BasicAuthConfig, log w
|
|||||||
}
|
}
|
||||||
|
|
||||||
func deniedNoBasicAuthData() types.Action {
|
func deniedNoBasicAuthData() types.Action {
|
||||||
_ = proxywasm.SendHttpResponse(401, WWWAuthenticateHeader(protectionSpace),
|
_ = proxywasm.SendHttpResponse(http.StatusUnauthorized, WWWAuthenticateHeader(protectionSpace),
|
||||||
[]byte("Request denied by Basic Auth check. No Basic Authentication information found."), -1)
|
[]byte("Request denied by Basic Auth check. No Basic Authentication information found."), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func deniedInvalidCredentials() types.Action {
|
func deniedInvalidCredentials() types.Action {
|
||||||
_ = proxywasm.SendHttpResponse(401, WWWAuthenticateHeader(protectionSpace),
|
_ = proxywasm.SendHttpResponse(http.StatusUnauthorized, WWWAuthenticateHeader(protectionSpace),
|
||||||
[]byte("Request denied by Basic Auth check. Invalid username and/or password."), -1)
|
[]byte("Request denied by Basic Auth check. Invalid username and/or password."), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func deniedUnauthorizedConsumer() types.Action {
|
func deniedUnauthorizedConsumer() types.Action {
|
||||||
_ = proxywasm.SendHttpResponse(403, WWWAuthenticateHeader(protectionSpace),
|
_ = proxywasm.SendHttpResponse(http.StatusForbidden, WWWAuthenticateHeader(protectionSpace),
|
||||||
[]byte("Request denied by Basic Auth check. Unauthorized consumer."), -1)
|
[]byte("Request denied by Basic Auth check. Unauthorized consumer."), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,20 +92,20 @@ const bodyTemplate string = `
|
|||||||
|
|
||||||
func onHttpRequestHeaders(ctx wrapper.HttpContext, config MyConfig, log wrapper.Log) types.Action {
|
func onHttpRequestHeaders(ctx wrapper.HttpContext, config MyConfig, log wrapper.Log) types.Action {
|
||||||
pairs := strings.SplitN(ctx.Path(), "?", 2)
|
pairs := strings.SplitN(ctx.Path(), "?", 2)
|
||||||
|
|
||||||
if len(pairs) < 2 {
|
if len(pairs) < 2 {
|
||||||
proxywasm.SendHttpResponse(400, nil, []byte("1-need prompt param"), -1)
|
proxywasm.SendHttpResponse(http.StatusBadRequest, nil, []byte("1-need prompt param"), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
querys, err := url.ParseQuery(pairs[1])
|
querys, err := url.ParseQuery(pairs[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
proxywasm.SendHttpResponse(400, nil, []byte("2-need prompt param"), -1)
|
proxywasm.SendHttpResponse(http.StatusBadRequest, nil, []byte("2-need prompt param"), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
var prompt []string
|
var prompt []string
|
||||||
var ok bool
|
var ok bool
|
||||||
if prompt, ok = querys[config.PromptParam]; !ok || len(prompt) == 0 {
|
if prompt, ok = querys[config.PromptParam]; !ok || len(prompt) == 0 {
|
||||||
proxywasm.SendHttpResponse(400, nil, []byte("3-need prompt param"), -1)
|
proxywasm.SendHttpResponse(http.StatusBadRequest, nil, []byte("3-need prompt param"), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
body := fmt.Sprintf(bodyTemplate, config.Model, prompt[0], config.HumainId, config.AIId)
|
body := fmt.Sprintf(bodyTemplate, config.Model, prompt[0], config.HumainId, config.AIId)
|
||||||
@@ -121,7 +121,7 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config MyConfig, log wrapper.
|
|||||||
proxywasm.SendHttpResponse(uint32(statusCode), headers, responseBody, -1)
|
proxywasm.SendHttpResponse(uint32(statusCode), headers, responseBody, -1)
|
||||||
}, 10000)
|
}, 10000)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
proxywasm.SendHttpResponse(500, nil, []byte("Internel Error: "+err.Error()), -1)
|
proxywasm.SendHttpResponse(http.StatusInternalServerError, nil, []byte("Internel Error: "+err.Error()), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
return types.ActionPause
|
return types.ActionPause
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"cors/config"
|
"cors/config"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
||||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
|
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
|
||||||
@@ -28,8 +30,6 @@ func main() {
|
|||||||
"cors",
|
"cors",
|
||||||
wrapper.ParseConfigBy(parseConfig),
|
wrapper.ParseConfigBy(parseConfig),
|
||||||
wrapper.ProcessRequestHeadersBy(onHttpRequestHeaders),
|
wrapper.ProcessRequestHeadersBy(onHttpRequestHeaders),
|
||||||
wrapper.ProcessRequestBodyBy(onHttpRequestBody),
|
|
||||||
wrapper.ProcessResponseBodyBy(onHttpResponseBody),
|
|
||||||
wrapper.ProcessResponseHeadersBy(onHttpResponseHeaders),
|
wrapper.ProcessResponseHeadersBy(onHttpResponseHeaders),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, corsConfig config.CorsConfig,
|
|||||||
if !httpCorsContext.IsValid {
|
if !httpCorsContext.IsValid {
|
||||||
headers := make([][2]string, 0)
|
headers := make([][2]string, 0)
|
||||||
headers = append(headers, [2]string{config.HeaderPluginTrace, "trace"})
|
headers = append(headers, [2]string{config.HeaderPluginTrace, "trace"})
|
||||||
proxywasm.SendHttpResponse(403, headers, []byte("Invalid CORS request"), -1)
|
proxywasm.SendHttpResponse(http.StatusForbidden, headers, []byte("Invalid CORS request"), -1)
|
||||||
return types.ActionPause
|
return types.ActionPause
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,18 +102,13 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, corsConfig config.CorsConfig,
|
|||||||
if httpCorsContext.IsPreFlight {
|
if httpCorsContext.IsPreFlight {
|
||||||
headers := make([][2]string, 0)
|
headers := make([][2]string, 0)
|
||||||
headers = append(headers, [2]string{config.HeaderPluginTrace, "trace"})
|
headers = append(headers, [2]string{config.HeaderPluginTrace, "trace"})
|
||||||
proxywasm.SendHttpResponse(200, headers, nil, -1)
|
proxywasm.SendHttpResponse(http.StatusOK, headers, nil, -1)
|
||||||
return types.ActionPause
|
return types.ActionPause
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func onHttpRequestBody(ctx wrapper.HttpContext, corsConfig config.CorsConfig, body []byte, log wrapper.Log) types.Action {
|
|
||||||
log.Debug("onHttpRequestBody()")
|
|
||||||
return types.ActionContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
func onHttpResponseHeaders(ctx wrapper.HttpContext, corsConfig config.CorsConfig, log wrapper.Log) types.Action {
|
func onHttpResponseHeaders(ctx wrapper.HttpContext, corsConfig config.CorsConfig, log wrapper.Log) types.Action {
|
||||||
log.Debug("onHttpResponseHeaders()")
|
log.Debug("onHttpResponseHeaders()")
|
||||||
// Remove trace header if existed
|
// Remove trace header if existed
|
||||||
@@ -162,8 +157,3 @@ func onHttpResponseHeaders(ctx wrapper.HttpContext, corsConfig config.CorsConfig
|
|||||||
|
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func onHttpResponseBody(ctx wrapper.HttpContext, corsConfig config.CorsConfig, body []byte, log wrapper.Log) types.Action {
|
|
||||||
log.Debug("onHttpResponseBody()")
|
|
||||||
return types.ActionContinue
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
. "github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
. "github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||||
@@ -34,6 +35,6 @@ func onHttpRequestHeaders(ctx HttpContext, config MyConfig, log Log) types.Actio
|
|||||||
log.Infof("alloc success, point address: %p", b)
|
log.Infof("alloc success, point address: %p", b)
|
||||||
memstats := fmt.Sprintf(`{"Sys": %d,"HeapSys": %d,"HeapIdle": %d,"HeapInuse": %d,"HeapReleased": %d}`, m.Sys, m.HeapSys, m.HeapIdle, m.HeapInuse, m.HeapReleased)
|
memstats := fmt.Sprintf(`{"Sys": %d,"HeapSys": %d,"HeapIdle": %d,"HeapInuse": %d,"HeapReleased": %d}`, m.Sys, m.HeapSys, m.HeapIdle, m.HeapInuse, m.HeapReleased)
|
||||||
log.Info(memstats)
|
log.Info(memstats)
|
||||||
proxywasm.SendHttpResponse(200, [][2]string{{"Content-Type", "application/json"}}, []byte(memstats), -1)
|
proxywasm.SendHttpResponse(http.StatusOK, [][2]string{{"Content-Type", "application/json"}}, []byte(memstats), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
||||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
|
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
|
||||||
|
|
||||||
@@ -36,6 +38,6 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config HelloWorldConfig, log
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Critical("failed to set request header")
|
log.Critical("failed to set request header")
|
||||||
}
|
}
|
||||||
proxywasm.SendHttpResponse(200, nil, []byte("hello world"), -1)
|
proxywasm.SendHttpResponse(http.StatusOK, nil, []byte("hello world"), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||||
@@ -74,9 +75,11 @@ type Consumer struct {
|
|||||||
// credential: token1
|
// credential: token1
|
||||||
// - name: consumer2
|
// - name: consumer2
|
||||||
// credential: token2
|
// credential: token2
|
||||||
|
//
|
||||||
// keys:
|
// keys:
|
||||||
// - x-api-key
|
// - x-api-key
|
||||||
// - token
|
// - token
|
||||||
|
//
|
||||||
// in_query: true
|
// in_query: true
|
||||||
// @End
|
// @End
|
||||||
type KeyAuthConfig struct {
|
type KeyAuthConfig struct {
|
||||||
@@ -319,19 +322,19 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config KeyAuthConfig, log wra
|
|||||||
}
|
}
|
||||||
|
|
||||||
func deniedMutiKeyAuthData() types.Action {
|
func deniedMutiKeyAuthData() types.Action {
|
||||||
_ = proxywasm.SendHttpResponse(401, WWWAuthenticateHeader(protectionSpace),
|
_ = proxywasm.SendHttpResponse(http.StatusUnauthorized, WWWAuthenticateHeader(protectionSpace),
|
||||||
[]byte("Request denied by Key Auth check. Muti Key Authentication information found."), -1)
|
[]byte("Request denied by Key Auth check. Muti Key Authentication information found."), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func deniedNoKeyAuthData() types.Action {
|
func deniedNoKeyAuthData() types.Action {
|
||||||
_ = proxywasm.SendHttpResponse(401, WWWAuthenticateHeader(protectionSpace),
|
_ = proxywasm.SendHttpResponse(http.StatusUnauthorized, WWWAuthenticateHeader(protectionSpace),
|
||||||
[]byte("Request denied by Key Auth check. No Key Authentication information found."), -1)
|
[]byte("Request denied by Key Auth check. No Key Authentication information found."), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func deniedUnauthorizedConsumer() types.Action {
|
func deniedUnauthorizedConsumer() types.Action {
|
||||||
_ = proxywasm.SendHttpResponse(403, WWWAuthenticateHeader(protectionSpace),
|
_ = proxywasm.SendHttpResponse(http.StatusForbidden, WWWAuthenticateHeader(protectionSpace),
|
||||||
[]byte("Request denied by Key Auth check. Unauthorized consumer."), -1)
|
[]byte("Request denied by Key Auth check. Unauthorized consumer."), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
||||||
@@ -39,19 +41,19 @@ func parseConfig(json gjson.Result, config *Config, log wrapper.Log) error {
|
|||||||
func onHttpRequestHeaders(ctx wrapper.HttpContext, config Config, log wrapper.Log) types.Action {
|
func onHttpRequestHeaders(ctx wrapper.HttpContext, config Config, log wrapper.Log) types.Action {
|
||||||
var res Res
|
var res Res
|
||||||
if config.TokenHeaders == "" || config.TokenSecretKey == "" {
|
if config.TokenHeaders == "" || config.TokenSecretKey == "" {
|
||||||
res.Code = 401
|
res.Code = http.StatusBadRequest
|
||||||
res.Msg = "参数不足"
|
res.Msg = "token or secret 不允许为空"
|
||||||
data, _ := json.Marshal(res)
|
data, _ := json.Marshal(res)
|
||||||
_ = proxywasm.SendHttpResponse(401, nil, data, -1)
|
_ = proxywasm.SendHttpResponse(http.StatusUnauthorized, nil, data, -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := proxywasm.GetHttpRequestHeader(config.TokenHeaders)
|
token, err := proxywasm.GetHttpRequestHeader(config.TokenHeaders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.Code = 401
|
res.Code = http.StatusUnauthorized
|
||||||
res.Msg = "认证失败"
|
res.Msg = "认证失败"
|
||||||
data, _ := json.Marshal(res)
|
data, _ := json.Marshal(res)
|
||||||
_ = proxywasm.SendHttpResponse(401, nil, data, -1)
|
_ = proxywasm.SendHttpResponse(http.StatusUnauthorized, nil, data, -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
valid := ParseTokenValid(token, config.TokenSecretKey)
|
valid := ParseTokenValid(token, config.TokenSecretKey)
|
||||||
@@ -59,10 +61,10 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config Config, log wrapper.Lo
|
|||||||
_ = proxywasm.ResumeHttpRequest()
|
_ = proxywasm.ResumeHttpRequest()
|
||||||
return types.ActionPause
|
return types.ActionPause
|
||||||
} else {
|
} else {
|
||||||
res.Code = 401
|
res.Code = http.StatusUnauthorized
|
||||||
res.Msg = "认证失败"
|
res.Msg = "认证失败"
|
||||||
data, _ := json.Marshal(res)
|
data, _ := json.Marshal(res)
|
||||||
_ = proxywasm.SendHttpResponse(401, nil, data, -1)
|
_ = proxywasm.SendHttpResponse(http.StatusUnauthorized, nil, data, -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
plugins/wasm-go/extensions/sni-misdirect/VERSION
Normal file
1
plugins/wasm-go/extensions/sni-misdirect/VERSION
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
14
plugins/wasm-go/extensions/sni-misdirect/go.mod
Normal file
14
plugins/wasm-go/extensions/sni-misdirect/go.mod
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
module wasm_go/higress/plugins/wasm-go/extensions/sni_misdirect
|
||||||
|
|
||||||
|
go 1.19
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/alibaba/higress/plugins/wasm-go v1.3.1
|
||||||
|
github.com/tetratelabs/proxy-wasm-go-sdk v0.22.0
|
||||||
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520 // indirect
|
||||||
|
github.com/magefile/mage v1.14.0 // indirect
|
||||||
|
github.com/tidwall/gjson v1.14.3 // indirect
|
||||||
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
|
)
|
||||||
20
plugins/wasm-go/extensions/sni-misdirect/go.sum
Normal file
20
plugins/wasm-go/extensions/sni-misdirect/go.sum
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
github.com/alibaba/higress/plugins/wasm-go v1.3.1 h1:d+t4W2NyqmqUz6DPZENflODfkLgdVlTfyso+nq0fSkg=
|
||||||
|
github.com/alibaba/higress/plugins/wasm-go v1.3.1/go.mod h1:WZ/68vwe8qWhusa6C4/gMwUqas0jvHWSOa1bp8iK8F4=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520 h1:IHDghbGQ2DTIXHBHxWfqCYQW1fKjyJ/I7W1pMyUDeEA=
|
||||||
|
github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520/go.mod h1:Nz8ORLaFiLWotg6GeKlJMhv8cci8mM43uEnLA5t8iew=
|
||||||
|
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
|
||||||
|
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
|
github.com/tetratelabs/proxy-wasm-go-sdk v0.22.0 h1:kS7BvMKN+FiptV4pfwiNX8e3q14evxAWkhYbxt8EI1M=
|
||||||
|
github.com/tetratelabs/proxy-wasm-go-sdk v0.22.0/go.mod h1:qkW5MBz2jch2u8bS59wws65WC+Gtx3x0aPUX5JL7CXI=
|
||||||
|
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
|
||||||
|
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
95
plugins/wasm-go/extensions/sni-misdirect/main.go
Normal file
95
plugins/wasm-go/extensions/sni-misdirect/main.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||||
|
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
||||||
|
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
wrapper.SetCtx(
|
||||||
|
"sni-misdirect",
|
||||||
|
wrapper.ProcessRequestHeadersBy(onHttpRequestHeaders),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func onHttpRequestHeaders(ctx wrapper.HttpContext, config Config, log wrapper.Log) types.Action {
|
||||||
|
// no need to check HTTP/1.0 and HTTP/1.1
|
||||||
|
protocol, err := proxywasm.GetProperty([]string{"request", "protocol"})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get request protocol: %v", err)
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(string(protocol), "HTTP/1") {
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
// no need to check http scheme
|
||||||
|
scheme := ctx.Scheme()
|
||||||
|
if scheme != "https" {
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
// no need to check grpc
|
||||||
|
contentType, err := proxywasm.GetHttpRequestHeader("content-type")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get request content-type: %v", err)
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(contentType, "application/grpc") {
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
// get sni
|
||||||
|
sni, err := proxywasm.GetProperty([]string{"connection", "requested_server_name"})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get requested_server_name: %v", err)
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
// get authority
|
||||||
|
host, err := proxywasm.GetHttpRequestHeader(":authority")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get request authority: %v", err)
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
host = stripPortFromHost(host)
|
||||||
|
if string(sni) == host {
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(string(sni), "*.") {
|
||||||
|
proxywasm.SendHttpResponse(http.StatusMisdirectedRequest, nil, []byte("Misdirected Request"), -1)
|
||||||
|
return types.ActionPause
|
||||||
|
}
|
||||||
|
if !strings.Contains(host, string(sni)[1:]) {
|
||||||
|
proxywasm.SendHttpResponse(http.StatusMisdirectedRequest, nil, []byte("Misdirected Request"), -1)
|
||||||
|
return types.ActionPause
|
||||||
|
}
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
func stripPortFromHost(requestHost string) string {
|
||||||
|
// Find the last occurrence of ':' to locate the port.
|
||||||
|
portStart := strings.LastIndex(requestHost, ":")
|
||||||
|
|
||||||
|
// Check if ':' is found.
|
||||||
|
if portStart != -1 {
|
||||||
|
// According to RFC3986, IPv6 address is always enclosed in "[]".
|
||||||
|
// section 3.2.2.
|
||||||
|
v6EndIndex := strings.LastIndex(requestHost, "]")
|
||||||
|
|
||||||
|
// Check if ']' is found and its position is after the ':'.
|
||||||
|
if v6EndIndex == -1 || v6EndIndex < portStart {
|
||||||
|
// Check if there are characters after ':'.
|
||||||
|
if portStart+1 <= len(requestHost) {
|
||||||
|
// Return the substring without the port.
|
||||||
|
return requestHost[:portStart]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no port is found or the conditions are not met, return the original requestHost.
|
||||||
|
return requestHost
|
||||||
|
}
|
||||||
562
test/e2e/conformance/tests/configmap-global.go
Normal file
562
test/e2e/conformance/tests/configmap-global.go
Normal file
@@ -0,0 +1,562 @@
|
|||||||
|
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/pkg/ingress/kube/configmap"
|
||||||
|
"github.com/alibaba/higress/test/e2e/conformance/utils/envoy"
|
||||||
|
"github.com/alibaba/higress/test/e2e/conformance/utils/kubernetes"
|
||||||
|
"github.com/alibaba/higress/test/e2e/conformance/utils/suite"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register(ConfigMapGlobalEnvoy)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ConfigMapGlobalEnvoy = suite.ConformanceTest{
|
||||||
|
ShortName: "ConfigMapGlobalEnvoy",
|
||||||
|
Description: "The Envoy config should contain global config",
|
||||||
|
Manifests: []string{"tests/configmap-global.yaml"},
|
||||||
|
Features: []suite.SupportedFeature{suite.EnvoyConfigConformanceFeature},
|
||||||
|
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
higressConfig *configmap.HigressConfig
|
||||||
|
envoyAssertion []envoy.Assertion
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "set config all",
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Downstream: &configmap.Downstream{
|
||||||
|
IdleTimeout: 180,
|
||||||
|
MaxRequestHeadersKb: 60,
|
||||||
|
ConnectionBufferLimits: 32768,
|
||||||
|
Http2: &configmap.Http2{
|
||||||
|
MaxConcurrentStreams: 100,
|
||||||
|
InitialStreamWindowSize: 65535,
|
||||||
|
InitialConnectionWindowSize: 1048576,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
},
|
||||||
|
envoyAssertion: []envoy.Assertion{
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_route_configs.#.route_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"request_headers_to_add": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"append": false,
|
||||||
|
"header": map[string]interface{}{
|
||||||
|
"key": "x-real-ip",
|
||||||
|
"value": "%REQ(X-ENVOY-EXTERNAL-ADDRESS)%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config.http_filters",
|
||||||
|
CheckType: envoy.CheckTypeMatch,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"name": "envoy.filters.http.router",
|
||||||
|
"typed_config": map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router",
|
||||||
|
"suppress_envoy_headers": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"per_connection_buffer_limit_bytes": 32768,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"http2_protocol_options": map[string]interface{}{
|
||||||
|
"max_concurrent_streams": 100,
|
||||||
|
"initial_stream_window_size": 65535,
|
||||||
|
"initial_connection_window_size": 1048576,
|
||||||
|
},
|
||||||
|
"stream_idle_timeout": "180s",
|
||||||
|
"max_request_headers_kb": 60,
|
||||||
|
"common_http_protocol_options": map[string]interface{}{
|
||||||
|
"idle_timeout": "180s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "did not set AddXRealIpHeader",
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Downstream: &configmap.Downstream{
|
||||||
|
IdleTimeout: 180,
|
||||||
|
MaxRequestHeadersKb: 60,
|
||||||
|
ConnectionBufferLimits: 32768,
|
||||||
|
Http2: &configmap.Http2{
|
||||||
|
MaxConcurrentStreams: 100,
|
||||||
|
InitialStreamWindowSize: 65535,
|
||||||
|
InitialConnectionWindowSize: 1048576,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
},
|
||||||
|
envoyAssertion: []envoy.Assertion{
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_route_configs.#.route_config.request_headers_to_add.#.header",
|
||||||
|
CheckType: envoy.CheckTypeNotExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"key": "x-real-ip",
|
||||||
|
"value": "%REQ(X-ENVOY-EXTERNAL-ADDRESS)%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config.http_filters",
|
||||||
|
CheckType: envoy.CheckTypeMatch,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"name": "envoy.filters.http.router",
|
||||||
|
"typed_config": map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router",
|
||||||
|
"suppress_envoy_headers": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"per_connection_buffer_limit_bytes": 32768,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"http2_protocol_options": map[string]interface{}{
|
||||||
|
"max_concurrent_streams": 100,
|
||||||
|
"initial_stream_window_size": 65535,
|
||||||
|
"initial_connection_window_size": 1048576,
|
||||||
|
},
|
||||||
|
"stream_idle_timeout": "180s",
|
||||||
|
"max_request_headers_kb": 60,
|
||||||
|
"common_http_protocol_options": map[string]interface{}{
|
||||||
|
"idle_timeout": "180s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "did not set DisableXEnvoyHeaders",
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Downstream: &configmap.Downstream{
|
||||||
|
IdleTimeout: 180,
|
||||||
|
MaxRequestHeadersKb: 60,
|
||||||
|
ConnectionBufferLimits: 32768,
|
||||||
|
Http2: &configmap.Http2{
|
||||||
|
MaxConcurrentStreams: 100,
|
||||||
|
InitialStreamWindowSize: 65535,
|
||||||
|
InitialConnectionWindowSize: 1048576,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
},
|
||||||
|
envoyAssertion: []envoy.Assertion{
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_route_configs.#.route_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"request_headers_to_add": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"append": false,
|
||||||
|
"header": map[string]interface{}{
|
||||||
|
"key": "x-real-ip",
|
||||||
|
"value": "%REQ(X-ENVOY-EXTERNAL-ADDRESS)%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config.http_filters",
|
||||||
|
CheckType: envoy.CheckTypeNotExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"typed_config": map[string]interface{}{
|
||||||
|
"suppress_envoy_headers": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"per_connection_buffer_limit_bytes": 32768,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"http2_protocol_options": map[string]interface{}{
|
||||||
|
"max_concurrent_streams": 100,
|
||||||
|
"initial_stream_window_size": 65535,
|
||||||
|
"initial_connection_window_size": 1048576,
|
||||||
|
},
|
||||||
|
"stream_idle_timeout": "180s",
|
||||||
|
"max_request_headers_kb": 60,
|
||||||
|
"common_http_protocol_options": map[string]interface{}{
|
||||||
|
"idle_timeout": "180s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "did not set AddXRealIpHeader and DisableXEnvoyHeaders",
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Downstream: &configmap.Downstream{
|
||||||
|
IdleTimeout: 180,
|
||||||
|
MaxRequestHeadersKb: 60,
|
||||||
|
ConnectionBufferLimits: 32768,
|
||||||
|
Http2: &configmap.Http2{
|
||||||
|
MaxConcurrentStreams: 100,
|
||||||
|
InitialStreamWindowSize: 65535,
|
||||||
|
InitialConnectionWindowSize: 1048576,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
envoyAssertion: []envoy.Assertion{
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_route_configs.#.route_config.request_headers_to_add.#.header",
|
||||||
|
CheckType: envoy.CheckTypeNotExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"key": "x-real-ip",
|
||||||
|
"value": "%REQ(X-ENVOY-EXTERNAL-ADDRESS)%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config.http_filters",
|
||||||
|
CheckType: envoy.CheckTypeNotExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"typed_config": map[string]interface{}{
|
||||||
|
"suppress_envoy_headers": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"per_connection_buffer_limit_bytes": 32768,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"http2_protocol_options": map[string]interface{}{
|
||||||
|
"max_concurrent_streams": 100,
|
||||||
|
"initial_stream_window_size": 65535,
|
||||||
|
"initial_connection_window_size": 1048576,
|
||||||
|
},
|
||||||
|
"stream_idle_timeout": "180s",
|
||||||
|
"max_request_headers_kb": 60,
|
||||||
|
"common_http_protocol_options": map[string]interface{}{
|
||||||
|
"idle_timeout": "180s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "did not set Downstream, will use default value",
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
},
|
||||||
|
envoyAssertion: []envoy.Assertion{
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_route_configs.#.route_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"request_headers_to_add": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"append": false,
|
||||||
|
"header": map[string]interface{}{
|
||||||
|
"key": "x-real-ip",
|
||||||
|
"value": "%REQ(X-ENVOY-EXTERNAL-ADDRESS)%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config.http_filters",
|
||||||
|
CheckType: envoy.CheckTypeMatch,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"name": "envoy.filters.http.router",
|
||||||
|
"typed_config": map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router",
|
||||||
|
"suppress_envoy_headers": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"per_connection_buffer_limit_bytes": 32768,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"max_concurrent_streams": 100,
|
||||||
|
"initial_stream_window_size": 65535,
|
||||||
|
"initial_connection_window_size": 1048576,
|
||||||
|
"stream_idle_timeout": "180s",
|
||||||
|
"max_request_headers_kb": 60,
|
||||||
|
"idle_timeout": "180s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "modify Downstream",
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Downstream: &configmap.Downstream{
|
||||||
|
IdleTimeout: 200,
|
||||||
|
MaxRequestHeadersKb: 60,
|
||||||
|
ConnectionBufferLimits: 32768,
|
||||||
|
Http2: &configmap.Http2{
|
||||||
|
MaxConcurrentStreams: 200,
|
||||||
|
InitialStreamWindowSize: 65535,
|
||||||
|
InitialConnectionWindowSize: 1048576,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DisableXEnvoyHeaders: true,
|
||||||
|
AddXRealIpHeader: true,
|
||||||
|
},
|
||||||
|
envoyAssertion: []envoy.Assertion{
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_route_configs.#.route_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"request_headers_to_add": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"append": false,
|
||||||
|
"header": map[string]interface{}{
|
||||||
|
"key": "x-real-ip",
|
||||||
|
"value": "%REQ(X-ENVOY-EXTERNAL-ADDRESS)%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config.http_filters",
|
||||||
|
CheckType: envoy.CheckTypeMatch,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"name": "envoy.filters.http.router",
|
||||||
|
"typed_config": map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router",
|
||||||
|
"suppress_envoy_headers": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"per_connection_buffer_limit_bytes": 32768,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"http2_protocol_options": map[string]interface{}{
|
||||||
|
"max_concurrent_streams": 200,
|
||||||
|
"initial_stream_window_size": 65535,
|
||||||
|
"initial_connection_window_size": 1048576,
|
||||||
|
},
|
||||||
|
"stream_idle_timeout": "200s",
|
||||||
|
"max_request_headers_kb": 60,
|
||||||
|
"common_http_protocol_options": map[string]interface{}{
|
||||||
|
"idle_timeout": "200s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "did not set global config, downstream will use default value",
|
||||||
|
higressConfig: &configmap.HigressConfig{},
|
||||||
|
envoyAssertion: []envoy.Assertion{
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_route_configs.#.route_config.request_headers_to_add.#.header",
|
||||||
|
CheckType: envoy.CheckTypeNotExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"key": "x-real-ip",
|
||||||
|
"value": "%REQ(X-ENVOY-EXTERNAL-ADDRESS)%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config.http_filters",
|
||||||
|
CheckType: envoy.CheckTypeNotExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"typed_config": map[string]interface{}{
|
||||||
|
"suppress_envoy_headers": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"per_connection_buffer_limit_bytes": 32768,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains.#.filters.#.typed_config",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"max_concurrent_streams": 100,
|
||||||
|
"initial_stream_window_size": 65535,
|
||||||
|
"initial_connection_window_size": 1048576,
|
||||||
|
"stream_idle_timeout": "180s",
|
||||||
|
"max_request_headers_kb": 60,
|
||||||
|
"idle_timeout": "180s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("ConfigMap Global Envoy", func(t *testing.T) {
|
||||||
|
for _, testcase := range testCases {
|
||||||
|
// apply config
|
||||||
|
err := kubernetes.ApplyConfigmapDataWithYaml(t, suite.Client, "higress-system", "higress-config", "higress", testcase.higressConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("can't apply conifgmap %s in namespace %s for data key %s", "higress-config", "higress-system", "higress")
|
||||||
|
}
|
||||||
|
t.Logf("Checking Envoy config for test case %s", testcase.name)
|
||||||
|
for _, assertion := range testcase.envoyAssertion {
|
||||||
|
envoy.AssertEnvoyConfig(t, suite.TimeoutConfig, assertion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
32
test/e2e/conformance/tests/configmap-global.yaml
Normal file
32
test/e2e/conformance/tests/configmap-global.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: higress-conformance-infra-configmap-global-test
|
||||||
|
namespace: higress-conformance-infra
|
||||||
|
spec:
|
||||||
|
ingressClassName: higress
|
||||||
|
rules:
|
||||||
|
- host: "foo.com"
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- pathType: Prefix
|
||||||
|
path: "/foo"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: infra-backend-v3
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/alibaba/higress/pkg/ingress/kube/configmap"
|
"github.com/alibaba/higress/pkg/ingress/kube/configmap"
|
||||||
|
"github.com/alibaba/higress/test/e2e/conformance/utils/envoy"
|
||||||
"github.com/alibaba/higress/test/e2e/conformance/utils/http"
|
"github.com/alibaba/higress/test/e2e/conformance/utils/http"
|
||||||
"github.com/alibaba/higress/test/e2e/conformance/utils/kubernetes"
|
"github.com/alibaba/higress/test/e2e/conformance/utils/kubernetes"
|
||||||
"github.com/alibaba/higress/test/e2e/conformance/utils/suite"
|
"github.com/alibaba/higress/test/e2e/conformance/utils/suite"
|
||||||
@@ -25,6 +26,266 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Register(ConfigmapGzip)
|
Register(ConfigmapGzip)
|
||||||
|
Register(ConfigMapGzipEnvoy)
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCases = []struct {
|
||||||
|
higressConfig *configmap.HigressConfig
|
||||||
|
envoyAssertion envoy.Assertion
|
||||||
|
httpAssert http.Assertion
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Gzip: &configmap.Gzip{
|
||||||
|
Enable: false,
|
||||||
|
MinContentLength: 1024,
|
||||||
|
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
||||||
|
DisableOnEtagHeader: true,
|
||||||
|
MemoryLevel: 5,
|
||||||
|
WindowBits: 12,
|
||||||
|
ChunkSize: 4096,
|
||||||
|
CompressionLevel: "BEST_COMPRESSION",
|
||||||
|
CompressionStrategy: "DEFAULT_STRATEGY",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
httpAssert: http.Assertion{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TestCaseName: "case1: disable gzip output",
|
||||||
|
TargetBackend: "web-backend",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/foo",
|
||||||
|
Method: "GET",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Accept-Encoding": "*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponseNoRequest: true,
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
AbsentHeaders: []string{"content-encoding"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
envoyAssertion: envoy.Assertion{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains",
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
CheckType: envoy.CheckTypeNotExist,
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"memory_level": 5,
|
||||||
|
"compression_level": "COMPRESSION_LEVEL_9",
|
||||||
|
"window_bits": 12,
|
||||||
|
"min_content_length": 1024,
|
||||||
|
"disable_on_etag_header": true,
|
||||||
|
"content_type": []interface{}{
|
||||||
|
"text/html",
|
||||||
|
"text/css",
|
||||||
|
"text/plain",
|
||||||
|
"text/xml",
|
||||||
|
"application/json",
|
||||||
|
"application/javascript",
|
||||||
|
"application/xhtml+xml",
|
||||||
|
"image/svg+xml",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Gzip: &configmap.Gzip{
|
||||||
|
Enable: true,
|
||||||
|
MinContentLength: 100,
|
||||||
|
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
||||||
|
DisableOnEtagHeader: true,
|
||||||
|
MemoryLevel: 5,
|
||||||
|
WindowBits: 12,
|
||||||
|
ChunkSize: 4096,
|
||||||
|
CompressionLevel: "BEST_COMPRESSION",
|
||||||
|
CompressionStrategy: "DEFAULT_STRATEGY",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
httpAssert: http.Assertion{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TestCaseName: "case2: enable gzip output",
|
||||||
|
TargetBackend: "web-backend",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/foo",
|
||||||
|
Method: "GET",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Accept-Encoding": "*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponseNoRequest: true,
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
},
|
||||||
|
AdditionalResponseHeaders: map[string]string{"content-encoding": "gzip"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
envoyAssertion: envoy.Assertion{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains",
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"name": "envoy.filters.network.http_connection_manager",
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
"memory_level": 5,
|
||||||
|
"compression_level": "COMPRESSION_LEVEL_9",
|
||||||
|
"window_bits": 12,
|
||||||
|
"min_content_length": 100,
|
||||||
|
"disable_on_etag_header": true,
|
||||||
|
"content_type": []interface{}{
|
||||||
|
"text/html",
|
||||||
|
"text/css",
|
||||||
|
"text/plain",
|
||||||
|
"text/xml",
|
||||||
|
"application/json",
|
||||||
|
"application/javascript",
|
||||||
|
"application/xhtml+xml",
|
||||||
|
"image/svg+xml",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Gzip: &configmap.Gzip{
|
||||||
|
Enable: true,
|
||||||
|
MinContentLength: 4096,
|
||||||
|
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
||||||
|
DisableOnEtagHeader: true,
|
||||||
|
MemoryLevel: 5,
|
||||||
|
WindowBits: 12,
|
||||||
|
ChunkSize: 4096,
|
||||||
|
CompressionLevel: "BEST_COMPRESSION",
|
||||||
|
CompressionStrategy: "DEFAULT_STRATEGY",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
httpAssert: http.Assertion{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TestCaseName: "case3: disable gzip output because content length less hhan 4096 ",
|
||||||
|
TargetBackend: "web-backend",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/foo",
|
||||||
|
Method: "GET",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Accept-Encoding": "*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponseNoRequest: true,
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
AbsentHeaders: []string{"content-encoding"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
envoyAssertion: envoy.Assertion{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains",
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"name": "envoy.filters.network.http_connection_manager",
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
"memory_level": 5,
|
||||||
|
"compression_level": "COMPRESSION_LEVEL_9",
|
||||||
|
"window_bits": 12,
|
||||||
|
"min_content_length": 4096,
|
||||||
|
"disable_on_etag_header": true,
|
||||||
|
"content_type": []interface{}{
|
||||||
|
"text/html",
|
||||||
|
"text/css",
|
||||||
|
"text/plain",
|
||||||
|
"text/xml",
|
||||||
|
"application/json",
|
||||||
|
"application/javascript",
|
||||||
|
"application/xhtml+xml",
|
||||||
|
"image/svg+xml",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
higressConfig: &configmap.HigressConfig{
|
||||||
|
Gzip: &configmap.Gzip{
|
||||||
|
Enable: true,
|
||||||
|
MinContentLength: 100,
|
||||||
|
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
||||||
|
DisableOnEtagHeader: true,
|
||||||
|
MemoryLevel: 5,
|
||||||
|
WindowBits: 12,
|
||||||
|
ChunkSize: 4096,
|
||||||
|
CompressionLevel: "BEST_COMPRESSION",
|
||||||
|
CompressionStrategy: "DEFAULT_STRATEGY",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
httpAssert: http.Assertion{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TestCaseName: "case4: disable gzip output because application/json missed in content types ",
|
||||||
|
TargetBackend: "web-backend",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/foo",
|
||||||
|
Method: "GET",
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Accept-Encoding": "*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponseNoRequest: true,
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
AbsentHeaders: []string{"content-encoding"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
envoyAssertion: envoy.Assertion{
|
||||||
|
Path: "configs.#.dynamic_listeners.#.active_state.listener.filter_chains",
|
||||||
|
TargetNamespace: "higress-system",
|
||||||
|
CheckType: envoy.CheckTypeExist,
|
||||||
|
ExpectEnvoyConfig: map[string]interface{}{
|
||||||
|
"name": "envoy.filters.network.http_connection_manager",
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||||
|
"stat_prefix": "outbound_0.0.0.0_80",
|
||||||
|
"memory_level": 5,
|
||||||
|
"compression_level": "COMPRESSION_LEVEL_9",
|
||||||
|
"window_bits": 12,
|
||||||
|
"min_content_length": 100,
|
||||||
|
"disable_on_etag_header": true,
|
||||||
|
"content_type": []interface{}{
|
||||||
|
"text/html",
|
||||||
|
"text/css",
|
||||||
|
"text/plain",
|
||||||
|
"text/xml",
|
||||||
|
"application/javascript",
|
||||||
|
"application/xhtml+xml",
|
||||||
|
"image/svg+xml",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var ConfigmapGzip = suite.ConformanceTest{
|
var ConfigmapGzip = suite.ConformanceTest{
|
||||||
@@ -33,171 +294,9 @@ var ConfigmapGzip = suite.ConformanceTest{
|
|||||||
Manifests: []string{"tests/configmap-gzip.yaml"},
|
Manifests: []string{"tests/configmap-gzip.yaml"},
|
||||||
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
|
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
|
||||||
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
|
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
|
||||||
testcases := []struct {
|
|
||||||
higressConfig *configmap.HigressConfig
|
|
||||||
httpAssert http.Assertion
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
higressConfig: &configmap.HigressConfig{
|
|
||||||
Gzip: &configmap.Gzip{
|
|
||||||
Enable: false,
|
|
||||||
MinContentLength: 1024,
|
|
||||||
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
|
||||||
DisableOnEtagHeader: true,
|
|
||||||
MemoryLevel: 5,
|
|
||||||
WindowBits: 12,
|
|
||||||
ChunkSize: 4096,
|
|
||||||
CompressionLevel: "BEST_COMPRESSION",
|
|
||||||
CompressionStrategy: "DEFAULT_STRATEGY",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
httpAssert: http.Assertion{
|
|
||||||
Meta: http.AssertionMeta{
|
|
||||||
TestCaseName: "case1: disable gzip output",
|
|
||||||
TargetBackend: "web-backend",
|
|
||||||
TargetNamespace: "higress-conformance-infra",
|
|
||||||
},
|
|
||||||
Request: http.AssertionRequest{
|
|
||||||
ActualRequest: http.Request{
|
|
||||||
Host: "foo.com",
|
|
||||||
Path: "/foo",
|
|
||||||
Method: "GET",
|
|
||||||
Headers: map[string]string{
|
|
||||||
"Accept-Encoding": "*",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Response: http.AssertionResponse{
|
|
||||||
ExpectedResponseNoRequest: true,
|
|
||||||
ExpectedResponse: http.Response{
|
|
||||||
StatusCode: 200,
|
|
||||||
AbsentHeaders: []string{"content-encoding"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
higressConfig: &configmap.HigressConfig{
|
|
||||||
Gzip: &configmap.Gzip{
|
|
||||||
Enable: true,
|
|
||||||
MinContentLength: 100,
|
|
||||||
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
|
||||||
DisableOnEtagHeader: true,
|
|
||||||
MemoryLevel: 5,
|
|
||||||
WindowBits: 12,
|
|
||||||
ChunkSize: 4096,
|
|
||||||
CompressionLevel: "BEST_COMPRESSION",
|
|
||||||
CompressionStrategy: "DEFAULT_STRATEGY",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
httpAssert: http.Assertion{
|
|
||||||
Meta: http.AssertionMeta{
|
|
||||||
TestCaseName: "case2: enable gzip output",
|
|
||||||
TargetBackend: "web-backend",
|
|
||||||
TargetNamespace: "higress-conformance-infra",
|
|
||||||
},
|
|
||||||
Request: http.AssertionRequest{
|
|
||||||
ActualRequest: http.Request{
|
|
||||||
Host: "foo.com",
|
|
||||||
Path: "/foo",
|
|
||||||
Method: "GET",
|
|
||||||
Headers: map[string]string{
|
|
||||||
"Accept-Encoding": "*",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Response: http.AssertionResponse{
|
|
||||||
ExpectedResponseNoRequest: true,
|
|
||||||
ExpectedResponse: http.Response{
|
|
||||||
StatusCode: 200,
|
|
||||||
},
|
|
||||||
AdditionalResponseHeaders: map[string]string{"content-encoding": "gzip"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
higressConfig: &configmap.HigressConfig{
|
|
||||||
Gzip: &configmap.Gzip{
|
|
||||||
Enable: true,
|
|
||||||
MinContentLength: 4096,
|
|
||||||
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/json", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
|
||||||
DisableOnEtagHeader: true,
|
|
||||||
MemoryLevel: 5,
|
|
||||||
WindowBits: 12,
|
|
||||||
ChunkSize: 4096,
|
|
||||||
CompressionLevel: "BEST_COMPRESSION",
|
|
||||||
CompressionStrategy: "DEFAULT_STRATEGY",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
httpAssert: http.Assertion{
|
|
||||||
Meta: http.AssertionMeta{
|
|
||||||
TestCaseName: "case3: disable gzip output because content length less hhan 4096 ",
|
|
||||||
TargetBackend: "web-backend",
|
|
||||||
TargetNamespace: "higress-conformance-infra",
|
|
||||||
},
|
|
||||||
Request: http.AssertionRequest{
|
|
||||||
ActualRequest: http.Request{
|
|
||||||
Host: "foo.com",
|
|
||||||
Path: "/foo",
|
|
||||||
Method: "GET",
|
|
||||||
Headers: map[string]string{
|
|
||||||
"Accept-Encoding": "*",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Response: http.AssertionResponse{
|
|
||||||
ExpectedResponseNoRequest: true,
|
|
||||||
ExpectedResponse: http.Response{
|
|
||||||
StatusCode: 200,
|
|
||||||
AbsentHeaders: []string{"content-encoding"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
higressConfig: &configmap.HigressConfig{
|
|
||||||
Gzip: &configmap.Gzip{
|
|
||||||
Enable: true,
|
|
||||||
MinContentLength: 100,
|
|
||||||
ContentType: []string{"text/html", "text/css", "text/plain", "text/xml", "application/javascript", "application/xhtml+xml", "image/svg+xml"},
|
|
||||||
DisableOnEtagHeader: true,
|
|
||||||
MemoryLevel: 5,
|
|
||||||
WindowBits: 12,
|
|
||||||
ChunkSize: 4096,
|
|
||||||
CompressionLevel: "BEST_COMPRESSION",
|
|
||||||
CompressionStrategy: "DEFAULT_STRATEGY",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
httpAssert: http.Assertion{
|
|
||||||
Meta: http.AssertionMeta{
|
|
||||||
TestCaseName: "case4: disable gzip output because application/json missed in content types ",
|
|
||||||
TargetBackend: "web-backend",
|
|
||||||
TargetNamespace: "higress-conformance-infra",
|
|
||||||
},
|
|
||||||
Request: http.AssertionRequest{
|
|
||||||
ActualRequest: http.Request{
|
|
||||||
Host: "foo.com",
|
|
||||||
Path: "/foo",
|
|
||||||
Method: "GET",
|
|
||||||
Headers: map[string]string{
|
|
||||||
"Accept-Encoding": "*",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Response: http.AssertionResponse{
|
|
||||||
ExpectedResponseNoRequest: true,
|
|
||||||
ExpectedResponse: http.Response{
|
|
||||||
StatusCode: 200,
|
|
||||||
AbsentHeaders: []string{"content-encoding"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("Configmap Gzip", func(t *testing.T) {
|
t.Run("Configmap Gzip", func(t *testing.T) {
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testCases {
|
||||||
err := kubernetes.ApplyConfigmapDataWithYaml(suite.Client, "higress-system", "higress-config", "higress", testcase.higressConfig)
|
err := kubernetes.ApplyConfigmapDataWithYaml(t, suite.Client, "higress-system", "higress-config", "higress", testcase.higressConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't apply conifgmap %s in namespace %s for data key %s", "higress-config", "higress-system", "higress")
|
t.Fatalf("can't apply conifgmap %s in namespace %s for data key %s", "higress-config", "higress-system", "higress")
|
||||||
}
|
}
|
||||||
@@ -206,3 +305,22 @@ var ConfigmapGzip = suite.ConformanceTest{
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ConfigMapGzipEnvoy = suite.ConformanceTest{
|
||||||
|
ShortName: "ConfigMapGzipEnvoy",
|
||||||
|
Description: "The Envoy config should contain gzip config",
|
||||||
|
Manifests: []string{"tests/configmap-gzip.yaml"},
|
||||||
|
Features: []suite.SupportedFeature{suite.EnvoyConfigConformanceFeature},
|
||||||
|
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
|
||||||
|
t.Run("ConfigMap Gzip Envoy", func(t *testing.T) {
|
||||||
|
for _, testcase := range testCases {
|
||||||
|
// apply config
|
||||||
|
err := kubernetes.ApplyConfigmapDataWithYaml(t, suite.Client, "higress-system", "higress-config", "higress", testcase.higressConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("can't apply conifgmap %s in namespace %s for data key %s", "higress-config", "higress-system", "higress")
|
||||||
|
}
|
||||||
|
envoy.AssertEnvoyConfig(t, suite.TimeoutConfig, testcase.envoyAssertion)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,4 +29,5 @@ spec:
|
|||||||
service:
|
service:
|
||||||
name: infra-backend-v3
|
name: infra-backend-v3
|
||||||
port:
|
port:
|
||||||
number: 8080
|
number: 8080
|
||||||
|
|
||||||
|
|||||||
100
test/e2e/conformance/tests/go-wasm-sni-misdirect.go
Normal file
100
test/e2e/conformance/tests/go-wasm-sni-misdirect.go
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/test/e2e/conformance/utils/cert"
|
||||||
|
"github.com/alibaba/higress/test/e2e/conformance/utils/http"
|
||||||
|
"github.com/alibaba/higress/test/e2e/conformance/utils/kubernetes"
|
||||||
|
"github.com/alibaba/higress/test/e2e/conformance/utils/suite"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register(WasmPluginsSniMisdirect)
|
||||||
|
}
|
||||||
|
|
||||||
|
var WasmPluginsSniMisdirect = suite.ConformanceTest{
|
||||||
|
ShortName: "WasmPluginsSniMisdirect",
|
||||||
|
Description: "The Ingress in the higress-conformance-infra namespace test the sni-misdirect wasmplugins.",
|
||||||
|
Manifests: []string{"tests/go-wasm-sni-misdirect.yaml"},
|
||||||
|
Features: []suite.SupportedFeature{suite.WASMGoConformanceFeature},
|
||||||
|
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
|
||||||
|
// Prepare certificates and secrets for testcases
|
||||||
|
caCertOut, _, caCert, caKey := cert.MustGenerateCaCert(t)
|
||||||
|
svcCertOut, svcKeyOut := cert.MustGenerateCertWithCA(t, cert.ServerCertType, caCert, caKey, []string{"foo.com"})
|
||||||
|
cliCertOut, cliKeyOut := cert.MustGenerateCertWithCA(t, cert.ClientCertType, caCert, caKey, nil)
|
||||||
|
fooSecret := kubernetes.ConstructTLSSecret("higress-conformance-infra", "foo-secret", svcCertOut.Bytes(), svcKeyOut.Bytes())
|
||||||
|
fooSecretCACert := kubernetes.ConstructCASecret("higress-conformance-infra", "foo-secret-cacert", caCertOut.Bytes())
|
||||||
|
suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{fooSecret, fooSecretCACert}, suite.Cleanup)
|
||||||
|
|
||||||
|
testcases := []http.Assertion{
|
||||||
|
{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TestCaseName: "case 1: http1.1 request",
|
||||||
|
TargetBackend: "infra-backend-v1",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TestCaseName: "case 2: https/1.1 request with sni and same with host",
|
||||||
|
TargetBackend: "infra-backend-v1",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/foo",
|
||||||
|
TLSConfig: &http.TLSConfig{
|
||||||
|
SNI: "foo.com",
|
||||||
|
Certificates: http.Certificates{
|
||||||
|
CACerts: [][]byte{caCertOut.Bytes()},
|
||||||
|
ClientKeyPairs: []http.ClientKeyPair{{
|
||||||
|
ClientCert: cliCertOut.Bytes(),
|
||||||
|
ClientKey: cliKeyOut.Bytes()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("WasmPlugin sni-misdirect", func(t *testing.T) {
|
||||||
|
for _, testcase := range testcases {
|
||||||
|
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, suite.GatewayAddress, testcase)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
46
test/e2e/conformance/tests/go-wasm-sni-misdirect.yaml
Normal file
46
test/e2e/conformance/tests/go-wasm-sni-misdirect.yaml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
higress.io/auth-tls-secret: foo-secret-cacert
|
||||||
|
name: wasmplugin-sni-misdirect
|
||||||
|
namespace: higress-conformance-infra
|
||||||
|
spec:
|
||||||
|
ingressClassName: higress
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- "foo.com"
|
||||||
|
secretName: foo-secret
|
||||||
|
rules:
|
||||||
|
- host: "foo.com"
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- pathType: Exact
|
||||||
|
path: "/foo"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: infra-backend-v1
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
|
---
|
||||||
|
apiVersion: extensions.higress.io/v1alpha1
|
||||||
|
kind: WasmPlugin
|
||||||
|
metadata:
|
||||||
|
name: sni-misdirect
|
||||||
|
namespace: higress-system
|
||||||
|
spec:
|
||||||
|
url: file:///opt/plugins/wasm-go/extensions/sni-misdirect/plugin.wasm
|
||||||
295
test/e2e/conformance/utils/envoy/envoy.go
Normal file
295
test/e2e/conformance/utils/envoy/envoy.go
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 The Kubernetes Authors.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package envoy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/alibaba/higress/cmd/hgctl/config"
|
||||||
|
cfg "github.com/alibaba/higress/test/e2e/conformance/utils/config"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CheckType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CheckTypeMatch checks if the actual value matches the expected value.
|
||||||
|
CheckTypeMatch CheckType = "match"
|
||||||
|
// CheckTypeExist checks if the actual value exists.
|
||||||
|
CheckTypeExist CheckType = "exist"
|
||||||
|
// CheckTypeNotExist checks if the actual value does not exist.
|
||||||
|
CheckTypeNotExist CheckType = "notexist"
|
||||||
|
|
||||||
|
// defaultSuccessThreshold is the default number of times the assertion must succeed in a row.
|
||||||
|
defaultSuccessThreshold = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// Assertion defines the assertion to be made on the Envoy config.
|
||||||
|
// TODO: It can support localization judgment so that this configuration check function will be more universal.
|
||||||
|
// TODO: Can be used for general e2e tests, rather than just envoy filter scenarios.
|
||||||
|
type Assertion struct {
|
||||||
|
// Path is the path of gjson to the value to be asserted.
|
||||||
|
Path string
|
||||||
|
// CheckType is the type of assertion to be made.
|
||||||
|
CheckType CheckType
|
||||||
|
// ExpectEnvoyConfig is the expected value of the Envoy config.
|
||||||
|
ExpectEnvoyConfig map[string]interface{}
|
||||||
|
// TargetNamespace is the namespace of the Envoy pod.
|
||||||
|
TargetNamespace string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssertEnvoyConfig asserts the Envoy config.
|
||||||
|
func AssertEnvoyConfig(t *testing.T, timeoutConfig cfg.TimeoutConfig, expected Assertion) {
|
||||||
|
options := config.NewDefaultGetEnvoyConfigOptions()
|
||||||
|
options.PodNamespace = expected.TargetNamespace
|
||||||
|
convertEnvoyConfig := convertNumbersToFloat64(expected.ExpectEnvoyConfig)
|
||||||
|
if _, ok := convertEnvoyConfig.(map[string]interface{}); !ok {
|
||||||
|
t.Errorf("failed to convert envoy config number to float64")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
expected.ExpectEnvoyConfig = convertEnvoyConfig.(map[string]interface{})
|
||||||
|
waitForEnvoyConfig(t, timeoutConfig, options, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertNumbersToFloat64(data interface{}) interface{} {
|
||||||
|
switch val := data.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
result := make(map[string]interface{})
|
||||||
|
for key, v := range val {
|
||||||
|
result[key] = convertNumbersToFloat64(v)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
case []interface{}:
|
||||||
|
result := make([]interface{}, len(val))
|
||||||
|
for i, v := range val {
|
||||||
|
result[i] = convertNumbersToFloat64(v)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
case float64:
|
||||||
|
return val
|
||||||
|
case int:
|
||||||
|
return float64(val)
|
||||||
|
case int64:
|
||||||
|
return float64(val)
|
||||||
|
case float32:
|
||||||
|
return float64(val)
|
||||||
|
default:
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// waitForEnvoyConfig waits for the Envoy config to be ready and asserts it.
|
||||||
|
func waitForEnvoyConfig(t *testing.T, timeoutConfig cfg.TimeoutConfig, options *config.GetEnvoyConfigOptions, expected Assertion) {
|
||||||
|
awaitConvergence(t, defaultSuccessThreshold, timeoutConfig.MaxTimeToConsistency, func(elapsed time.Duration) bool {
|
||||||
|
allEnvoyConfig := ""
|
||||||
|
err := wait.Poll(1*time.Second, 10*time.Second, func() (bool, error) {
|
||||||
|
out, err := config.GetEnvoyConfig(options)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
allEnvoyConfig = string(out)
|
||||||
|
return true, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch expected.CheckType {
|
||||||
|
case CheckTypeMatch:
|
||||||
|
err = assertEnvoyConfigMatch(t, allEnvoyConfig, expected)
|
||||||
|
case CheckTypeExist:
|
||||||
|
err = assertEnvoyConfigExist(t, allEnvoyConfig, expected)
|
||||||
|
case CheckTypeNotExist:
|
||||||
|
err = assertEnvoyConfigNotExist(t, allEnvoyConfig, expected)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unsupported check type %s", expected.CheckType)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
t.Logf("✅ Envoy config checked")
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertEnvoyConfigNotExist asserts the Envoy config does not exist.
|
||||||
|
func assertEnvoyConfigNotExist(t *testing.T, envoyConfig string, expected Assertion) error {
|
||||||
|
result := gjson.Get(envoyConfig, expected.Path).Value()
|
||||||
|
if result == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !findMustNotExist(t, result, expected.ExpectEnvoyConfig) {
|
||||||
|
return fmt.Errorf("the expected value %s exists in path '%s'", expected.ExpectEnvoyConfig, expected.Path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertEnvoyConfigExist asserts the Envoy config exists.
|
||||||
|
func assertEnvoyConfigExist(t *testing.T, envoyConfig string, expected Assertion) error {
|
||||||
|
result := gjson.Get(envoyConfig, expected.Path).Value()
|
||||||
|
if result == nil {
|
||||||
|
return fmt.Errorf("failed to get value from path '%s'", expected.Path)
|
||||||
|
}
|
||||||
|
if !findMustExist(t, result, expected.ExpectEnvoyConfig) {
|
||||||
|
return fmt.Errorf("the expected value %s does not exist in path '%s'", expected.ExpectEnvoyConfig, expected.Path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertEnvoyConfigMatch asserts the Envoy config matches the expected value.
|
||||||
|
func assertEnvoyConfigMatch(t *testing.T, envoyConfig string, expected Assertion) error {
|
||||||
|
result := gjson.Get(envoyConfig, expected.Path).Value()
|
||||||
|
if result == nil {
|
||||||
|
return fmt.Errorf("failed to get value from path '%s'", expected.Path)
|
||||||
|
}
|
||||||
|
if !match(t, result, expected.ExpectEnvoyConfig) {
|
||||||
|
return fmt.Errorf("failed to match value from path '%s'", expected.Path)
|
||||||
|
}
|
||||||
|
t.Logf("✅ Matched value %s in path '%s'", expected.ExpectEnvoyConfig, expected.Path)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// awaitConvergence runs the given function until it returns 'true' `threshold` times in a row.
|
||||||
|
// Each failed attempt has a 1s delay; successful attempts have no delay.
|
||||||
|
func awaitConvergence(t *testing.T, threshold int, maxTimeToConsistency time.Duration, fn func(elapsed time.Duration) bool) {
|
||||||
|
successes := 0
|
||||||
|
attempts := 0
|
||||||
|
start := time.Now()
|
||||||
|
to := time.After(maxTimeToConsistency)
|
||||||
|
delay := time.Second
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-to:
|
||||||
|
t.Fatalf("timeout while waiting after %d attempts", attempts)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
completed := fn(time.Now().Sub(start))
|
||||||
|
attempts++
|
||||||
|
if completed {
|
||||||
|
successes++
|
||||||
|
if successes >= threshold {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Skip delay if we have a success
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
successes = 0
|
||||||
|
select {
|
||||||
|
// Capture the overall timeout
|
||||||
|
case <-to:
|
||||||
|
t.Fatalf("timeout while waiting after %d attempts, %d/%d sucessess", attempts, successes, threshold)
|
||||||
|
// And the per-try delay
|
||||||
|
case <-time.After(delay):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// match
|
||||||
|
// 1. interface{} is a slice: if one of the slice elements matches, the assertion passes
|
||||||
|
// Notice: can recursively find slices
|
||||||
|
// 2. interface{} is a map: if all the map elements match, the assertion passes
|
||||||
|
// 3. interface{} is a field: if the field matches, the assertion passes
|
||||||
|
func match(t *testing.T, actual interface{}, expected map[string]interface{}) bool {
|
||||||
|
reflectValue := reflect.ValueOf(actual)
|
||||||
|
kind := reflectValue.Kind()
|
||||||
|
switch kind {
|
||||||
|
case reflect.Slice:
|
||||||
|
actualValueSlice := actual.([]interface{})
|
||||||
|
for _, v := range actualValueSlice {
|
||||||
|
if match(t, v, expected) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
case reflect.Map:
|
||||||
|
actualValueMap := actual.(map[string]interface{})
|
||||||
|
for key, expectValue := range expected {
|
||||||
|
actualValue, ok := actualValueMap[key]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(actualValue, expectValue) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return reflect.DeepEqual(actual, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// findMustExist finds the value of the given path in the given Envoy config.
|
||||||
|
func findMustExist(t *testing.T, actual interface{}, expected map[string]interface{}) bool {
|
||||||
|
for key, expectValue := range expected {
|
||||||
|
// If the key does not exist, the assertion fails.
|
||||||
|
t.Logf("🔍 Finding key %s", key)
|
||||||
|
if !findKey(actual, key, expectValue) {
|
||||||
|
t.Logf("❌ Not found key %s", key)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
t.Logf("✅ Found key %s", key)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// findMustNotExist finds the value of the given path in the given Envoy config.
|
||||||
|
func findMustNotExist(t *testing.T, actual interface{}, expected map[string]interface{}) bool {
|
||||||
|
for key, expectValue := range expected {
|
||||||
|
// If the key exists, the assertion fails.
|
||||||
|
t.Logf("🔍 Finding key %s", key)
|
||||||
|
if findKey(actual, key, expectValue) {
|
||||||
|
t.Logf("❌ Found key %s", key)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
t.Logf("✅ Not found key %s", key)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// findKey finds the value of the given key in the given Envoy config.
|
||||||
|
func findKey(actual interface{}, key string, expectValue interface{}) bool {
|
||||||
|
reflectValue := reflect.ValueOf(actual)
|
||||||
|
kind := reflectValue.Kind()
|
||||||
|
switch kind {
|
||||||
|
case reflect.Slice:
|
||||||
|
actualValueSlice := actual.([]interface{})
|
||||||
|
for _, v := range actualValueSlice {
|
||||||
|
if findKey(v, key, expectValue) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
case reflect.Map:
|
||||||
|
actualValueMap := actual.(map[string]interface{})
|
||||||
|
for actualKey, actualValue := range actualValueMap {
|
||||||
|
if actualKey == key && reflect.DeepEqual(actualValue, expectValue) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if findKey(actualValue, key, expectValue) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
if reflectValue.String() == key && reflect.DeepEqual(actual, expectValue) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
462
test/e2e/conformance/utils/envoy/envoy_test.go
Normal file
462
test/e2e/conformance/utils/envoy/envoy_test.go
Normal file
@@ -0,0 +1,462 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 The Kubernetes Authors.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package envoy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_match(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
actual interface{}
|
||||||
|
expected map[string]interface{}
|
||||||
|
expectResult bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "case 1",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 2",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bay",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 3",
|
||||||
|
actual: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"bar": "baz",
|
||||||
|
"baz": "bay",
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 4",
|
||||||
|
actual: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 5",
|
||||||
|
actual: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 6",
|
||||||
|
actual: []interface{}{
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 7",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
result := match(t, testCase.actual, testCase.expected)
|
||||||
|
if result != testCase.expectResult {
|
||||||
|
t.Errorf("expected %v, got %v", testCase.expectResult, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_findMustExist(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
actual interface{}
|
||||||
|
expected map[string]interface{}
|
||||||
|
expectResult bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "case 1",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 2",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 3",
|
||||||
|
actual: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"bar": "baz",
|
||||||
|
"baz": "bay",
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 4",
|
||||||
|
actual: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 5",
|
||||||
|
actual: []interface{}{
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 6",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 7",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"test": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"test": "baz",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 8",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"test": "baz",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
"test": "baz",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 9",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 9",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"content": []interface{}{
|
||||||
|
"one",
|
||||||
|
"two",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
"content": []interface{}{
|
||||||
|
"one",
|
||||||
|
"two",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
result := findMustExist(t, testCase.actual, testCase.expected)
|
||||||
|
if result != testCase.expectResult {
|
||||||
|
t.Errorf("expected %v, got %v", testCase.expectResult, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_findMustNotExist(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
actual interface{}
|
||||||
|
expected map[string]interface{}
|
||||||
|
expectResult bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "case 1",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 2",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 3",
|
||||||
|
actual: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"bar": "baz",
|
||||||
|
"baz": "bay",
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 4",
|
||||||
|
actual: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 5",
|
||||||
|
actual: []interface{}{
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 6",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 7",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"test": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 8",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"test": "baz",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
"test": "baz",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "case 9",
|
||||||
|
actual: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
expectResult: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
result := findMustNotExist(t, testCase.actual, testCase.expected)
|
||||||
|
if result != testCase.expectResult {
|
||||||
|
t.Errorf("expected %v, got %v", testCase.expectResult, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,4 +26,5 @@ var (
|
|||||||
IsWasmPluginTest = flag.Bool("isWasmPluginTest", false, "Determine if run wasm plugin conformance test")
|
IsWasmPluginTest = flag.Bool("isWasmPluginTest", false, "Determine if run wasm plugin conformance test")
|
||||||
WasmPluginType = flag.String("wasmPluginType", "GO", "Define wasm plugin type, currently supports GO, CPP")
|
WasmPluginType = flag.String("wasmPluginType", "GO", "Define wasm plugin type, currently supports GO, CPP")
|
||||||
WasmPluginName = flag.String("wasmPluginName", "", "Define wasm plugin name")
|
WasmPluginName = flag.String("wasmPluginName", "", "Define wasm plugin name")
|
||||||
|
IsEnvoyConfigTest = flag.Bool("isEnvoyConfigTest", false, "Determine if run envoy config conformance test")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ func FindPodConditionInList(t *testing.T, conditions []v1.PodCondition, condName
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func ApplyConfigmapDataWithYaml(c client.Client, namespace string, name string, key string, val any) error {
|
func ApplyConfigmapDataWithYaml(t *testing.T, c client.Client, namespace string, name string, key string, val any) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -140,8 +140,11 @@ func ApplyConfigmapDataWithYaml(c client.Client, namespace string, name string,
|
|||||||
}
|
}
|
||||||
cm.Data[key] = data
|
cm.Data[key] = data
|
||||||
|
|
||||||
|
t.Logf("🏗 Updating %s %s", name, namespace)
|
||||||
|
|
||||||
if err := c.Update(ctx, cm); err != nil {
|
if err := c.Update(ctx, cm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ const (
|
|||||||
EurekaConformanceFeature SupportedFeature = "eureka"
|
EurekaConformanceFeature SupportedFeature = "eureka"
|
||||||
ConsulConformanceFeature SupportedFeature = "consul"
|
ConsulConformanceFeature SupportedFeature = "consul"
|
||||||
NacosConformanceFeature SupportedFeature = "nacos"
|
NacosConformanceFeature SupportedFeature = "nacos"
|
||||||
|
|
||||||
|
// extended: envoy config
|
||||||
|
EnvoyConfigConformanceFeature SupportedFeature = "envoy-config"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AllFeatures = sets.Set{}.
|
var AllFeatures = sets.Set{}.
|
||||||
@@ -38,7 +41,8 @@ var AllFeatures = sets.Set{}.
|
|||||||
Insert(string(DubboConformanceFeature)).
|
Insert(string(DubboConformanceFeature)).
|
||||||
Insert(string(EurekaConformanceFeature)).
|
Insert(string(EurekaConformanceFeature)).
|
||||||
Insert(string(ConsulConformanceFeature)).
|
Insert(string(ConsulConformanceFeature)).
|
||||||
Insert(string(NacosConformanceFeature))
|
Insert(string(NacosConformanceFeature)).
|
||||||
|
Insert(string(EnvoyConfigConformanceFeature))
|
||||||
|
|
||||||
var ExperimentFeatures = sets.Set{}.
|
var ExperimentFeatures = sets.Set{}.
|
||||||
Insert(string(WASMGoConformanceFeature)).
|
Insert(string(WASMGoConformanceFeature)).
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ type Options struct {
|
|||||||
// resources such as Gateways should be cleaned up after the run.
|
// resources such as Gateways should be cleaned up after the run.
|
||||||
CleanupBaseResources bool
|
CleanupBaseResources bool
|
||||||
TimeoutConfig config.TimeoutConfig
|
TimeoutConfig config.TimeoutConfig
|
||||||
|
|
||||||
|
// IsEnvoyConfigTest indicates whether or not the test is for envoy config
|
||||||
|
IsEnvoyConfigTest bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type WASMOptions struct {
|
type WASMOptions struct {
|
||||||
@@ -87,6 +90,8 @@ func New(s Options) *ConformanceTestSuite {
|
|||||||
} else {
|
} else {
|
||||||
s.SupportedFeatures.Insert(string(WASMGoConformanceFeature))
|
s.SupportedFeatures.Insert(string(WASMGoConformanceFeature))
|
||||||
}
|
}
|
||||||
|
} else if s.IsEnvoyConfigTest {
|
||||||
|
s.SupportedFeatures.Insert(string(EnvoyConfigConformanceFeature))
|
||||||
} else if s.EnableAllSupportedFeatures {
|
} else if s.EnableAllSupportedFeatures {
|
||||||
s.SupportedFeatures = AllFeatures
|
s.SupportedFeatures = AllFeatures
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ func TestHigressConformanceTests(t *testing.T) {
|
|||||||
},
|
},
|
||||||
GatewayAddress: "localhost",
|
GatewayAddress: "localhost",
|
||||||
EnableAllSupportedFeatures: true,
|
EnableAllSupportedFeatures: true,
|
||||||
|
IsEnvoyConfigTest: *flags.IsEnvoyConfigTest,
|
||||||
})
|
})
|
||||||
|
|
||||||
cSuite.Setup(t)
|
cSuite.Setup(t)
|
||||||
|
|||||||
@@ -15,36 +15,37 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
: "${BINARY_NAME:="hgctl"}"
|
: "${BINARY_NAME:="hgctl"}"
|
||||||
|
: "${BINARY_NAME_WINDOWS:="hgctl.exe"}"
|
||||||
: "${hgctl_INSTALL_DIR:="/usr/local/bin"}"
|
: "${hgctl_INSTALL_DIR:="/usr/local/bin"}"
|
||||||
|
: "${hgctl_INSTALL_DIR_WINDOWS:="${USERPROFILE}/hgctl/bin"}"
|
||||||
export VERSION
|
export VERSION
|
||||||
|
|
||||||
HAS_CURL="$(type "curl" &> /dev/null && echo true || echo false)"
|
HAS_CURL="$(type "curl" &>/dev/null && echo true || echo false)"
|
||||||
HAS_WGET="$(type "wget" &> /dev/null && echo true || echo false)"
|
HAS_WGET="$(type "wget" &>/dev/null && echo true || echo false)"
|
||||||
HAS_GIT="$(type "git" &> /dev/null && echo true || echo false)"
|
HAS_GIT="$(type "git" &>/dev/null && echo true || echo false)"
|
||||||
|
|
||||||
# initArch discovers the architecture for this system.
|
# initArch discovers the architecture for this system.
|
||||||
initArch() {
|
initArch() {
|
||||||
ARCH=$(uname -m)
|
ARCH=$(uname -m)
|
||||||
case $ARCH in
|
case $ARCH in
|
||||||
armv5*) ARCH="armv5";;
|
armv5*) ARCH="armv5" ;;
|
||||||
armv6*) ARCH="armv6";;
|
armv6*) ARCH="armv6" ;;
|
||||||
armv7*) ARCH="arm";;
|
armv7*) ARCH="arm" ;;
|
||||||
aarch64) ARCH="arm64";;
|
aarch64) ARCH="arm64" ;;
|
||||||
x86) ARCH="386";;
|
x86) ARCH="386" ;;
|
||||||
x86_64) ARCH="amd64";;
|
x86_64) ARCH="amd64" ;;
|
||||||
i686) ARCH="386";;
|
i686) ARCH="386" ;;
|
||||||
i386) ARCH="386";;
|
i386) ARCH="386" ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# initOS discovers the operating system for this system.
|
# initOS discovers the operating system for this system.
|
||||||
initOS() {
|
initOS() {
|
||||||
OS="$(uname|tr '[:upper:]' '[:lower:]')"
|
OS="$(uname | tr '[:upper:]' '[:lower:]')"
|
||||||
|
|
||||||
case "$OS" in
|
case "$OS" in
|
||||||
# Minimalist GNU for Windows
|
# Minimalist GNU for Windows
|
||||||
mingw*|cygwin*) OS='windows';;
|
mingw* | cygwin*) OS='windows' ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ runAsRoot() {
|
|||||||
# verifySupported checks that the os/arch combination is supported for
|
# verifySupported checks that the os/arch combination is supported for
|
||||||
# binary builds, as well whether or not necessary tools are present.
|
# binary builds, as well whether or not necessary tools are present.
|
||||||
verifySupported() {
|
verifySupported() {
|
||||||
local supported="darwin-amd64\ndarwin-arm64\nlinux-amd64\nlinux-arm64\n"
|
local supported="darwin-amd64\ndarwin-arm64\nlinux-amd64\nlinux-arm64\nwindows-amd64\nwindows-arm64\n"
|
||||||
if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then
|
if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then
|
||||||
echo "No prebuilt binary for ${OS}-${ARCH}."
|
echo "No prebuilt binary for ${OS}-${ARCH}."
|
||||||
echo "To build from source, go to https://github.com/alibaba/higress"
|
echo "To build from source, go to https://github.com/alibaba/higress"
|
||||||
@@ -94,7 +95,7 @@ checkDesiredVersion() {
|
|||||||
# if it needs to be changed.
|
# if it needs to be changed.
|
||||||
checkhgctlInstalledVersion() {
|
checkhgctlInstalledVersion() {
|
||||||
if [[ -f "${hgctl_INSTALL_DIR}/${BINARY_NAME}" ]]; then
|
if [[ -f "${hgctl_INSTALL_DIR}/${BINARY_NAME}" ]]; then
|
||||||
version=$("${hgctl_INSTALL_DIR}/${BINARY_NAME}" version --client | grep -Eo "v[0-9]+\.[0-9]+.*" )
|
version=$("${hgctl_INSTALL_DIR}/${BINARY_NAME}" version --client | grep -Eo "v[0-9]+\.[0-9]+.*")
|
||||||
if [[ "$version" == "$VERSION" ]]; then
|
if [[ "$version" == "$VERSION" ]]; then
|
||||||
echo "hgctl ${version} is already ${VERSION:-latest}"
|
echo "hgctl ${version} is already ${VERSION:-latest}"
|
||||||
return 0
|
return 0
|
||||||
@@ -111,6 +112,9 @@ checkhgctlInstalledVersion() {
|
|||||||
# for that binary.
|
# for that binary.
|
||||||
downloadFile() {
|
downloadFile() {
|
||||||
hgctl_DIST="hgctl_${VERSION}_${OS}_${ARCH}.tar.gz"
|
hgctl_DIST="hgctl_${VERSION}_${OS}_${ARCH}.tar.gz"
|
||||||
|
if [ "${OS}" == "windows" ]; then
|
||||||
|
hgctl_DIST="hgctl_${VERSION}_${OS}_${ARCH}.zip"
|
||||||
|
fi
|
||||||
DOWNLOAD_URL="https://github.com/alibaba/higress/releases/download/$VERSION/$hgctl_DIST"
|
DOWNLOAD_URL="https://github.com/alibaba/higress/releases/download/$VERSION/$hgctl_DIST"
|
||||||
hgctl_TMP_ROOT="$(mktemp -dt hgctl-installer-XXXXXX)"
|
hgctl_TMP_ROOT="$(mktemp -dt hgctl-installer-XXXXXX)"
|
||||||
hgctl_TMP_FILE="$hgctl_TMP_ROOT/$hgctl_DIST"
|
hgctl_TMP_FILE="$hgctl_TMP_ROOT/$hgctl_DIST"
|
||||||
@@ -133,6 +137,18 @@ installFile() {
|
|||||||
echo "$BINARY_NAME installed into $hgctl_INSTALL_DIR/$BINARY_NAME"
|
echo "$BINARY_NAME installed into $hgctl_INSTALL_DIR/$BINARY_NAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# installFileWindows installs the hgctl binary for windows.
|
||||||
|
installFileWindows() {
|
||||||
|
hgctl_TMP="$hgctl_TMP_ROOT/$BINARY_NAME"
|
||||||
|
mkdir -p "$hgctl_TMP"
|
||||||
|
unzip "$hgctl_TMP_FILE" -d "$hgctl_TMP"
|
||||||
|
hgctl_TMP_BIN="$hgctl_TMP/out/${OS}_${ARCH}/hgctl.exe"
|
||||||
|
echo "Preparing to install ${BINARY_NAME} into ${hgctl_INSTALL_DIR_WINDOWS}"
|
||||||
|
mkdir -p ${hgctl_INSTALL_DIR_WINDOWS}
|
||||||
|
cp "$hgctl_TMP_BIN" "$hgctl_INSTALL_DIR_WINDOWS/$BINARY_NAME_WINDOWS"
|
||||||
|
echo "$BINARY_NAME installed into $hgctl_INSTALL_DIR_WINDOWS/$BINARY_NAME_WINDOWS"
|
||||||
|
}
|
||||||
|
|
||||||
# fail_trap is executed if an error occurs.
|
# fail_trap is executed if an error occurs.
|
||||||
fail_trap() {
|
fail_trap() {
|
||||||
result=$?
|
result=$?
|
||||||
@@ -150,9 +166,13 @@ fail_trap() {
|
|||||||
|
|
||||||
# testVersion tests the installed client to make sure it is working.
|
# testVersion tests the installed client to make sure it is working.
|
||||||
testVersion() {
|
testVersion() {
|
||||||
|
dir="$hgctl_INSTALL_DIR"
|
||||||
|
if [ "${OS}" == "windows" ]; then
|
||||||
|
dir="$hgctl_INSTALL_DIR_WINDOWS"
|
||||||
|
fi
|
||||||
set +e
|
set +e
|
||||||
if ! [ "$(command -v $BINARY_NAME)" ]; then
|
if ! [ "$(command -v $BINARY_NAME)" ]; then
|
||||||
echo "$BINARY_NAME not found. Is $hgctl_INSTALL_DIR on your PATH?"
|
echo "$BINARY_NAME not found. Is ${dir} on your PATH?"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
set -e
|
set -e
|
||||||
@@ -177,7 +197,11 @@ verifySupported
|
|||||||
checkDesiredVersion
|
checkDesiredVersion
|
||||||
if ! checkhgctlInstalledVersion; then
|
if ! checkhgctlInstalledVersion; then
|
||||||
downloadFile
|
downloadFile
|
||||||
installFile
|
if [ "${OS}" == "windows" ]; then
|
||||||
|
installFileWindows
|
||||||
|
else
|
||||||
|
installFile
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
testVersion
|
testVersion
|
||||||
cleanup
|
cleanup
|
||||||
|
|||||||
Reference in New Issue
Block a user