diff --git a/Makefile.core.mk b/Makefile.core.mk index 7100701ad..7794bf67a 100644 --- a/Makefile.core.mk +++ b/Makefile.core.mk @@ -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 diff --git a/pkg/ingress/kube/configmap/mcp_server.go b/pkg/ingress/kube/configmap/mcp_server.go index 66aa09279..46f572043 100644 --- a/pkg/ingress/kube/configmap/mcp_server.go +++ b/pkg/ingress/kube/configmap/mcp_server.go @@ -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) diff --git a/pkg/ingress/kube/configmap/mcp_server_test.go b/pkg/ingress/kube/configmap/mcp_server_test.go index c9ac19df7..e7d48e848 100644 --- a/pkg/ingress/kube/configmap/mcp_server_test.go +++ b/pkg/ingress/kube/configmap/mcp_server_test.go @@ -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"} + }] } } }`,