mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-18 20:17:04 +00:00
Feat: mechanism to let user add relationship mapping rule by configmap (#3968)
* WIP add some code Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com> small fix Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com> fix all tests Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com> * add comment Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com> fix ci delete useless code Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com> go mod vendor Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com> * fix failed test Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com> * more test Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
This commit is contained in:
@@ -96,6 +96,8 @@ const (
|
||||
|
||||
// LabelProject recorde the project the resource belong to
|
||||
LabelProject = "core.oam.dev/project"
|
||||
|
||||
LabelResourceRules = "rules.oam.dev/resources"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -156,6 +156,11 @@ func (h *provider) GetApplicationResourceTree(ctx wfContext.Context, v *value.Va
|
||||
if err != nil {
|
||||
return v.FillObject(err.Error(), "err")
|
||||
}
|
||||
// merge user defined customize rule before every request.
|
||||
err = mergeCustomRules(context.Background(), h.cli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, resource := range appResList {
|
||||
root := querytypes.ResourceTreeNode{
|
||||
APIVersion: resource.APIVersion,
|
||||
|
||||
@@ -740,7 +740,7 @@ options: {
|
||||
Name: "vela-system",
|
||||
},
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(err).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
|
||||
for _, s := range testServicelist {
|
||||
ns := "default"
|
||||
if s["namespace"] != nil {
|
||||
|
||||
@@ -20,6 +20,9 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
velatypes "github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
@@ -31,11 +34,15 @@ import (
|
||||
"k8s.io/kubectl/pkg/util/podutils"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
"github.com/oam-dev/kubevela/pkg/velaql/providers/query/types"
|
||||
)
|
||||
|
||||
// relationshipKey is the configmap key of relationShip rule
|
||||
var relationshipKey = "rules"
|
||||
|
||||
// set the iterator max depth is 5
|
||||
var maxDepth = 5
|
||||
|
||||
@@ -84,6 +91,12 @@ type ResourceType struct {
|
||||
Kind string `json:"kind,omitempty"`
|
||||
}
|
||||
|
||||
// customRule define the customize rule created by user
|
||||
type customRule struct {
|
||||
ParentResourceType *GroupResourceType `json:"parentResourceType,omitempty"`
|
||||
ChildrenResourceType []ResourceType `json:"childrenResourceType,omitempty"`
|
||||
}
|
||||
|
||||
// ChildrenResourcesRule define the relationShip between parentObject and children resource
|
||||
type ChildrenResourcesRule struct {
|
||||
// every subResourceType can have a specified genListOptionFunc.
|
||||
@@ -446,3 +459,36 @@ func iteratorChildResources(ctx context.Context, cluster string, k8sClient clien
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// mergeCustomRules merge the customize
|
||||
func mergeCustomRules(ctx context.Context, k8sClient client.Client) error {
|
||||
rulesList := v12.ConfigMapList{}
|
||||
if err := k8sClient.List(ctx, &rulesList, client.InNamespace(velatypes.DefaultKubeVelaNS), client.HasLabels{oam.LabelResourceRules}); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range rulesList.Items {
|
||||
ruleStr := item.Data[relationshipKey]
|
||||
var customRules []*customRule
|
||||
err := yaml.Unmarshal([]byte(ruleStr), &customRules)
|
||||
if err != nil {
|
||||
// don't let one miss-config configmap brake whole process
|
||||
log.Logger.Errorf("relationship rule configamp %s miss config %v", item.Name, err)
|
||||
}
|
||||
for _, rule := range customRules {
|
||||
if cResource, ok := globalRule[*rule.ParentResourceType]; ok {
|
||||
for _, resourceType := range rule.ChildrenResourceType {
|
||||
if _, ok := cResource.CareResource[resourceType]; !ok {
|
||||
cResource.CareResource[resourceType] = nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
caredResources := map[ResourceType]genListOptionFunc{}
|
||||
for _, resourceType := range rule.ChildrenResourceType {
|
||||
caredResources[resourceType] = nil
|
||||
}
|
||||
globalRule[*rule.ParentResourceType] = ChildrenResourcesRule{DefaultGenListOptionFunc: nil, CareResource: caredResources}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
types3 "github.com/oam-dev/kubevela/apis/types"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/model/value"
|
||||
@@ -844,3 +846,101 @@ var _ = Describe("unit-test to e2e test", func() {
|
||||
Expect(len(res.List)).Should(Equal(2))
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("test merge globalRules", func() {
|
||||
cloneSetStr := `
|
||||
- parentResourceType:
|
||||
group: apps.kruise.io
|
||||
kind: CloneSet
|
||||
childrenResourceType:
|
||||
- apiVersion: v1
|
||||
kind: Pod
|
||||
- apiVersion: apps/v1
|
||||
kind: ControllerRevision
|
||||
`
|
||||
daemonSetStr := `
|
||||
- parentResourceType:
|
||||
group: apps
|
||||
kind: DaemonSet
|
||||
childrenResourceType:
|
||||
- apiVersion: v1
|
||||
kind: Pod
|
||||
- apiVersion: apps/v1
|
||||
kind: ControllerRevision
|
||||
`
|
||||
stsStr := `
|
||||
- parentResourceType:
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
childrenResourceType:
|
||||
- apiVersion: v1
|
||||
kind: Pod
|
||||
- apiVersion: apps/v1
|
||||
kind: ControllerRevision
|
||||
`
|
||||
missConfigedStr := `
|
||||
- parentResourceType:
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
childrenResourceType:
|
||||
- apiVersion: v1
|
||||
kind: Pod
|
||||
- apiVersion: apps/v1
|
||||
kind: ControllerRevision
|
||||
`
|
||||
|
||||
It("test merge rules", func() {
|
||||
Expect(k8sClient.Create(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "vela-system"}})).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
|
||||
cloneSetConfigMap := v1.ConfigMap{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: types3.DefaultKubeVelaNS, Name: "cloneset", Labels: map[string]string{oam.LabelResourceRules: "true"}},
|
||||
Data: map[string]string{relationshipKey: cloneSetStr},
|
||||
}
|
||||
Expect(k8sClient.Create(ctx, &cloneSetConfigMap)).Should(BeNil())
|
||||
|
||||
daemonSetConfigMap := v1.ConfigMap{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: types3.DefaultKubeVelaNS, Name: "daemonset", Labels: map[string]string{oam.LabelResourceRules: "true"}},
|
||||
Data: map[string]string{relationshipKey: daemonSetStr},
|
||||
}
|
||||
Expect(k8sClient.Create(ctx, &daemonSetConfigMap)).Should(BeNil())
|
||||
|
||||
stsConfigMap := v1.ConfigMap{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: types3.DefaultKubeVelaNS, Name: "sts", Labels: map[string]string{oam.LabelResourceRules: "true"}},
|
||||
Data: map[string]string{relationshipKey: stsStr},
|
||||
}
|
||||
Expect(k8sClient.Create(ctx, &stsConfigMap)).Should(BeNil())
|
||||
|
||||
missConfigedCm := v1.ConfigMap{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: types3.DefaultKubeVelaNS, Name: "miss-configed", Labels: map[string]string{oam.LabelResourceRules: "true"}},
|
||||
Data: map[string]string{relationshipKey: missConfigedStr},
|
||||
}
|
||||
Expect(k8sClient.Create(ctx, &missConfigedCm)).Should(BeNil())
|
||||
|
||||
Expect(mergeCustomRules(ctx, k8sClient)).Should(BeNil())
|
||||
childrenResources, ok := globalRule[GroupResourceType{Group: "apps.kruise.io", Kind: "CloneSet"}]
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(childrenResources.DefaultGenListOptionFunc).Should(BeNil())
|
||||
Expect(len(childrenResources.CareResource)).Should(BeEquivalentTo(2))
|
||||
specifyFunc, ok := childrenResources.CareResource[ResourceType{APIVersion: "v1", Kind: "Pod"}]
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(specifyFunc).Should(BeNil())
|
||||
|
||||
dsChildrenResources, ok := globalRule[GroupResourceType{Group: "apps", Kind: "DaemonSet"}]
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(dsChildrenResources.DefaultGenListOptionFunc).Should(BeNil())
|
||||
Expect(len(dsChildrenResources.CareResource)).Should(BeEquivalentTo(2))
|
||||
dsSpecifyFunc, ok := dsChildrenResources.CareResource[ResourceType{APIVersion: "v1", Kind: "Pod"}]
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(dsSpecifyFunc).Should(BeNil())
|
||||
crSpecifyFunc, ok := dsChildrenResources.CareResource[ResourceType{APIVersion: "apps/v1", Kind: "ControllerRevision"}]
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(crSpecifyFunc).Should(BeNil())
|
||||
|
||||
stsChildrenResources, ok := globalRule[GroupResourceType{Group: "apps", Kind: "StatefulSet"}]
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(stsChildrenResources.DefaultGenListOptionFunc).Should(BeNil())
|
||||
Expect(len(stsChildrenResources.CareResource)).Should(BeEquivalentTo(2))
|
||||
stsCrSpecifyFunc, ok := stsChildrenResources.CareResource[ResourceType{APIVersion: "apps/v1", Kind: "ControllerRevision"}]
|
||||
Expect(ok).Should(BeTrue())
|
||||
Expect(stsCrSpecifyFunc).Should(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user