141 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
| package defaultinterpreter
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 
 | |
| 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 | |
| 	"k8s.io/apimachinery/pkg/runtime"
 | |
| 	"k8s.io/apimachinery/pkg/runtime/schema"
 | |
| 	"k8s.io/klog/v2"
 | |
| 
 | |
| 	configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
 | |
| 	workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
 | |
| )
 | |
| 
 | |
| // DefaultInterpreter contains all default operation interpreter factory
 | |
| // for interpreting common resource.
 | |
| type DefaultInterpreter struct {
 | |
| 	replicaHandlers         map[schema.GroupVersionKind]replicaInterpreter
 | |
| 	reviseReplicaHandlers   map[schema.GroupVersionKind]reviseReplicaInterpreter
 | |
| 	retentionHandlers       map[schema.GroupVersionKind]retentionInterpreter
 | |
| 	aggregateStatusHandlers map[schema.GroupVersionKind]aggregateStatusInterpreter
 | |
| 	dependenciesHandlers    map[schema.GroupVersionKind]dependenciesInterpreter
 | |
| 	reflectStatusHandlers   map[schema.GroupVersionKind]reflectStatusInterpreter
 | |
| 	healthHandlers          map[schema.GroupVersionKind]healthInterpreter
 | |
| }
 | |
| 
 | |
| // NewDefaultInterpreter return a new DefaultInterpreter.
 | |
| func NewDefaultInterpreter() *DefaultInterpreter {
 | |
| 	return &DefaultInterpreter{
 | |
| 		replicaHandlers:         getAllDefaultReplicaInterpreter(),
 | |
| 		reviseReplicaHandlers:   getAllDefaultReviseReplicaInterpreter(),
 | |
| 		retentionHandlers:       getAllDefaultRetentionInterpreter(),
 | |
| 		aggregateStatusHandlers: getAllDefaultAggregateStatusInterpreter(),
 | |
| 		dependenciesHandlers:    getAllDefaultDependenciesInterpreter(),
 | |
| 		reflectStatusHandlers:   getAllDefaultReflectStatusInterpreter(),
 | |
| 		healthHandlers:          getAllDefaultHealthInterpreter(),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // HookEnabled tells if any hook exist for specific resource type and operation type.
 | |
| func (e *DefaultInterpreter) HookEnabled(kind schema.GroupVersionKind, operationType configv1alpha1.InterpreterOperation) bool {
 | |
| 	switch operationType {
 | |
| 	case configv1alpha1.InterpreterOperationInterpretReplica:
 | |
| 		if _, exist := e.replicaHandlers[kind]; exist {
 | |
| 			return true
 | |
| 		}
 | |
| 	case configv1alpha1.InterpreterOperationReviseReplica:
 | |
| 		if _, exist := e.reviseReplicaHandlers[kind]; exist {
 | |
| 			return true
 | |
| 		}
 | |
| 	case configv1alpha1.InterpreterOperationRetain:
 | |
| 		if _, exist := e.retentionHandlers[kind]; exist {
 | |
| 			return true
 | |
| 		}
 | |
| 	case configv1alpha1.InterpreterOperationAggregateStatus:
 | |
| 		if _, exist := e.aggregateStatusHandlers[kind]; exist {
 | |
| 			return true
 | |
| 		}
 | |
| 	case configv1alpha1.InterpreterOperationInterpretDependency:
 | |
| 		if _, exist := e.dependenciesHandlers[kind]; exist {
 | |
| 			return true
 | |
| 		}
 | |
| 	case configv1alpha1.InterpreterOperationInterpretStatus:
 | |
| 		return true
 | |
| 	case configv1alpha1.InterpreterOperationInterpretHealth:
 | |
| 		if _, exist := e.healthHandlers[kind]; exist {
 | |
| 			return true
 | |
| 		}
 | |
| 		// TODO(RainbowMango): more cases should be added here
 | |
| 	}
 | |
| 
 | |
| 	klog.V(4).Infof("Default interpreter is not enabled for kind %q with operation %q.", kind, operationType)
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| // GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
 | |
| func (e *DefaultInterpreter) GetReplicas(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error) {
 | |
| 	handler, exist := e.replicaHandlers[object.GroupVersionKind()]
 | |
| 	if !exist {
 | |
| 		return 0, &workv1alpha2.ReplicaRequirements{}, fmt.Errorf("default %s interpreter for %q not found", configv1alpha1.InterpreterOperationInterpretReplica, object.GroupVersionKind())
 | |
| 	}
 | |
| 	return handler(object)
 | |
| }
 | |
| 
 | |
| // ReviseReplica revises the replica of the given object.
 | |
| func (e *DefaultInterpreter) ReviseReplica(object *unstructured.Unstructured, replica int64) (*unstructured.Unstructured, error) {
 | |
| 	handler, exist := e.reviseReplicaHandlers[object.GroupVersionKind()]
 | |
| 	if !exist {
 | |
| 		return nil, fmt.Errorf("default %s interpreter for %q not found", configv1alpha1.InterpreterOperationReviseReplica, object.GroupVersionKind())
 | |
| 	}
 | |
| 	return handler(object, replica)
 | |
| }
 | |
| 
 | |
| // Retain returns the objects that based on the "desired" object but with values retained from the "observed" object.
 | |
| func (e *DefaultInterpreter) Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error) {
 | |
| 	handler, exist := e.retentionHandlers[desired.GroupVersionKind()]
 | |
| 	if !exist {
 | |
| 		return nil, fmt.Errorf("default %s interpreter for %q not found", configv1alpha1.InterpreterOperationRetain, desired.GroupVersionKind())
 | |
| 	}
 | |
| 	return handler(desired, observed)
 | |
| }
 | |
| 
 | |
| // AggregateStatus returns the objects that based on the 'object' but with status aggregated.
 | |
| func (e *DefaultInterpreter) AggregateStatus(object *unstructured.Unstructured, aggregatedStatusItems []workv1alpha2.AggregatedStatusItem) (*unstructured.Unstructured, error) {
 | |
| 	handler, exist := e.aggregateStatusHandlers[object.GroupVersionKind()]
 | |
| 	if !exist {
 | |
| 		return nil, fmt.Errorf("default %s interpreter for %q not found", configv1alpha1.InterpreterOperationAggregateStatus, object.GroupVersionKind())
 | |
| 	}
 | |
| 	return handler(object, aggregatedStatusItems)
 | |
| }
 | |
| 
 | |
| // GetDependencies returns the dependent resources of the given object.
 | |
| func (e *DefaultInterpreter) GetDependencies(object *unstructured.Unstructured) (dependencies []configv1alpha1.DependentObjectReference, err error) {
 | |
| 	handler, exist := e.dependenciesHandlers[object.GroupVersionKind()]
 | |
| 	if !exist {
 | |
| 		return dependencies, fmt.Errorf("default interpreter for operation %s not found", configv1alpha1.InterpreterOperationInterpretDependency)
 | |
| 	}
 | |
| 	return handler(object)
 | |
| }
 | |
| 
 | |
| // ReflectStatus returns the status of the object.
 | |
| func (e *DefaultInterpreter) ReflectStatus(object *unstructured.Unstructured) (status *runtime.RawExtension, err error) {
 | |
| 	handler, exist := e.reflectStatusHandlers[object.GroupVersionKind()]
 | |
| 	if exist {
 | |
| 		return handler(object)
 | |
| 	}
 | |
| 
 | |
| 	// for resource types that don't have a build-in handler, try to collect the whole status from '.status' filed.
 | |
| 	return reflectWholeStatus(object)
 | |
| }
 | |
| 
 | |
| // InterpretHealth returns the health state of the object.
 | |
| func (e *DefaultInterpreter) InterpretHealth(object *unstructured.Unstructured) (bool, error) {
 | |
| 	handler, exist := e.healthHandlers[object.GroupVersionKind()]
 | |
| 	if exist {
 | |
| 		return handler(object)
 | |
| 	}
 | |
| 
 | |
| 	return false, fmt.Errorf("default %s interpreter for %q not found", configv1alpha1.InterpreterOperationInterpretHealth, object.GroupVersionKind())
 | |
| }
 |