mirror of
https://github.com/alibaba/higress.git
synced 2026-06-08 20:27:31 +08:00
feat : support mcp server auto discovery for nacos registry (#2122)
Co-authored-by: 澄潭 <zty98751@alibaba-inc.com>
This commit is contained in:
@@ -15,12 +15,21 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
higressconfig "github.com/alibaba/higress/pkg/config"
|
||||
"github.com/alibaba/higress/registry"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
extensions "istio.io/api/extensions/v1alpha1"
|
||||
"istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/pkg/log"
|
||||
|
||||
"github.com/alibaba/higress/pkg/common"
|
||||
@@ -30,6 +39,8 @@ import (
|
||||
type Cache interface {
|
||||
UpdateServiceWrapper(service string, data *ServiceWrapper)
|
||||
DeleteServiceWrapper(service string)
|
||||
UpdateConfigCache(kind config.GroupVersionKind, key string, config *config.Config, forceDelete bool)
|
||||
GetAllConfigs(kind config.GroupVersionKind) map[string]*config.Config
|
||||
PurgeStaleService()
|
||||
UpdateServiceEntryEndpointWrapper(service, ip, regionId, zoneId, protocol string, labels map[string]string)
|
||||
GetServiceByEndpoints(requestVersions, endpoints map[string]bool, versionKey string, protocol common.Protocol) map[string][]string
|
||||
@@ -44,6 +55,7 @@ func NewCache() Cache {
|
||||
return &store{
|
||||
mux: &sync.RWMutex{},
|
||||
sew: make(map[string]*ServiceWrapper),
|
||||
configs: make(map[string]map[string]*config.Config),
|
||||
toBeUpdated: make([]*ServiceWrapper, 0),
|
||||
toBeDeleted: make([]*ServiceWrapper, 0),
|
||||
ip2services: make(map[string]map[string]bool),
|
||||
@@ -54,12 +66,85 @@ func NewCache() Cache {
|
||||
type store struct {
|
||||
mux *sync.RWMutex
|
||||
sew map[string]*ServiceWrapper
|
||||
configs map[string]map[string]*config.Config
|
||||
toBeUpdated []*ServiceWrapper
|
||||
toBeDeleted []*ServiceWrapper
|
||||
ip2services map[string]map[string]bool
|
||||
deferedDelete map[string]struct{}
|
||||
}
|
||||
|
||||
func (s *store) GetAllConfigs(kind config.GroupVersionKind) map[string]*config.Config {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
cfgs, exist := s.configs[kind.String()]
|
||||
if !exist {
|
||||
return map[string]*config.Config{}
|
||||
}
|
||||
if kind == gvk.WasmPlugin {
|
||||
pluginConfig := ®istry.WasmPluginConfig{}
|
||||
var ns string
|
||||
for _, cfg := range cfgs {
|
||||
ns = cfg.Namespace
|
||||
rule := cfg.Spec.(*registry.McpServerRule)
|
||||
pluginConfig.Rules = append(pluginConfig.Rules, rule)
|
||||
}
|
||||
rulesBytes, err := json.Marshal(pluginConfig)
|
||||
if err != nil {
|
||||
log.Errorf("marshal mcp wasm plugin config error %v", err)
|
||||
return map[string]*config.Config{}
|
||||
}
|
||||
pbs := &structpb.Struct{}
|
||||
if err = protojson.Unmarshal(rulesBytes, pbs); err != nil {
|
||||
log.Errorf("unmarshal mcp wasm plugin config error %v", err)
|
||||
return map[string]*config.Config{}
|
||||
}
|
||||
wasmPlugin := &extensions.WasmPlugin{
|
||||
ImagePullPolicy: extensions.PullPolicy_Always,
|
||||
Phase: extensions.PluginPhase_UNSPECIFIED_PHASE,
|
||||
Priority: &wrapperspb.Int32Value{Value: 30},
|
||||
PluginConfig: pbs,
|
||||
Url: higressconfig.McpServerWasmImageUrl,
|
||||
}
|
||||
|
||||
return map[string]*config.Config{"wasm": &config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.WasmPlugin,
|
||||
Name: "istio-autogenerated-mcp-wasmplugin",
|
||||
Namespace: ns,
|
||||
},
|
||||
Spec: wasmPlugin,
|
||||
}}
|
||||
}
|
||||
|
||||
return cfgs
|
||||
}
|
||||
|
||||
func (s *store) UpdateConfigCache(kind config.GroupVersionKind, key string, cfg *config.Config, forceDelete bool) {
|
||||
if cfg == nil && !forceDelete {
|
||||
return
|
||||
}
|
||||
|
||||
s.mux.Lock()
|
||||
if forceDelete {
|
||||
for _, allConfigs := range s.configs {
|
||||
delete(allConfigs, key)
|
||||
}
|
||||
log.Infof("Delete config %s in cache", key)
|
||||
} else {
|
||||
if _, exist := s.configs[kind.String()]; !exist {
|
||||
s.configs[kind.String()] = make(map[string]*config.Config)
|
||||
}
|
||||
|
||||
if _, exist := s.configs[kind.String()][key]; exist {
|
||||
log.Infof("Update kind %s config %s", kind.String(), key)
|
||||
} else {
|
||||
log.Infof("Add kind %s config %s", kind.String(), key)
|
||||
}
|
||||
s.configs[kind.String()][key] = cfg
|
||||
}
|
||||
s.mux.Unlock()
|
||||
}
|
||||
|
||||
func (s *store) UpdateServiceEntryEndpointWrapper(service, ip, regionId, zoneId, protocol string, labels map[string]string) {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
@@ -226,6 +311,15 @@ func (s *store) GetAllDestinationRuleWrapper() []*ingress.WrapperDestinationRule
|
||||
drwList = append(drwList, serviceEntryWrapper.DeepCopy().DestinationRuleWrapper)
|
||||
}
|
||||
}
|
||||
configFromMcp := s.configs[gvk.DestinationRule.String()]
|
||||
for _, cfg := range configFromMcp {
|
||||
dr := cfg.Spec.(*v1alpha3.DestinationRule)
|
||||
drwList = append(drwList, &ingress.WrapperDestinationRule{
|
||||
DestinationRule: dr,
|
||||
ServiceKey: ingress.ServiceKey{ServiceFQDN: dr.Host},
|
||||
})
|
||||
}
|
||||
|
||||
return drwList
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user