in pkg/plugins/resources/traditional/store.go [280:492]
func (t *traditionalStore) Update(ctx context.Context, resource core_model.Resource, fs ...store.UpdateOptionsFunc) error {
opts := store.NewUpdateOptions(fs...)
if opts.Name == core_model.DefaultMesh {
opts.Name += ".universal"
}
name, _, err := util_k8s.CoreNameToK8sName(opts.Name)
if err != nil {
return err
}
switch resource.Descriptor().Name {
case mesh.DataplaneType:
// Dataplane资源无法更新, 只能获取和删除
case mesh.TagRouteType:
labels := opts.Labels
base := mesh_proto.Base{
Application: labels[mesh_proto.Application],
Service: labels[mesh_proto.Service],
ID: labels[mesh_proto.ID],
ServiceVersion: labels[mesh_proto.ServiceVersion],
ServiceGroup: labels[mesh_proto.ServiceGroup],
}
id := mesh_proto.BuildServiceKey(base)
path := mesh_proto.GetRoutePath(id, consts.TagRoute)
cfg, err := t.governance.GetConfig(path)
if err != nil {
return err
}
if cfg == "" {
return core_store.ErrorResourceNotFound(resource.Descriptor().Name, opts.Name, opts.Mesh)
}
bytes, err := core_model.ToYAML(resource.GetSpec())
if err != nil {
return fmt.Errorf("failed to marshal tag route to yaml %s", err.Error())
}
err = t.governance.SetConfig(path, string(bytes))
if err != nil {
return err
}
case mesh.ConditionRouteType:
labels := opts.Labels
base := mesh_proto.Base{
Application: labels[mesh_proto.Application],
Service: labels[mesh_proto.Service],
ID: labels[mesh_proto.ID],
ServiceVersion: labels[mesh_proto.ServiceVersion],
ServiceGroup: labels[mesh_proto.ServiceGroup],
}
id := mesh_proto.BuildServiceKey(base)
path := mesh_proto.GetRoutePath(id, consts.ConditionRoute)
cfg, err := t.governance.GetConfig(path)
if err != nil {
return err
}
if cfg == "" {
return core_store.ErrorResourceNotFound(resource.Descriptor().Name, opts.Name, opts.Mesh)
}
bytes, err := resource.GetSpec().(*mesh_proto.ConditionRoute).ToYAML()
if err != nil {
return fmt.Errorf("failed to marshal condition route to yaml %s", err.Error())
}
err = t.governance.SetConfig(path, string(bytes))
if err != nil {
return err
}
case mesh.DynamicConfigType:
labels := opts.Labels
base := mesh_proto.Base{
Application: labels[mesh_proto.Application],
Service: labels[mesh_proto.Service],
ID: labels[mesh_proto.ID],
ServiceVersion: labels[mesh_proto.ServiceVersion],
ServiceGroup: labels[mesh_proto.ServiceGroup],
}
id := mesh_proto.BuildServiceKey(base)
path := mesh_proto.GetOverridePath(id)
existConfig, err := t.governance.GetConfig(path)
if err != nil {
return err
} else if existConfig == "" {
return core_store.ErrorResourceNotFound(resource.Descriptor().Name, opts.Name, opts.Mesh)
}
bytes, err := core_model.ToYAML(resource.GetSpec())
if err != nil {
return fmt.Errorf("failed to marshal configurator to yaml %s", err.Error())
}
err = t.governance.SetConfig(path, string(bytes))
if err != nil {
return err
}
case mesh.AffinityRouteType:
labels := opts.Labels
base := mesh_proto.Base{
Application: labels[mesh_proto.Application],
Service: labels[mesh_proto.Service],
ID: labels[mesh_proto.ID],
ServiceVersion: labels[mesh_proto.ServiceVersion],
ServiceGroup: labels[mesh_proto.ServiceGroup],
}
id := mesh_proto.BuildServiceKey(base)
path := mesh_proto.GetRoutePath(id, consts.AffinityRoute)
existConfig, err := t.governance.GetConfig(path)
if err != nil {
return err
} else if existConfig == "" {
return core_store.ErrorResourceNotFound(resource.Descriptor().Name, opts.Name, opts.Mesh)
}
if b, err := core_model.ToYAML(resource.GetSpec()); err != nil {
return fmt.Errorf("failed to marshal affinity route to yaml %s", err.Error())
} else {
err := t.governance.SetConfig(path, string(b))
if err != nil {
return err
}
}
case mesh.MappingType:
spec := resource.GetSpec()
mapping := spec.(*mesh_proto.Mapping)
appNames := mapping.ApplicationNames
serviceInterface := mapping.InterfaceName
for _, app := range appNames {
path := getMappingPath(serviceInterface)
// 先使用regClient判断是否存在, 如果存在的话就先删除再更新
bytes, err := t.regClient.GetContent(path)
if err != nil {
return err
}
if len(bytes) != 0 {
// 说明有内容, 需要先删除
err := t.regClient.DeleteContent(path)
if err != nil {
return err
}
}
err = t.metadataReport.RegisterServiceAppMapping(serviceInterface, mappingGroup, app)
if err != nil {
return err
}
}
case mesh.MetaDataType:
spec := resource.GetSpec()
metadata := spec.(*mesh_proto.MetaData)
// 先判断identifier是否存在, 如果存在到话需要将其删除
content, err := t.regClient.GetContent(getMetadataPath(metadata.GetApp(), metadata.GetRevision()))
if err != nil {
return err
}
if len(content) != 0 {
// 如果不为空, 先删除
err := t.regClient.DeleteContent(getMetadataPath(metadata.GetApp(), metadata.GetRevision()))
if err != nil {
return err
}
}
services := map[string]*info.ServiceInfo{}
// 把metadata赋值到services中
for key, serviceInfo := range metadata.GetServices() {
services[key] = &info.ServiceInfo{
Name: serviceInfo.GetName(),
Group: serviceInfo.GetGroup(),
Version: serviceInfo.GetVersion(),
Protocol: serviceInfo.GetProtocol(),
Path: serviceInfo.GetPath(),
Params: serviceInfo.GetParams(),
}
}
metadataInfo := &info.MetadataInfo{
App: metadata.GetApp(),
Revision: metadata.GetRevision(),
Services: services,
}
err = t.metadataReport.PublishAppMetadata(metadataInfo.App, metadataInfo.Revision, metadataInfo)
if err != nil {
return err
}
default:
bytes, err := core_model.ToYAML(resource.GetSpec())
if err != nil {
return err
}
path := GenerateCpGroupPath(string(resource.Descriptor().Name), name)
// 使用RegClient
err = t.regClient.SetContent(path, bytes)
if err != nil {
return err
}
}
resource.SetMeta(&resourceMetaObject{
Name: name,
Mesh: opts.Mesh,
ModificationTime: opts.ModificationTime,
Labels: maps.Clone(opts.Labels),
})
if t.eventWriter != nil {
go func() {
t.eventWriter.Send(events.ResourceChangedEvent{
Operation: events.Update,
Type: resource.Descriptor().Name,
Key: core_model.MetaToResourceKey(&resourceMetaObject{
Name: name,
Mesh: opts.Mesh,
}),
})
}()
}
return nil
}