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:
wyike
2022-05-25 16:44:46 +08:00
committed by GitHub
parent dfb33e0ea7
commit dae0358bc0
5 changed files with 154 additions and 1 deletions
+2
View File
@@ -96,6 +96,8 @@ const (
// LabelProject recorde the project the resource belong to
LabelProject = "core.oam.dev/project"
LabelResourceRules = "rules.oam.dev/resources"
)
const (
+5
View File
@@ -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,
+1 -1
View File
@@ -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 {
+46
View File
@@ -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
}
+100
View File
@@ -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())
})
})