Merge pull request #2829 from XiShanYongYe-Chang/add-e2e-for-resourceInterpreterCustomization
[E2E] add test case for resource interpreter customization
This commit is contained in:
commit
8aa58ec6cf
|
@ -35,6 +35,7 @@ func (c *ConfigurableInterpreter) HookEnabled(kind schema.GroupVersionKind, oper
|
|||
|
||||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
|
||||
func (c *ConfigurableInterpreter) GetReplicas(object *unstructured.Unstructured) (replicas int32, requires *workv1alpha2.ReplicaRequirements, enabled bool, err error) {
|
||||
klog.V(4).Infof("Get replicas for object: %v %s/%s with configurable interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
luaScript, enabled := c.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationInterpretReplica)
|
||||
if !enabled {
|
||||
return
|
||||
|
@ -46,6 +47,7 @@ func (c *ConfigurableInterpreter) GetReplicas(object *unstructured.Unstructured)
|
|||
|
||||
// ReviseReplica revises the replica of the given object.
|
||||
func (c *ConfigurableInterpreter) ReviseReplica(object *unstructured.Unstructured, replica int64) (revised *unstructured.Unstructured, enabled bool, err error) {
|
||||
klog.V(4).Infof("Revise replicas for object: %v %s/%s with configurable interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
luaScript, enabled := c.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationReviseReplica)
|
||||
if !enabled {
|
||||
return
|
||||
|
@ -57,6 +59,7 @@ func (c *ConfigurableInterpreter) ReviseReplica(object *unstructured.Unstructure
|
|||
|
||||
// Retain returns the objects that based on the "desired" object but with values retained from the "observed" object.
|
||||
func (c *ConfigurableInterpreter) Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, enabled bool, err error) {
|
||||
klog.V(4).Infof("Retain object: %v %s/%s with configurable interpreter.", desired.GroupVersionKind(), desired.GetNamespace(), desired.GetName())
|
||||
luaScript, enabled := c.getInterpreter(desired.GroupVersionKind(), configv1alpha1.InterpreterOperationRetain)
|
||||
if !enabled {
|
||||
return
|
||||
|
@ -68,6 +71,7 @@ func (c *ConfigurableInterpreter) Retain(desired *unstructured.Unstructured, obs
|
|||
|
||||
// AggregateStatus returns the objects that based on the 'object' but with status aggregated.
|
||||
func (c *ConfigurableInterpreter) AggregateStatus(object *unstructured.Unstructured, aggregatedStatusItems []workv1alpha2.AggregatedStatusItem) (status *unstructured.Unstructured, enabled bool, err error) {
|
||||
klog.V(4).Infof("Aggregate status of object: %v %s/%s with configurable interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
luaScript, enabled := c.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationAggregateStatus)
|
||||
if !enabled {
|
||||
return
|
||||
|
@ -79,6 +83,7 @@ func (c *ConfigurableInterpreter) AggregateStatus(object *unstructured.Unstructu
|
|||
|
||||
// GetDependencies returns the dependent resources of the given object.
|
||||
func (c *ConfigurableInterpreter) GetDependencies(object *unstructured.Unstructured) (dependencies []configv1alpha1.DependentObjectReference, enabled bool, err error) {
|
||||
klog.V(4).Infof("Get dependencies of object: %v %s/%s with configurable interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
luaScript, enabled := c.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationInterpretDependency)
|
||||
if !enabled {
|
||||
return
|
||||
|
@ -90,6 +95,7 @@ func (c *ConfigurableInterpreter) GetDependencies(object *unstructured.Unstructu
|
|||
|
||||
// ReflectStatus returns the status of the object.
|
||||
func (c *ConfigurableInterpreter) ReflectStatus(object *unstructured.Unstructured) (status *runtime.RawExtension, enabled bool, err error) {
|
||||
klog.V(4).Infof("Reflect status of object: %v %s/%s with configurable interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
luaScript, enabled := c.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationInterpretStatus)
|
||||
if !enabled {
|
||||
return
|
||||
|
@ -101,6 +107,7 @@ func (c *ConfigurableInterpreter) ReflectStatus(object *unstructured.Unstructure
|
|||
|
||||
// InterpretHealth returns the health state of the object.
|
||||
func (c *ConfigurableInterpreter) InterpretHealth(object *unstructured.Unstructured) (health bool, enabled bool, err error) {
|
||||
klog.V(4).Infof("Get health status of object: %v %s/%s with configurable interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
luaScript, enabled := c.getInterpreter(object.GroupVersionKind(), configv1alpha1.InterpreterOperationInterpretHealth)
|
||||
if !enabled {
|
||||
return
|
||||
|
|
|
@ -46,7 +46,7 @@ func (vm VM) GetReplicas(obj *unstructured.Unstructured, script string) (replica
|
|||
f := l.GetGlobal("GetReplicas")
|
||||
|
||||
if f.Type() == lua.LTNil {
|
||||
return 0, nil, fmt.Errorf("can't get function ReviseReplica pleace check the function name")
|
||||
return 0, nil, fmt.Errorf("can't get function GetReplicas, please check the lua script")
|
||||
}
|
||||
|
||||
args := make([]lua.LValue, 1)
|
||||
|
@ -107,7 +107,7 @@ func (vm VM) ReviseReplica(object *unstructured.Unstructured, replica int64, scr
|
|||
}
|
||||
reviseReplicaLuaFunc := l.GetGlobal("ReviseReplica")
|
||||
if reviseReplicaLuaFunc.Type() == lua.LTNil {
|
||||
return nil, fmt.Errorf("can't get function ReviseReplica pleace check the function name")
|
||||
return nil, fmt.Errorf("can't get function ReviseReplica, please check the lua script")
|
||||
}
|
||||
|
||||
args := make([]lua.LValue, 2)
|
||||
|
@ -183,7 +183,7 @@ func (vm VM) Retain(desired *unstructured.Unstructured, observed *unstructured.U
|
|||
}
|
||||
retainLuaFunc := l.GetGlobal("Retain")
|
||||
if retainLuaFunc.Type() == lua.LTNil {
|
||||
return nil, fmt.Errorf("can't get function Retatin pleace check the function ")
|
||||
return nil, fmt.Errorf("can't get function Retatin, please check the lua script")
|
||||
}
|
||||
|
||||
args := make([]lua.LValue, 2)
|
||||
|
@ -237,7 +237,7 @@ func (vm VM) AggregateStatus(object *unstructured.Unstructured, items []workv1al
|
|||
|
||||
f := l.GetGlobal("AggregateStatus")
|
||||
if f.Type() == lua.LTNil {
|
||||
return nil, fmt.Errorf("can't get function AggregateStatus pleace check the function ")
|
||||
return nil, fmt.Errorf("can't get function AggregateStatus, please check the lua script")
|
||||
}
|
||||
args := make([]lua.LValue, 2)
|
||||
args[0], err = decodeValue(l, object.Object)
|
||||
|
@ -289,7 +289,7 @@ func (vm VM) InterpretHealth(object *unstructured.Unstructured, script string) (
|
|||
}
|
||||
f := l.GetGlobal("InterpretHealth")
|
||||
if f.Type() == lua.LTNil {
|
||||
return false, fmt.Errorf("can't get function InterpretHealth pleace check the function ")
|
||||
return false, fmt.Errorf("can't get function InterpretHealth, please check the lua script")
|
||||
}
|
||||
|
||||
args := make([]lua.LValue, 1)
|
||||
|
@ -335,7 +335,7 @@ func (vm VM) ReflectStatus(object *unstructured.Unstructured, script string) (st
|
|||
}
|
||||
f := l.GetGlobal("ReflectStatus")
|
||||
if f.Type() == lua.LTNil {
|
||||
return nil, fmt.Errorf("can't get function ReflectStatus pleace check the function ")
|
||||
return nil, fmt.Errorf("can't get function ReflectStatus, please check the lua script")
|
||||
}
|
||||
|
||||
args := make([]lua.LValue, 1)
|
||||
|
@ -382,7 +382,7 @@ func (vm VM) GetDependencies(object *unstructured.Unstructured, script string) (
|
|||
}
|
||||
f := l.GetGlobal("GetDependencies")
|
||||
if f.Type() == lua.LTNil {
|
||||
return nil, fmt.Errorf("can't get function Retatin pleace check the function ")
|
||||
return nil, fmt.Errorf("can't get function GetDependencies, please check the lua script")
|
||||
}
|
||||
|
||||
args := make([]lua.LValue, 1)
|
||||
|
|
|
@ -71,6 +71,8 @@ func (e *CustomizedInterpreter) HookEnabled(objGVK schema.GroupVersionKind, oper
|
|||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
|
||||
// return matched value to indicate whether there is a matching hook.
|
||||
func (e *CustomizedInterpreter) GetReplicas(ctx context.Context, attributes *webhook.RequestAttributes) (replica int32, requires *workv1alpha2.ReplicaRequirements, matched bool, err error) {
|
||||
klog.V(4).Infof("Get replicas for object: %v %s/%s with webhook interpreter.",
|
||||
attributes.Object.GroupVersionKind(), attributes.Object.GetNamespace(), attributes.Object.GetName())
|
||||
var response *webhook.ResponseAttributes
|
||||
response, matched, err = e.interpret(ctx, attributes)
|
||||
if err != nil {
|
||||
|
|
|
@ -75,6 +75,7 @@ func (e *DefaultInterpreter) HookEnabled(kind schema.GroupVersionKind, operation
|
|||
|
||||
// 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) {
|
||||
klog.V(4).Infof("Get replicas for object: %v %s/%s with build-in interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
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())
|
||||
|
@ -84,6 +85,7 @@ func (e *DefaultInterpreter) GetReplicas(object *unstructured.Unstructured) (int
|
|||
|
||||
// ReviseReplica revises the replica of the given object.
|
||||
func (e *DefaultInterpreter) ReviseReplica(object *unstructured.Unstructured, replica int64) (*unstructured.Unstructured, error) {
|
||||
klog.V(4).Infof("Revise replicas for object: %v %s/%s with build-in interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
handler, exist := e.reviseReplicaHandlers[object.GroupVersionKind()]
|
||||
if !exist {
|
||||
return nil, fmt.Errorf("default %s interpreter for %q not found", configv1alpha1.InterpreterOperationReviseReplica, object.GroupVersionKind())
|
||||
|
@ -93,6 +95,7 @@ func (e *DefaultInterpreter) ReviseReplica(object *unstructured.Unstructured, re
|
|||
|
||||
// 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) {
|
||||
klog.V(4).Infof("Retain object: %v %s/%s with build-in interpreter.", desired.GroupVersionKind(), desired.GetNamespace(), desired.GetName())
|
||||
handler, exist := e.retentionHandlers[desired.GroupVersionKind()]
|
||||
if !exist {
|
||||
return nil, fmt.Errorf("default %s interpreter for %q not found", configv1alpha1.InterpreterOperationRetain, desired.GroupVersionKind())
|
||||
|
@ -102,6 +105,7 @@ func (e *DefaultInterpreter) Retain(desired *unstructured.Unstructured, 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) {
|
||||
klog.V(4).Infof("Aggregate status of object: %v %s/%s with build-in interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
handler, exist := e.aggregateStatusHandlers[object.GroupVersionKind()]
|
||||
if !exist {
|
||||
return nil, fmt.Errorf("default %s interpreter for %q not found", configv1alpha1.InterpreterOperationAggregateStatus, object.GroupVersionKind())
|
||||
|
@ -111,6 +115,7 @@ func (e *DefaultInterpreter) AggregateStatus(object *unstructured.Unstructured,
|
|||
|
||||
// GetDependencies returns the dependent resources of the given object.
|
||||
func (e *DefaultInterpreter) GetDependencies(object *unstructured.Unstructured) (dependencies []configv1alpha1.DependentObjectReference, err error) {
|
||||
klog.V(4).Infof("Get dependencies of object: %v %s/%s with build-in interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
handler, exist := e.dependenciesHandlers[object.GroupVersionKind()]
|
||||
if !exist {
|
||||
return dependencies, fmt.Errorf("default interpreter for operation %s not found", configv1alpha1.InterpreterOperationInterpretDependency)
|
||||
|
@ -120,6 +125,7 @@ func (e *DefaultInterpreter) GetDependencies(object *unstructured.Unstructured)
|
|||
|
||||
// ReflectStatus returns the status of the object.
|
||||
func (e *DefaultInterpreter) ReflectStatus(object *unstructured.Unstructured) (status *runtime.RawExtension, err error) {
|
||||
klog.V(4).Infof("Reflect status of object: %v %s/%s with build-in interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
handler, exist := e.reflectStatusHandlers[object.GroupVersionKind()]
|
||||
if exist {
|
||||
return handler(object)
|
||||
|
@ -131,6 +137,7 @@ func (e *DefaultInterpreter) ReflectStatus(object *unstructured.Unstructured) (s
|
|||
|
||||
// InterpretHealth returns the health state of the object.
|
||||
func (e *DefaultInterpreter) InterpretHealth(object *unstructured.Unstructured) (bool, error) {
|
||||
klog.V(4).Infof("Get health status of object: %v %s/%s with build-in interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
handler, exist := e.healthHandlers[object.GroupVersionKind()]
|
||||
if exist {
|
||||
return handler(object)
|
||||
|
|
|
@ -91,8 +91,6 @@ func (i *customResourceInterpreterImpl) HookEnabled(objGVK schema.GroupVersionKi
|
|||
|
||||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
|
||||
func (i *customResourceInterpreterImpl) GetReplicas(object *unstructured.Unstructured) (replica int32, requires *workv1alpha2.ReplicaRequirements, err error) {
|
||||
klog.V(4).Infof("Begin to get replicas for request object: %v %s/%s.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
|
||||
var hookEnabled bool
|
||||
|
||||
replica, requires, hookEnabled, err = i.configurableInterpreter.GetReplicas(object)
|
||||
|
@ -120,8 +118,6 @@ func (i *customResourceInterpreterImpl) GetReplicas(object *unstructured.Unstruc
|
|||
|
||||
// ReviseReplica revises the replica of the given object.
|
||||
func (i *customResourceInterpreterImpl) ReviseReplica(object *unstructured.Unstructured, replica int64) (*unstructured.Unstructured, error) {
|
||||
klog.V(4).Infof("Begin to revise replicas for object: %v %s/%s.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
|
||||
obj, hookEnabled, err := i.configurableInterpreter.ReviseReplica(object, replica)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -130,6 +126,7 @@ func (i *customResourceInterpreterImpl) ReviseReplica(object *unstructured.Unstr
|
|||
return obj, nil
|
||||
}
|
||||
|
||||
klog.V(4).Infof("Revise replicas for object: %v %s/%s with webhook interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
obj, hookEnabled, err = i.customizedInterpreter.Patch(context.TODO(), &webhook.RequestAttributes{
|
||||
Operation: configv1alpha1.InterpreterOperationReviseReplica,
|
||||
Object: object,
|
||||
|
@ -147,8 +144,6 @@ func (i *customResourceInterpreterImpl) ReviseReplica(object *unstructured.Unstr
|
|||
|
||||
// Retain returns the objects that based on the "desired" object but with values retained from the "observed" object.
|
||||
func (i *customResourceInterpreterImpl) Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
klog.V(4).Infof("Begin to retain object: %v %s/%s.", desired.GroupVersionKind(), desired.GetNamespace(), desired.GetName())
|
||||
|
||||
obj, hookEnabled, err := i.configurableInterpreter.Retain(desired, observed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -157,6 +152,7 @@ func (i *customResourceInterpreterImpl) Retain(desired *unstructured.Unstructure
|
|||
return obj, nil
|
||||
}
|
||||
|
||||
klog.V(4).Infof("Retain object: %v %s/%s with webhook interpreter.", desired.GroupVersionKind(), desired.GetNamespace(), desired.GetName())
|
||||
obj, hookEnabled, err = i.customizedInterpreter.Patch(context.TODO(), &webhook.RequestAttributes{
|
||||
Operation: configv1alpha1.InterpreterOperationRetain,
|
||||
Object: desired,
|
||||
|
@ -174,8 +170,6 @@ func (i *customResourceInterpreterImpl) Retain(desired *unstructured.Unstructure
|
|||
|
||||
// AggregateStatus returns the objects that based on the 'object' but with status aggregated.
|
||||
func (i *customResourceInterpreterImpl) AggregateStatus(object *unstructured.Unstructured, aggregatedStatusItems []workv1alpha2.AggregatedStatusItem) (*unstructured.Unstructured, error) {
|
||||
klog.V(4).Infof("Begin to aggregate status for object: %v %s/%s.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
|
||||
obj, hookEnabled, err := i.configurableInterpreter.AggregateStatus(object, aggregatedStatusItems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -184,6 +178,7 @@ func (i *customResourceInterpreterImpl) AggregateStatus(object *unstructured.Uns
|
|||
return obj, nil
|
||||
}
|
||||
|
||||
klog.V(4).Infof("Aggregate status of object: %v %s/%s with webhook interpreter.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
obj, hookEnabled, err = i.customizedInterpreter.Patch(context.TODO(), &webhook.RequestAttributes{
|
||||
Operation: configv1alpha1.InterpreterOperationAggregateStatus,
|
||||
Object: object.DeepCopy(),
|
||||
|
@ -201,7 +196,6 @@ func (i *customResourceInterpreterImpl) AggregateStatus(object *unstructured.Uns
|
|||
|
||||
// GetDependencies returns the dependent resources of the given object.
|
||||
func (i *customResourceInterpreterImpl) GetDependencies(object *unstructured.Unstructured) (dependencies []configv1alpha1.DependentObjectReference, err error) {
|
||||
klog.V(4).Infof("Begin to get dependencies for object: %v %s/%s.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
dependencies, hookEnabled, err := i.configurableInterpreter.GetDependencies(object)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -227,8 +221,6 @@ func (i *customResourceInterpreterImpl) GetDependencies(object *unstructured.Uns
|
|||
|
||||
// ReflectStatus returns the status of the object.
|
||||
func (i *customResourceInterpreterImpl) ReflectStatus(object *unstructured.Unstructured) (status *runtime.RawExtension, err error) {
|
||||
klog.V(4).Infof("Begin to grab status for object: %v %s/%s.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
|
||||
status, hookEnabled, err := i.configurableInterpreter.ReflectStatus(object)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -253,8 +245,6 @@ func (i *customResourceInterpreterImpl) ReflectStatus(object *unstructured.Unstr
|
|||
|
||||
// InterpretHealth returns the health state of the object.
|
||||
func (i *customResourceInterpreterImpl) InterpretHealth(object *unstructured.Unstructured) (healthy bool, err error) {
|
||||
klog.V(4).Infof("Begin to check health for object: %v %s/%s.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
|
||||
healthy, hookEnabled, err := i.configurableInterpreter.InterpretHealth(object)
|
||||
if err != nil {
|
||||
return
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package framework
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/onsi/gomega"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
karmada "github.com/karmada-io/karmada/pkg/generated/clientset/versioned"
|
||||
)
|
||||
|
||||
// CreateResourceInterpreterCustomization creates ResourceInterpreterCustomization with karmada client.
|
||||
func CreateResourceInterpreterCustomization(client karmada.Interface, customization *configv1alpha1.ResourceInterpreterCustomization) {
|
||||
ginkgo.By(fmt.Sprintf("Creating ResourceInterpreterCustomization(%s)", customization.Name), func() {
|
||||
_, err := client.ConfigV1alpha1().ResourceInterpreterCustomizations().Create(context.TODO(), customization, metav1.CreateOptions{})
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteResourceInterpreterCustomization deletes ResourceInterpreterCustomization with karmada client.
|
||||
func DeleteResourceInterpreterCustomization(client karmada.Interface, name string) {
|
||||
ginkgo.By(fmt.Sprintf("Deleting ResourceInterpreterCustomization(%s)", name), func() {
|
||||
err := client.ConfigV1alpha1().ResourceInterpreterCustomizations().Delete(context.TODO(), name, metav1.DeleteOptions{})
|
||||
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
}
|
|
@ -4,10 +4,14 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/onsi/gomega"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/rand"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
@ -15,6 +19,7 @@ import (
|
|||
"k8s.io/utils/pointer"
|
||||
|
||||
workloadv1alpha1 "github.com/karmada-io/karmada/examples/customresourceinterpreter/apis/workload/v1alpha1"
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/util/names"
|
||||
|
@ -272,3 +277,149 @@ var _ = ginkgo.Describe("Resource interpreter webhook testing", func() {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
var _ = framework.SerialDescribe("Resource interpreter customization testing", func() {
|
||||
var customization *configv1alpha1.ResourceInterpreterCustomization
|
||||
var deployment *appsv1.Deployment
|
||||
var policy *policyv1alpha1.PropagationPolicy
|
||||
// We only need to test any one of the member clusters.
|
||||
var targetCluster string
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
targetCluster = framework.ClusterNames()[rand.Intn(len(framework.ClusterNames()))]
|
||||
deployment = testhelper.NewDeployment(testNamespace, deploymentNamePrefix+rand.String(RandomStrLength))
|
||||
policy = testhelper.NewPropagationPolicy(testNamespace, deployment.Name, []policyv1alpha1.ResourceSelector{
|
||||
{
|
||||
APIVersion: deployment.APIVersion,
|
||||
Kind: deployment.Kind,
|
||||
Name: deployment.Name,
|
||||
},
|
||||
}, policyv1alpha1.Placement{
|
||||
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
|
||||
ClusterNames: []string{targetCluster},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.JustBeforeEach(func() {
|
||||
framework.CreateResourceInterpreterCustomization(karmadaClient, customization)
|
||||
// Wait for resource interpreter informer synced.
|
||||
time.Sleep(time.Second)
|
||||
|
||||
framework.CreatePropagationPolicy(karmadaClient, policy)
|
||||
framework.CreateDeployment(kubeClient, deployment)
|
||||
ginkgo.DeferCleanup(func() {
|
||||
framework.RemoveDeployment(kubeClient, deployment.Namespace, deployment.Name)
|
||||
framework.RemovePropagationPolicy(karmadaClient, policy.Namespace, policy.Name)
|
||||
framework.DeleteResourceInterpreterCustomization(karmadaClient, customization.Name)
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.Context("InterpreterOperation InterpretReplica testing", func() {
|
||||
ginkgo.BeforeEach(func() {
|
||||
customization = testhelper.NewResourceInterpreterCustomization(
|
||||
"interpreter-customization"+rand.String(RandomStrLength),
|
||||
configv1alpha1.CustomizationTarget{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
configv1alpha1.CustomizationRules{
|
||||
ReplicaResource: &configv1alpha1.ReplicaResourceRequirement{
|
||||
LuaScript: `
|
||||
function GetReplicas(desiredObj)
|
||||
replica = desiredObj.spec.replicas + 1
|
||||
requirement = {}
|
||||
requirement.nodeClaim = {}
|
||||
requirement.nodeClaim.nodeSelector = desiredObj.spec.template.spec.nodeSelector
|
||||
requirement.nodeClaim.tolerations = desiredObj.spec.template.spec.tolerations
|
||||
requirement.resourceRequest = desiredObj.spec.template.spec.containers[1].resources.limits
|
||||
return replica, requirement
|
||||
end`,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It("InterpretReplica testing", func() {
|
||||
ginkgo.By("check if workload's replica is interpreted", func() {
|
||||
resourceBindingName := names.GenerateBindingName(deployment.Kind, deployment.Name)
|
||||
// Just for the current test case to distinguish the build-in logic.
|
||||
expectedReplicas := *deployment.Spec.Replicas + 1
|
||||
expectedReplicaRequirements := &workv1alpha2.ReplicaRequirements{
|
||||
ResourceRequest: map[corev1.ResourceName]resource.Quantity{
|
||||
corev1.ResourceCPU: resource.MustParse("100m"),
|
||||
}}
|
||||
|
||||
gomega.Eventually(func(g gomega.Gomega) (bool, error) {
|
||||
resourceBinding, err := karmadaClient.WorkV1alpha2().ResourceBindings(deployment.Namespace).Get(context.TODO(), resourceBindingName, metav1.GetOptions{})
|
||||
g.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
klog.Infof(fmt.Sprintf("ResourceBinding(%s/%s)'s replicas is %d, expected: %d.",
|
||||
resourceBinding.Namespace, resourceBinding.Name, resourceBinding.Spec.Replicas, expectedReplicas))
|
||||
if resourceBinding.Spec.Replicas != expectedReplicas {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
klog.Infof(fmt.Sprintf("ResourceBinding(%s/%s)'s replicaRequirements is %+v, expected: %+v.",
|
||||
resourceBinding.Namespace, resourceBinding.Name, resourceBinding.Spec.ReplicaRequirements, expectedReplicaRequirements))
|
||||
return reflect.DeepEqual(resourceBinding.Spec.ReplicaRequirements, expectedReplicaRequirements), nil
|
||||
}, pollTimeout, pollInterval).Should(gomega.Equal(true))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.Context("InterpreterOperation ReviseReplica testing", func() {
|
||||
ginkgo.BeforeEach(func() {
|
||||
customization = testhelper.NewResourceInterpreterCustomization(
|
||||
"interpreter-customization"+rand.String(RandomStrLength),
|
||||
configv1alpha1.CustomizationTarget{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
configv1alpha1.CustomizationRules{
|
||||
ReplicaRevision: &configv1alpha1.ReplicaRevision{
|
||||
LuaScript: `
|
||||
function ReviseReplica(obj, desiredReplica)
|
||||
obj.spec.replicas = desiredReplica + 1
|
||||
return obj
|
||||
end`,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
sumWeight := 0
|
||||
staticWeightLists := make([]policyv1alpha1.StaticClusterWeight, 0)
|
||||
for index, clusterName := range framework.ClusterNames() {
|
||||
staticWeightList := policyv1alpha1.StaticClusterWeight{
|
||||
TargetCluster: policyv1alpha1.ClusterAffinity{
|
||||
ClusterNames: []string{clusterName},
|
||||
},
|
||||
Weight: int64(index + 1),
|
||||
}
|
||||
sumWeight += index + 1
|
||||
staticWeightLists = append(staticWeightLists, staticWeightList)
|
||||
}
|
||||
deployment.Spec.Replicas = pointer.Int32Ptr(int32(sumWeight))
|
||||
policy.Spec.Placement = policyv1alpha1.Placement{
|
||||
ClusterAffinity: &policyv1alpha1.ClusterAffinity{
|
||||
ClusterNames: framework.ClusterNames(),
|
||||
},
|
||||
ReplicaScheduling: &policyv1alpha1.ReplicaSchedulingStrategy{
|
||||
ReplicaDivisionPreference: policyv1alpha1.ReplicaDivisionPreferenceWeighted,
|
||||
ReplicaSchedulingType: policyv1alpha1.ReplicaSchedulingTypeDivided,
|
||||
WeightPreference: &policyv1alpha1.ClusterPreferences{
|
||||
StaticWeightList: staticWeightLists,
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("ReviseReplica testing", func() {
|
||||
for index, clusterName := range framework.ClusterNames() {
|
||||
framework.WaitDeploymentPresentOnClusterFitWith(clusterName, deployment.Namespace, deployment.Name, func(deployment *appsv1.Deployment) bool {
|
||||
return *deployment.Spec.Replicas == int32(index+1)+1
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
)
|
||||
|
||||
// NewResourceInterpreterCustomization will build a ResourceInterpreterCustomization object.
|
||||
func NewResourceInterpreterCustomization(
|
||||
name string,
|
||||
target configv1alpha1.CustomizationTarget,
|
||||
rules configv1alpha1.CustomizationRules) *configv1alpha1.ResourceInterpreterCustomization {
|
||||
return &configv1alpha1.ResourceInterpreterCustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||
Spec: configv1alpha1.ResourceInterpreterCustomizationSpec{
|
||||
Target: target,
|
||||
Customizations: rules,
|
||||
},
|
||||
}
|
||||
}
|
|
@ -56,6 +56,11 @@ func NewDeployment(namespace string, name string) *appsv1.Deployment {
|
|||
Containers: []corev1.Container{{
|
||||
Name: "nginx",
|
||||
Image: "nginx:1.19.0",
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: map[corev1.ResourceName]resource.Quantity{
|
||||
corev1.ResourceCPU: resource.MustParse("100m"),
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue