support multiple dependencyInterpreter lua script for one gvk

Signed-off-by: changzhen <changzhen5@huawei.com>
This commit is contained in:
changzhen 2022-11-30 09:10:27 +08:00
parent 37cca1cd8d
commit 5ed2100ee1
9 changed files with 660 additions and 386 deletions

View File

@ -19,7 +19,7 @@ type LuaScriptAccessor interface {
GetStatusReflectionLuaScript() string
GetStatusAggregationLuaScript() string
GetHealthInterpretationLuaScript() string
GetDependencyInterpretationLuaScript() string
GetDependencyInterpretationLuaScripts() []string
}
// CustomAccessor provides a common interface to get custom interpreter configuration.
@ -34,7 +34,7 @@ type resourceCustomAccessor struct {
statusReflection *configv1alpha1.StatusReflection
statusAggregation *configv1alpha1.StatusAggregation
healthInterpretation *configv1alpha1.HealthInterpretation
dependencyInterpretation *configv1alpha1.DependencyInterpretation
dependencyInterpretations []*configv1alpha1.DependencyInterpretation
}
// NewResourceCustomAccessor creates an accessor for resource interpreter customization.
@ -63,7 +63,7 @@ func (a *resourceCustomAccessor) Merge(rules configv1alpha1.CustomizationRules)
a.setHealthInterpretation(rules.HealthInterpretation)
}
if rules.DependencyInterpretation != nil {
a.setDependencyInterpretation(rules.DependencyInterpretation)
a.appendDependencyInterpretation(rules.DependencyInterpretation)
}
}
@ -109,11 +109,18 @@ func (a *resourceCustomAccessor) GetHealthInterpretationLuaScript() string {
return a.healthInterpretation.LuaScript
}
func (a *resourceCustomAccessor) GetDependencyInterpretationLuaScript() string {
if a.dependencyInterpretation == nil {
return ""
func (a *resourceCustomAccessor) GetDependencyInterpretationLuaScripts() []string {
if a.dependencyInterpretations == nil {
return nil
}
return a.dependencyInterpretation.LuaScript
var scripts []string
for _, interpretation := range a.dependencyInterpretations {
if interpretation.LuaScript != "" {
scripts = append(scripts, interpretation.LuaScript)
}
}
return scripts
}
func (a *resourceCustomAccessor) setRetain(retention *configv1alpha1.LocalValueRetention) {
@ -182,13 +189,6 @@ func (a *resourceCustomAccessor) setHealthInterpretation(healthInterpretation *c
}
}
func (a *resourceCustomAccessor) setDependencyInterpretation(dependencyInterpretation *configv1alpha1.DependencyInterpretation) {
if a.dependencyInterpretation == nil {
a.dependencyInterpretation = dependencyInterpretation
return
}
if dependencyInterpretation.LuaScript != "" && a.dependencyInterpretation.LuaScript == "" {
a.dependencyInterpretation.LuaScript = dependencyInterpretation.LuaScript
}
func (a *resourceCustomAccessor) appendDependencyInterpretation(dependencyInterpretation *configv1alpha1.DependencyInterpretation) {
a.dependencyInterpretations = append(a.dependencyInterpretations, dependencyInterpretation)
}

View File

@ -25,7 +25,7 @@ var resourceInterpreterCustomizationsGVR = schema.GroupVersionResource{
// ConfigManager can list custom resource interpreter.
type ConfigManager interface {
LuaScriptAccessors() map[schema.GroupVersionKind]CustomAccessor
CustomAccessors() map[schema.GroupVersionKind]CustomAccessor
HasSynced() bool
LoadConfig(customizations []*configv1alpha1.ResourceInterpreterCustomization)
}
@ -37,8 +37,8 @@ type interpreterConfigManager struct {
configuration atomic.Value
}
// LuaScriptAccessors returns all cached configurations.
func (configManager *interpreterConfigManager) LuaScriptAccessors() map[schema.GroupVersionKind]CustomAccessor {
// CustomAccessors returns all cached configurations.
func (configManager *interpreterConfigManager) CustomAccessors() map[schema.GroupVersionKind]CustomAccessor {
return configManager.configuration.Load().(map[schema.GroupVersionKind]CustomAccessor)
}

View File

@ -122,7 +122,7 @@ func Test_interpreterConfigManager_LuaScriptAccessors(t *testing.T) {
t.Errorf("informer has not been synced")
}
gotAccessors := configManager.LuaScriptAccessors()
gotAccessors := configManager.CustomAccessors()
for gvk, gotAccessor := range gotAccessors {
wantAccessor, ok := tt.want[gvk]
if !ok {

View File

@ -32,114 +32,185 @@ func NewConfigurableInterpreter(informer genericmanager.SingleClusterInformerMan
// HookEnabled tells if any hook exist for specific resource gvk and operation type.
func (c *ConfigurableInterpreter) HookEnabled(kind schema.GroupVersionKind, operationType configv1alpha1.InterpreterOperation) bool {
_, exist := c.getInterpreter(kind, operationType)
accessor, exist := c.getCustomAccessor(kind)
if !exist {
return exist
}
if operationType == configv1alpha1.InterpreterOperationInterpretDependency {
scripts := accessor.GetDependencyInterpretationLuaScripts()
return scripts != nil
}
var script string
switch operationType {
case configv1alpha1.InterpreterOperationAggregateStatus:
script = accessor.GetStatusAggregationLuaScript()
case configv1alpha1.InterpreterOperationInterpretHealth:
script = accessor.GetHealthInterpretationLuaScript()
case configv1alpha1.InterpreterOperationInterpretReplica:
script = accessor.GetReplicaResourceLuaScript()
case configv1alpha1.InterpreterOperationInterpretStatus:
script = accessor.GetStatusReflectionLuaScript()
case configv1alpha1.InterpreterOperationRetain:
script = accessor.GetRetentionLuaScript()
case configv1alpha1.InterpreterOperationReviseReplica:
script = accessor.GetReplicaRevisionLuaScript()
}
return len(script) > 0
}
// 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)
accessor, enabled := c.getCustomAccessor(object.GroupVersionKind())
if !enabled {
return
}
replicas, requires, err = c.luaVM.GetReplicas(object, luaScript)
script := accessor.GetReplicaResourceLuaScript()
if len(script) == 0 {
enabled = false
return
}
replicas, requires, err = c.luaVM.GetReplicas(object, script)
return
}
// 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)
accessor, enabled := c.getCustomAccessor(object.GroupVersionKind())
if !enabled {
return
}
revised, err = c.luaVM.ReviseReplica(object, replica, luaScript)
script := accessor.GetReplicaRevisionLuaScript()
if len(script) == 0 {
enabled = false
return
}
revised, err = c.luaVM.ReviseReplica(object, replica, script)
return
}
// 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)
accessor, enabled := c.getCustomAccessor(desired.GroupVersionKind())
if !enabled {
return
}
retained, err = c.luaVM.Retain(desired, observed, luaScript)
script := accessor.GetRetentionLuaScript()
if len(script) == 0 {
enabled = false
return
}
retained, err = c.luaVM.Retain(desired, observed, script)
return
}
// 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)
accessor, enabled := c.getCustomAccessor(object.GroupVersionKind())
if !enabled {
return
}
status, err = c.luaVM.AggregateStatus(object, aggregatedStatusItems, luaScript)
script := accessor.GetStatusAggregationLuaScript()
if len(script) == 0 {
enabled = false
return
}
status, err = c.luaVM.AggregateStatus(object, aggregatedStatusItems, script)
return
}
// 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)
accessor, enabled := c.getCustomAccessor(object.GroupVersionKind())
if !enabled {
return
}
dependencies, err = c.luaVM.GetDependencies(object, luaScript)
scripts := accessor.GetDependencyInterpretationLuaScripts()
if scripts == nil {
enabled = false
return
}
referenceSet := newDependencySet()
for _, luaScript := range scripts {
var references []configv1alpha1.DependentObjectReference
references, err = c.luaVM.GetDependencies(object, luaScript)
if err != nil {
klog.Errorf("Failed to get DependentObjectReferences from object: %v %s/%s, error: %v",
object.GroupVersionKind(), object.GetNamespace(), object.GetName(), err)
return
}
referenceSet.insert(references...)
}
dependencies = referenceSet.list()
return
}
// 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)
accessor, enabled := c.getCustomAccessor(object.GroupVersionKind())
if !enabled {
return
}
status, err = c.luaVM.ReflectStatus(object, luaScript)
script := accessor.GetStatusReflectionLuaScript()
if len(script) == 0 {
enabled = false
return
}
status, err = c.luaVM.ReflectStatus(object, script)
return
}
// 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)
accessor, enabled := c.getCustomAccessor(object.GroupVersionKind())
if !enabled {
return
}
health, err = c.luaVM.InterpretHealth(object, luaScript)
script := accessor.GetHealthInterpretationLuaScript()
if len(script) == 0 {
enabled = false
return
}
health, err = c.luaVM.InterpretHealth(object, script)
return
}
func (c *ConfigurableInterpreter) getInterpreter(kind schema.GroupVersionKind, operationType configv1alpha1.InterpreterOperation) (string, bool) {
func (c *ConfigurableInterpreter) getCustomAccessor(kind schema.GroupVersionKind) (configmanager.CustomAccessor, bool) {
if !c.configManager.HasSynced() {
klog.Errorf("not yet ready to handle request")
return "", false
return nil, false
}
accessors, exist := c.configManager.LuaScriptAccessors()[kind]
if !exist {
return "", false
}
var script string
switch operationType {
case configv1alpha1.InterpreterOperationAggregateStatus:
script = accessors.GetStatusAggregationLuaScript()
case configv1alpha1.InterpreterOperationInterpretHealth:
script = accessors.GetHealthInterpretationLuaScript()
case configv1alpha1.InterpreterOperationInterpretDependency:
script = accessors.GetDependencyInterpretationLuaScript()
case configv1alpha1.InterpreterOperationInterpretReplica:
script = accessors.GetReplicaResourceLuaScript()
case configv1alpha1.InterpreterOperationInterpretStatus:
script = accessors.GetStatusReflectionLuaScript()
case configv1alpha1.InterpreterOperationRetain:
script = accessors.GetRetentionLuaScript()
case configv1alpha1.InterpreterOperationReviseReplica:
script = accessors.GetReplicaRevisionLuaScript()
}
return script, len(script) > 0
accessor, exist := c.configManager.CustomAccessors()[kind]
return accessor, exist
}
// LoadConfig loads and stores rules from customizations

View File

@ -0,0 +1,36 @@
package configurableinterpreter
import (
"fmt"
"sort"
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
)
type dependencySet map[configv1alpha1.DependentObjectReference]struct{}
func newDependencySet(items ...configv1alpha1.DependentObjectReference) dependencySet {
s := make(dependencySet, len(items))
s.insert(items...)
return s
}
func (s dependencySet) insert(items ...configv1alpha1.DependentObjectReference) dependencySet {
for _, item := range items {
s[item] = struct{}{}
}
return s
}
func (s dependencySet) list() []configv1alpha1.DependentObjectReference {
keys := make([]configv1alpha1.DependentObjectReference, len(s))
index := 0
for key := range s {
keys[index] = key
index++
}
sort.Slice(keys, func(i, j int) bool {
return fmt.Sprintf("%s", keys[i]) < fmt.Sprintf("%s", keys[j])
})
return keys
}

View File

@ -0,0 +1,69 @@
package configurableinterpreter
import (
"reflect"
"testing"
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
)
func Test_dependencySet_list(t *testing.T) {
tests := []struct {
name string
s dependencySet
want []configv1alpha1.DependentObjectReference
}{
{
name: "empty set",
s: newDependencySet(),
want: []configv1alpha1.DependentObjectReference{},
},
{
name: "new with items",
s: newDependencySet([]configv1alpha1.DependentObjectReference{
{APIVersion: "v1", Kind: "Secret", Namespace: "foo", Name: "foo"},
}...),
want: []configv1alpha1.DependentObjectReference{
{APIVersion: "v1", Kind: "Secret", Namespace: "foo", Name: "foo"},
},
},
{
name: "insert with different items",
s: newDependencySet([]configv1alpha1.DependentObjectReference{
{APIVersion: "v1", Kind: "Secret", Namespace: "foo", Name: "foo"},
}...).insert(
[]configv1alpha1.DependentObjectReference{
{APIVersion: "v1", Kind: "Configmap", Namespace: "foo", Name: "foo"},
}...),
want: []configv1alpha1.DependentObjectReference{
{APIVersion: "v1", Kind: "Configmap", Namespace: "foo", Name: "foo"},
{APIVersion: "v1", Kind: "Secret", Namespace: "foo", Name: "foo"},
},
},
{
name: "insert with same items",
s: newDependencySet([]configv1alpha1.DependentObjectReference{
{APIVersion: "v1", Kind: "Secret", Namespace: "foo", Name: "foo"},
}...).insert(
[]configv1alpha1.DependentObjectReference{
{APIVersion: "v1", Kind: "Configmap", Namespace: "foo", Name: "foo"},
}...).insert(
[]configv1alpha1.DependentObjectReference{
{APIVersion: "v1", Kind: "Secret", Namespace: "foo", Name: "foo"},
{APIVersion: "apps/v1", Kind: "Deployment", Namespace: "foo", Name: "foo"},
}...),
want: []configv1alpha1.DependentObjectReference{
{APIVersion: "apps/v1", Kind: "Deployment", Namespace: "foo", Name: "foo"},
{APIVersion: "v1", Kind: "Configmap", Namespace: "foo", Name: "foo"},
{APIVersion: "v1", Kind: "Secret", Namespace: "foo", Name: "foo"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.s.list(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("dependencySet.list() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -16,6 +16,10 @@ func validateCustomizationRule(oldRules, newRules *configv1alpha1.ResourceInterp
return nil
}
for _, rule := range interpreter.AllResourceInterpreterCustomizationRules {
// skip InterpretDependency operation because it supports multiple rules.
if rule.Name() == string(configv1alpha1.InterpreterOperationInterpretDependency) {
continue
}
oldScript := rule.GetScript(oldRules)
newScript := rule.GetScript(newRules)
if oldScript != "" && newScript != "" {

View File

@ -256,7 +256,7 @@ func Test_validateCustomizationRule(t *testing.T) {
},
},
},
wantErr: true,
wantErr: false,
},
}
for _, tt := range tests {

View File

@ -282,6 +282,7 @@ var _ = framework.SerialDescribe("Resource interpreter customization testing", f
// We only need to test any one of the member clusters.
var targetCluster string
ginkgo.When("Apply single ResourceInterpreterCustomization without DependencyInterpretation operation", func() {
ginkgo.BeforeEach(func() {
targetCluster = framework.ClusterNames()[rand.Intn(len(framework.ClusterNames()))]
deployment = testhelper.NewDeployment(testNamespace, deploymentNamePrefix+rand.String(RandomStrLength))
@ -323,7 +324,7 @@ var _ = framework.SerialDescribe("Resource interpreter customization testing", f
configv1alpha1.CustomizationRules{
ReplicaResource: &configv1alpha1.ReplicaResourceRequirement{
LuaScript: `
function GetReplicas(desiredObj)
function GetReplicas(desiredObj)
replica = desiredObj.spec.replicas + 1
requirement = {}
requirement.nodeClaim = {}
@ -331,7 +332,7 @@ function GetReplicas(desiredObj)
requirement.nodeClaim.tolerations = desiredObj.spec.template.spec.tolerations
requirement.resourceRequest = desiredObj.spec.template.spec.containers[1].resources.limits
return replica, requirement
end`,
end`,
},
})
})
@ -375,10 +376,10 @@ end`,
configv1alpha1.CustomizationRules{
ReplicaRevision: &configv1alpha1.ReplicaRevision{
LuaScript: `
function ReviseReplica(obj, desiredReplica)
function ReviseReplica(obj, desiredReplica)
obj.spec.replicas = desiredReplica + 1
return obj
end`,
end`,
},
})
})
@ -431,10 +432,10 @@ end`,
configv1alpha1.CustomizationRules{
Retention: &configv1alpha1.LocalValueRetention{
LuaScript: `
function Retain(desiredObj, observedObj)
function Retain(desiredObj, observedObj)
desiredObj.spec.paused = observedObj.spec.paused
return desiredObj
end`,
end`,
},
})
})
@ -473,7 +474,7 @@ end`,
configv1alpha1.CustomizationRules{
StatusAggregation: &configv1alpha1.StatusAggregation{
LuaScript: `
function AggregateStatus(desiredObj, statusItems)
function AggregateStatus(desiredObj, statusItems)
if statusItems == nil then
return desiredObj
end
@ -488,7 +489,7 @@ function AggregateStatus(desiredObj, statusItems)
end
desiredObj.status.replicas = replicas
return desiredObj
end`,
end`,
},
})
})
@ -520,12 +521,12 @@ end`,
configv1alpha1.CustomizationRules{
StatusReflection: &configv1alpha1.StatusReflection{
LuaScript: `
function ReflectStatus (observedObj)
function ReflectStatus (observedObj)
if observedObj.status == nil then
return nil
end
return observedObj.status
end`,
end`,
},
})
})
@ -550,9 +551,9 @@ end`,
configv1alpha1.CustomizationRules{
HealthInterpretation: &configv1alpha1.HealthInterpretation{
LuaScript: `
function InterpretHealth(observedObj)
function InterpretHealth(observedObj)
return observedObj.status.readyReplicas == observedObj.spec.replicas
end `,
end `,
},
})
})
@ -594,15 +595,49 @@ end `,
})
})
})
})
ginkgo.When("Apply multi ResourceInterpreterCustomization with DependencyInterpretation operation", func() {
var customizationAnother *configv1alpha1.ResourceInterpreterCustomization
var configMapName string
var configMap *corev1.ConfigMap
ginkgo.Context("InterpreterOperation DependencyInterpretation testing", func() {
var saName string
var sa *corev1.ServiceAccount
ginkgo.BeforeEach(func() {
targetCluster = framework.ClusterNames()[rand.Intn(len(framework.ClusterNames()))]
deployment = testhelper.NewDeployment(testNamespace, deploymentNamePrefix+rand.String(RandomStrLength))
configMapName = configMapNamePrefix + rand.String(RandomStrLength)
configMap = testhelper.NewConfigMap(testNamespace, configMapName, map[string]string{"user": "karmada"})
deployment.Spec.Template.Spec.Volumes = []corev1.Volume{{
Name: "vol-configmap",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: configMapName,
}}}}}
saName = saNamePrefix + rand.String(RandomStrLength)
sa = testhelper.NewServiceaccount(testNamespace, saName)
deployment = testhelper.NewDeploymentWithServiceAccount(testNamespace, deployment.Name, saName)
deployment.Spec.Template.Spec.ServiceAccountName = saName
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},
},
})
policy.Spec.PropagateDeps = true
customization = testhelper.NewResourceInterpreterCustomization(
"interpreter-customization"+rand.String(RandomStrLength),
configv1alpha1.CustomizationTarget{
@ -632,25 +667,84 @@ function GetDependencies(desiredObj)
end `,
},
})
customizationAnother = testhelper.NewResourceInterpreterCustomization(
"interpreter-customization"+rand.String(RandomStrLength),
configv1alpha1.CustomizationTarget{
APIVersion: "apps/v1",
Kind: "Deployment",
},
configv1alpha1.CustomizationRules{
DependencyInterpretation: &configv1alpha1.DependencyInterpretation{
LuaScript: `
function GetDependencies(desiredObj)
dependentSas = {}
refs = {}
if desiredObj.spec.template.spec.volumes == nil then
return refs
end
local idx = 1
for index, volume in pairs(desiredObj.spec.template.spec.volumes) do
if volume.configMap ~= nil then
dependObj = {}
dependObj.apiVersion = 'v1'
dependObj.kind = 'ConfigMap'
dependObj.name = volume.configMap.name
dependObj.namespace = desiredObj.metadata.namespace
refs[idx] = dependObj
idx = idx + 1
end
end
return refs
end `,
},
})
ginkgo.It("DependencyInterpretation testing", func() {
ginkgo.By("check if the serviceAccount is propagated automatically", func() {
})
ginkgo.JustBeforeEach(func() {
framework.CreateResourceInterpreterCustomization(karmadaClient, customization)
framework.CreateResourceInterpreterCustomization(karmadaClient, customizationAnother)
// Wait for resource interpreter informer synced.
time.Sleep(time.Second)
framework.CreateServiceAccount(kubeClient, sa)
framework.CreateConfigMap(kubeClient, configMap)
framework.CreatePropagationPolicy(karmadaClient, policy)
framework.CreateDeployment(kubeClient, deployment)
ginkgo.DeferCleanup(func() {
framework.RemoveServiceAccount(kubeClient, sa.GetNamespace(), sa.GetName())
framework.RemoveServiceAccount(kubeClient, sa.Namespace, sa.Name)
framework.RemoveConfigMap(kubeClient, configMap.Namespace, configMap.Name)
framework.RemoveDeployment(kubeClient, deployment.Namespace, deployment.Name)
framework.RemovePropagationPolicy(karmadaClient, policy.Namespace, policy.Name)
framework.DeleteResourceInterpreterCustomization(karmadaClient, customization.Name)
framework.DeleteResourceInterpreterCustomization(karmadaClient, customizationAnother.Name)
})
})
ginkgo.Context("InterpreterOperation DependencyInterpretation testing", func() {
ginkgo.It("DependencyInterpretation testing", func() {
ginkgo.By("check if the resources is propagated automatically", func() {
framework.WaitDeploymentPresentOnClusterFitWith(targetCluster, deployment.Namespace, deployment.Name,
func(deployment *appsv1.Deployment) bool {
return true
})
framework.WaitServiceAccountPresentOnClusterFitWith(targetCluster, deployment.Namespace, sa.GetName(),
framework.WaitServiceAccountPresentOnClusterFitWith(targetCluster, sa.Namespace, sa.Name,
func(sa *corev1.ServiceAccount) bool {
return true
})
framework.WaitConfigMapPresentOnClusterFitWith(targetCluster, configMap.Namespace, configMap.Name,
func(configmap *corev1.ConfigMap) bool {
return true
})
})
})
})
})
})