func()

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
}