106 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
package thirdparty
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"io"
 | 
						|
	"io/fs"
 | 
						|
	"path/filepath"
 | 
						|
	"sort"
 | 
						|
	"strings"
 | 
						|
	"sync/atomic"
 | 
						|
 | 
						|
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
						|
	"k8s.io/apimachinery/pkg/util/yaml"
 | 
						|
	"k8s.io/klog/v2"
 | 
						|
 | 
						|
	configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
 | 
						|
	"github.com/karmada-io/karmada/pkg/resourceinterpreter/customized/declarative/configmanager"
 | 
						|
	"github.com/karmada-io/karmada/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations"
 | 
						|
)
 | 
						|
 | 
						|
const configurableInterpreterFile = "customizations.yaml"
 | 
						|
 | 
						|
// configManager collects the thirdparty resource interpreter customization.
 | 
						|
type configManager struct {
 | 
						|
	configuration atomic.Value
 | 
						|
}
 | 
						|
 | 
						|
func (t *configManager) HasSynced() bool {
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
func (t *configManager) LoadConfig(customizations []*configv1alpha1.ResourceInterpreterCustomization) {
 | 
						|
	sort.Slice(customizations, func(i, j int) bool {
 | 
						|
		return customizations[i].Name < customizations[j].Name
 | 
						|
	})
 | 
						|
 | 
						|
	accessors := make(map[schema.GroupVersionKind]configmanager.CustomAccessor)
 | 
						|
	for _, config := range customizations {
 | 
						|
		key := schema.FromAPIVersionAndKind(config.Spec.Target.APIVersion, config.Spec.Target.Kind)
 | 
						|
		var ac configmanager.CustomAccessor
 | 
						|
		var ok bool
 | 
						|
		if ac, ok = accessors[key]; !ok {
 | 
						|
			ac = configmanager.NewResourceCustomAccessor()
 | 
						|
		}
 | 
						|
		ac.Merge(config.Spec.Customizations)
 | 
						|
		accessors[key] = ac
 | 
						|
	}
 | 
						|
 | 
						|
	t.configuration.Store(accessors)
 | 
						|
}
 | 
						|
 | 
						|
// CustomAccessors returns all cached configurations.
 | 
						|
func (t *configManager) CustomAccessors() map[schema.GroupVersionKind]configmanager.CustomAccessor {
 | 
						|
	return t.configuration.Load().(map[schema.GroupVersionKind]configmanager.CustomAccessor)
 | 
						|
}
 | 
						|
 | 
						|
// NewThirdPartyConfigManager load third party resource in the cache.
 | 
						|
func NewThirdPartyConfigManager() configmanager.ConfigManager {
 | 
						|
	manager := &configManager{}
 | 
						|
	manager.configuration.Store(make(map[schema.GroupVersionKind]configmanager.CustomAccessor))
 | 
						|
	manager.loadThirdPartyConfig()
 | 
						|
	return manager
 | 
						|
}
 | 
						|
 | 
						|
func (t *configManager) loadThirdPartyConfig() {
 | 
						|
	var configs []*configv1alpha1.ResourceInterpreterCustomization
 | 
						|
	if err := fs.WalkDir(resourcecustomizations.Embedded, ".", func(path string, d fs.DirEntry, err error) error {
 | 
						|
		if err != nil {
 | 
						|
			// cannot happen
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		if d.IsDir() {
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
		if strings.Contains(d.Name(), "testdata") {
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
 | 
						|
		if filepath.Base(d.Name()) != configurableInterpreterFile {
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
		data, err := fs.ReadFile(resourcecustomizations.Embedded, path)
 | 
						|
		if err != nil {
 | 
						|
			// cannot happen
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		decoder := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(data), 4096)
 | 
						|
		for {
 | 
						|
			config := &configv1alpha1.ResourceInterpreterCustomization{}
 | 
						|
			err = decoder.Decode(config)
 | 
						|
			if err != nil {
 | 
						|
				break
 | 
						|
			}
 | 
						|
			configs = append(configs, config)
 | 
						|
		}
 | 
						|
		if err != io.EOF {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
	}); err != nil {
 | 
						|
		klog.Warning(err, "failed to load third party resource")
 | 
						|
		return
 | 
						|
	}
 | 
						|
	t.LoadConfig(configs)
 | 
						|
}
 |