mirror of
https://github.com/alibaba/higress.git
synced 2026-02-06 23:21:08 +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 ?
|
||||
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
|
||||
|
||||
|
||||
@@ -328,9 +328,26 @@ func (m *McpServerController) ConstructEnvoyFilters() ([]*config.Config, error)
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
// mcp-session envoy filter
|
||||
// mcp-session envoy filter with ECDS
|
||||
mcpSessionStruct := m.constructMcpSessionStruct(mcpServer)
|
||||
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{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.EnvoyFilter,
|
||||
@@ -358,7 +375,14 @@ func (m *McpServerController) ConstructEnvoyFilters() ([]*config.Config, error)
|
||||
},
|
||||
Patch: &networking.EnvoyFilter_Patch{
|
||||
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)
|
||||
}
|
||||
|
||||
// mcp-server envoy filter
|
||||
// mcp-server envoy filter with ECDS
|
||||
mcpServerStruct := m.constructMcpServerStruct(mcpServer)
|
||||
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{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.EnvoyFilter,
|
||||
@@ -397,7 +438,14 @@ func (m *McpServerController) ConstructEnvoyFilters() ([]*config.Config, error)
|
||||
},
|
||||
Patch: &networking.EnvoyFilter_Patch{
|
||||
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)
|
||||
}
|
||||
|
||||
// Build complete configuration structure
|
||||
// Build complete configuration structure for EXTENSION_CONFIG
|
||||
return fmt.Sprintf(`{
|
||||
"name": "envoy.filters.http.golang",
|
||||
"typed_config": {
|
||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"library_id": "mcp-session",
|
||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||
"plugin_name": "mcp-session",
|
||||
"plugin_config": {
|
||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||
"value": {
|
||||
"library_id": "mcp-session",
|
||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||
"plugin_name": "mcp-session",
|
||||
"plugin_config": {
|
||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||
"value": {
|
||||
"redis": %s,
|
||||
"rate_limit": %s,
|
||||
"sse_path_suffix": "%s",
|
||||
"match_list": %s,
|
||||
"enable_user_level_server": %t
|
||||
}
|
||||
}
|
||||
"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, ","))
|
||||
}
|
||||
|
||||
// Build complete configuration structure
|
||||
// Build complete configuration structure for EXTENSION_CONFIG
|
||||
return fmt.Sprintf(`{
|
||||
"name": "envoy.filters.http.golang",
|
||||
"typed_config": {
|
||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"library_id": "mcp-server",
|
||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||
"plugin_name": "mcp-server",
|
||||
"plugin_config": {
|
||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||
"value": {
|
||||
"library_id": "mcp-server",
|
||||
"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": %s
|
||||
}
|
||||
}
|
||||
}`, servers)
|
||||
|
||||
@@ -599,29 +599,23 @@ func TestMcpServerController_constructMcpSessionStruct(t *testing.T) {
|
||||
Servers: []*SSEServer{},
|
||||
},
|
||||
wantJSON: `{
|
||||
"name": "envoy.filters.http.golang",
|
||||
"typed_config": {
|
||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"library_id": "mcp-session",
|
||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||
"plugin_name": "mcp-session",
|
||||
"plugin_config": {
|
||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||
"value": {
|
||||
"library_id": "mcp-session",
|
||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||
"plugin_name": "mcp-session",
|
||||
"plugin_config": {
|
||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||
"value": {
|
||||
"redis": {
|
||||
"address": "localhost:6379",
|
||||
"username": "",
|
||||
"password": "",
|
||||
"db": 0
|
||||
},
|
||||
"rate_limit": null,
|
||||
"sse_path_suffix": "",
|
||||
"match_list": [],
|
||||
"enable_user_level_server": false
|
||||
}
|
||||
}
|
||||
"redis": {
|
||||
"address": "localhost:6379",
|
||||
"username": "",
|
||||
"password": "",
|
||||
"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: `{
|
||||
"name": "envoy.filters.http.golang",
|
||||
"typed_config": {
|
||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"library_id": "mcp-session",
|
||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||
"plugin_name": "mcp-session",
|
||||
"plugin_config": {
|
||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||
"value": {
|
||||
"library_id": "mcp-session",
|
||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||
"plugin_name": "mcp-session",
|
||||
"plugin_config": {
|
||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||
"value": {
|
||||
"redis": {
|
||||
"address": "localhost:6379",
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
"db": 1
|
||||
},
|
||||
"rate_limit": {
|
||||
"limit": 100,
|
||||
"window": 3600,
|
||||
"white_list": ["user1","user2"]
|
||||
},
|
||||
"sse_path_suffix": "/sse",
|
||||
"match_list": [{
|
||||
"match_rule_domain": "*",
|
||||
"match_rule_path": "/test",
|
||||
"match_rule_type": "exact",
|
||||
"upstream_type": "",
|
||||
"enable_path_rewrite": false,
|
||||
"path_rewrite_prefix": ""
|
||||
},{
|
||||
"match_rule_domain": "*",
|
||||
"match_rule_path": "/sse-test-1",
|
||||
"match_rule_type": "prefix",
|
||||
"upstream_type": "sse",
|
||||
"enable_path_rewrite": false,
|
||||
"path_rewrite_prefix": ""
|
||||
},{
|
||||
"match_rule_domain": "*",
|
||||
"match_rule_path": "/sse-test-2",
|
||||
"match_rule_type": "prefix",
|
||||
"upstream_type": "sse",
|
||||
"enable_path_rewrite": true,
|
||||
"path_rewrite_prefix": "/mcp"
|
||||
}],
|
||||
"enable_user_level_server": true
|
||||
}
|
||||
}
|
||||
"redis": {
|
||||
"address": "localhost:6379",
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
"db": 1
|
||||
},
|
||||
"rate_limit": {
|
||||
"limit": 100,
|
||||
"window": 3600,
|
||||
"white_list": ["user1","user2"]
|
||||
},
|
||||
"sse_path_suffix": "/sse",
|
||||
"match_list": [{
|
||||
"match_rule_domain": "*",
|
||||
"match_rule_path": "/test",
|
||||
"match_rule_type": "exact",
|
||||
"upstream_type": "",
|
||||
"enable_path_rewrite": false,
|
||||
"path_rewrite_prefix": ""
|
||||
},{
|
||||
"match_rule_domain": "*",
|
||||
"match_rule_path": "/sse-test-1",
|
||||
"match_rule_type": "prefix",
|
||||
"upstream_type": "sse",
|
||||
"enable_path_rewrite": false,
|
||||
"path_rewrite_prefix": ""
|
||||
},{
|
||||
"match_rule_domain": "*",
|
||||
"match_rule_path": "/sse-test-2",
|
||||
"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: `{
|
||||
"name": "envoy.filters.http.golang",
|
||||
"typed_config": {
|
||||
"@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
|
||||
"type_url": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config",
|
||||
"library_id": "mcp-server",
|
||||
"library_path": "/var/lib/istio/envoy/golang-filter.so",
|
||||
"plugin_name": "mcp-server",
|
||||
"plugin_config": {
|
||||
"@type": "type.googleapis.com/xds.type.v3.TypedStruct",
|
||||
"value": {
|
||||
"library_id": "mcp-server",
|
||||
"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": [{
|
||||
"name": "test-server",
|
||||
"path": "/test",
|
||||
"type": "test",
|
||||
"domain_list": ["example.com"],
|
||||
"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