mirror of
https://github.com/alibaba/higress.git
synced 2026-04-22 04:27:26 +08:00
refactor(mcp): use ECDS for golang filter configuration to avoid connection drain (#2931)
This commit is contained in:
@@ -137,9 +137,9 @@ endif
|
|||||||
# for now docker is limited to Linux compiles - why ?
|
# for now docker is limited to Linux compiles - why ?
|
||||||
include docker/docker.mk
|
include docker/docker.mk
|
||||||
|
|
||||||
docker-build-amd64: docker.higress-amd64 ## Build and push amdd64 docker images to registry defined by $HUB and $TAG
|
docker-build-amd64: clean-higress docker.higress-amd64 ## Build and push amdd64 docker images to registry defined by $HUB and $TAG
|
||||||
|
|
||||||
docker-build: docker.higress ## Build and push docker images to registry defined by $HUB and $TAG
|
docker-build: clean-higress docker.higress ## Build and push docker images to registry defined by $HUB and $TAG
|
||||||
|
|
||||||
docker-buildx-push: clean-env docker.higress-buildx
|
docker-buildx-push: clean-env docker.higress-buildx
|
||||||
|
|
||||||
|
|||||||
@@ -328,9 +328,26 @@ func (m *McpServerController) ConstructEnvoyFilters() ([]*config.Config, error)
|
|||||||
return configs, nil
|
return configs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// mcp-session envoy filter
|
// mcp-session envoy filter with ECDS
|
||||||
mcpSessionStruct := m.constructMcpSessionStruct(mcpServer)
|
mcpSessionStruct := m.constructMcpSessionStruct(mcpServer)
|
||||||
if mcpSessionStruct != "" {
|
if mcpSessionStruct != "" {
|
||||||
|
// HTTP_FILTER configuration with config_discovery reference
|
||||||
|
sessionFilterRef := `{
|
||||||
|
"name": "golang-filter-mcp-session",
|
||||||
|
"config_discovery": {
|
||||||
|
"config_source": {
|
||||||
|
"ads": {}
|
||||||
|
},
|
||||||
|
"type_urls": ["type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config"]
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
// EXTENSION_CONFIG configuration with actual filter config
|
||||||
|
sessionExtensionConfig := fmt.Sprintf(`{
|
||||||
|
"name": "golang-filter-mcp-session",
|
||||||
|
"typed_config": %s
|
||||||
|
}`, mcpSessionStruct)
|
||||||
|
|
||||||
sessionConfig := &config.Config{
|
sessionConfig := &config.Config{
|
||||||
Meta: config.Meta{
|
Meta: config.Meta{
|
||||||
GroupVersionKind: gvk.EnvoyFilter,
|
GroupVersionKind: gvk.EnvoyFilter,
|
||||||
@@ -358,7 +375,14 @@ func (m *McpServerController) ConstructEnvoyFilters() ([]*config.Config, error)
|
|||||||
},
|
},
|
||||||
Patch: &networking.EnvoyFilter_Patch{
|
Patch: &networking.EnvoyFilter_Patch{
|
||||||
Operation: networking.EnvoyFilter_Patch_INSERT_AFTER,
|
Operation: networking.EnvoyFilter_Patch_INSERT_AFTER,
|
||||||
Value: util.BuildPatchStruct(mcpSessionStruct),
|
Value: util.BuildPatchStruct(sessionFilterRef),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ApplyTo: networking.EnvoyFilter_EXTENSION_CONFIG,
|
||||||
|
Patch: &networking.EnvoyFilter_Patch{
|
||||||
|
Operation: networking.EnvoyFilter_Patch_ADD,
|
||||||
|
Value: util.BuildPatchStruct(sessionExtensionConfig),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -367,9 +391,26 @@ func (m *McpServerController) ConstructEnvoyFilters() ([]*config.Config, error)
|
|||||||
configs = append(configs, sessionConfig)
|
configs = append(configs, sessionConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mcp-server envoy filter
|
// mcp-server envoy filter with ECDS
|
||||||
mcpServerStruct := m.constructMcpServerStruct(mcpServer)
|
mcpServerStruct := m.constructMcpServerStruct(mcpServer)
|
||||||
if mcpServerStruct != "" {
|
if mcpServerStruct != "" {
|
||||||
|
// HTTP_FILTER configuration with config_discovery reference
|
||||||
|
serverFilterRef := `{
|
||||||
|
"name": "golang-filter-mcp-server",
|
||||||
|
"config_discovery": {
|
||||||
|
"config_source": {
|
||||||
|
"ads": {}
|
||||||
|
},
|
||||||
|
"type_urls": ["type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config"]
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
// EXTENSION_CONFIG configuration with actual filter config
|
||||||
|
serverExtensionConfig := fmt.Sprintf(`{
|
||||||
|
"name": "golang-filter-mcp-server",
|
||||||
|
"typed_config": %s
|
||||||
|
}`, mcpServerStruct)
|
||||||
|
|
||||||
serverConfig := &config.Config{
|
serverConfig := &config.Config{
|
||||||
Meta: config.Meta{
|
Meta: config.Meta{
|
||||||
GroupVersionKind: gvk.EnvoyFilter,
|
GroupVersionKind: gvk.EnvoyFilter,
|
||||||
@@ -397,7 +438,14 @@ func (m *McpServerController) ConstructEnvoyFilters() ([]*config.Config, error)
|
|||||||
},
|
},
|
||||||
Patch: &networking.EnvoyFilter_Patch{
|
Patch: &networking.EnvoyFilter_Patch{
|
||||||
Operation: networking.EnvoyFilter_Patch_INSERT_BEFORE,
|
Operation: networking.EnvoyFilter_Patch_INSERT_BEFORE,
|
||||||
Value: util.BuildPatchStruct(mcpServerStruct),
|
Value: util.BuildPatchStruct(serverFilterRef),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ApplyTo: networking.EnvoyFilter_EXTENSION_CONFIG,
|
||||||
|
Patch: &networking.EnvoyFilter_Patch{
|
||||||
|
Operation: networking.EnvoyFilter_Patch_ADD,
|
||||||
|
Value: util.BuildPatchStruct(serverExtensionConfig),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -478,26 +526,20 @@ func (m *McpServerController) constructMcpSessionStruct(mcp *McpServer) string {
|
|||||||
}`, mcp.Ratelimit.Limit, mcp.Ratelimit.Window, whiteList)
|
}`, mcp.Ratelimit.Limit, mcp.Ratelimit.Window, whiteList)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build complete configuration structure
|
// Build complete configuration structure for EXTENSION_CONFIG
|
||||||
return fmt.Sprintf(`{
|
return fmt.Sprintf(`{
|
||||||
"name": "envoy.filters.http.golang",
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||||
"typed_config": {
|
"library_id": "mcp-session",
|
||||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
"plugin_name": "mcp-session",
|
||||||
|
"plugin_config": {
|
||||||
|
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||||
"value": {
|
"value": {
|
||||||
"library_id": "mcp-session",
|
"redis": %s,
|
||||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
"rate_limit": %s,
|
||||||
"plugin_name": "mcp-session",
|
"sse_path_suffix": "%s",
|
||||||
"plugin_config": {
|
"match_list": %s,
|
||||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
"enable_user_level_server": %t
|
||||||
"value": {
|
|
||||||
"redis": %s,
|
|
||||||
"rate_limit": %s,
|
|
||||||
"sse_path_suffix": "%s",
|
|
||||||
"match_list": %s,
|
|
||||||
"enable_user_level_server": %t
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
@@ -540,22 +582,16 @@ func (m *McpServerController) constructMcpServerStruct(mcp *McpServer) string {
|
|||||||
servers = fmt.Sprintf("[%s]", strings.Join(serverConfigs, ","))
|
servers = fmt.Sprintf("[%s]", strings.Join(serverConfigs, ","))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build complete configuration structure
|
// Build complete configuration structure for EXTENSION_CONFIG
|
||||||
return fmt.Sprintf(`{
|
return fmt.Sprintf(`{
|
||||||
"name": "envoy.filters.http.golang",
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||||
"typed_config": {
|
"library_id": "mcp-server",
|
||||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
"plugin_name": "mcp-server",
|
||||||
|
"plugin_config": {
|
||||||
|
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||||
"value": {
|
"value": {
|
||||||
"library_id": "mcp-server",
|
"servers": %s
|
||||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
|
||||||
"plugin_name": "mcp-server",
|
|
||||||
"plugin_config": {
|
|
||||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
|
||||||
"value": {
|
|
||||||
"servers": %s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`, servers)
|
}`, servers)
|
||||||
|
|||||||
@@ -599,29 +599,23 @@ func TestMcpServerController_constructMcpSessionStruct(t *testing.T) {
|
|||||||
Servers: []*SSEServer{},
|
Servers: []*SSEServer{},
|
||||||
},
|
},
|
||||||
wantJSON: `{
|
wantJSON: `{
|
||||||
"name": "envoy.filters.http.golang",
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||||
"typed_config": {
|
"library_id": "mcp-session",
|
||||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
"plugin_name": "mcp-session",
|
||||||
|
"plugin_config": {
|
||||||
|
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||||
"value": {
|
"value": {
|
||||||
"library_id": "mcp-session",
|
"redis": {
|
||||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
"address": "localhost:6379",
|
||||||
"plugin_name": "mcp-session",
|
"username": "",
|
||||||
"plugin_config": {
|
"password": "",
|
||||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
"db": 0
|
||||||
"value": {
|
},
|
||||||
"redis": {
|
"rate_limit": null,
|
||||||
"address": "localhost:6379",
|
"sse_path_suffix": "",
|
||||||
"username": "",
|
"match_list": [],
|
||||||
"password": "",
|
"enable_user_level_server": false
|
||||||
"db": 0
|
|
||||||
},
|
|
||||||
"rate_limit": null,
|
|
||||||
"sse_path_suffix": "",
|
|
||||||
"match_list": [],
|
|
||||||
"enable_user_level_server": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
@@ -666,54 +660,48 @@ func TestMcpServerController_constructMcpSessionStruct(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantJSON: `{
|
wantJSON: `{
|
||||||
"name": "envoy.filters.http.golang",
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||||
"typed_config": {
|
"library_id": "mcp-session",
|
||||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
"plugin_name": "mcp-session",
|
||||||
|
"plugin_config": {
|
||||||
|
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||||
"value": {
|
"value": {
|
||||||
"library_id": "mcp-session",
|
"redis": {
|
||||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
"address": "localhost:6379",
|
||||||
"plugin_name": "mcp-session",
|
"username": "user",
|
||||||
"plugin_config": {
|
"password": "pass",
|
||||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
"db": 1
|
||||||
"value": {
|
},
|
||||||
"redis": {
|
"rate_limit": {
|
||||||
"address": "localhost:6379",
|
"limit": 100,
|
||||||
"username": "user",
|
"window": 3600,
|
||||||
"password": "pass",
|
"white_list": ["user1","user2"]
|
||||||
"db": 1
|
},
|
||||||
},
|
"sse_path_suffix": "/sse",
|
||||||
"rate_limit": {
|
"match_list": [{
|
||||||
"limit": 100,
|
"match_rule_domain": "*",
|
||||||
"window": 3600,
|
"match_rule_path": "/test",
|
||||||
"white_list": ["user1","user2"]
|
"match_rule_type": "exact",
|
||||||
},
|
"upstream_type": "",
|
||||||
"sse_path_suffix": "/sse",
|
"enable_path_rewrite": false,
|
||||||
"match_list": [{
|
"path_rewrite_prefix": ""
|
||||||
"match_rule_domain": "*",
|
},{
|
||||||
"match_rule_path": "/test",
|
"match_rule_domain": "*",
|
||||||
"match_rule_type": "exact",
|
"match_rule_path": "/sse-test-1",
|
||||||
"upstream_type": "",
|
"match_rule_type": "prefix",
|
||||||
"enable_path_rewrite": false,
|
"upstream_type": "sse",
|
||||||
"path_rewrite_prefix": ""
|
"enable_path_rewrite": false,
|
||||||
},{
|
"path_rewrite_prefix": ""
|
||||||
"match_rule_domain": "*",
|
},{
|
||||||
"match_rule_path": "/sse-test-1",
|
"match_rule_domain": "*",
|
||||||
"match_rule_type": "prefix",
|
"match_rule_path": "/sse-test-2",
|
||||||
"upstream_type": "sse",
|
"match_rule_type": "prefix",
|
||||||
"enable_path_rewrite": false,
|
"upstream_type": "sse",
|
||||||
"path_rewrite_prefix": ""
|
"enable_path_rewrite": true,
|
||||||
},{
|
"path_rewrite_prefix": "/mcp"
|
||||||
"match_rule_domain": "*",
|
}],
|
||||||
"match_rule_path": "/sse-test-2",
|
"enable_user_level_server": true
|
||||||
"match_rule_type": "prefix",
|
|
||||||
"upstream_type": "sse",
|
|
||||||
"enable_path_rewrite": true,
|
|
||||||
"path_rewrite_prefix": "/mcp"
|
|
||||||
}],
|
|
||||||
"enable_user_level_server": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
@@ -762,26 +750,20 @@ func TestMcpServerController_constructMcpServerStruct(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantJSON: `{
|
wantJSON: `{
|
||||||
"name": "envoy.filters.http.golang",
|
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||||
"typed_config": {
|
"library_id": "mcp-server",
|
||||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
"plugin_name": "mcp-server",
|
||||||
|
"plugin_config": {
|
||||||
|
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||||
"value": {
|
"value": {
|
||||||
"library_id": "mcp-server",
|
"servers": [{
|
||||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
"name": "test-server",
|
||||||
"plugin_name": "mcp-server",
|
"path": "/test",
|
||||||
"plugin_config": {
|
"type": "test",
|
||||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
"domain_list": ["example.com"],
|
||||||
"value": {
|
"config": {"key":"value"}
|
||||||
"servers": [{
|
}]
|
||||||
"name": "test-server",
|
|
||||||
"path": "/test",
|
|
||||||
"type": "test",
|
|
||||||
"domain_list": ["example.com"],
|
|
||||||
"config": {"key":"value"}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
|
|||||||
Reference in New Issue
Block a user