Fix: multicluster cluster scope ref

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
This commit is contained in:
Somefive
2022-11-23 16:48:11 +08:00
parent 8516ede345
commit 40a9a981d9
2 changed files with 55 additions and 13 deletions

View File

@@ -19,6 +19,7 @@ package component
import (
"context"
"encoding/json"
"fmt"
"strings"
"github.com/pkg/errors"
@@ -141,10 +142,18 @@ func SelectRefObjectsForDispatch(ctx context.Context, cli client.Client, appNs s
if err != nil {
return nil, err
}
isNamespaced, err := IsGroupVersionKindNamespaceScoped(cli.RESTMapper(), gvk)
if err != nil {
return nil, err
}
if selector.Name == "" && labelSelector != nil {
uns := &unstructured.UnstructuredList{}
uns.SetGroupVersionKind(gvk)
if err = cli.List(ctx, uns, client.InNamespace(ns), client.MatchingLabels(labelSelector)); err != nil {
opts := []client.ListOption{client.MatchingLabels(labelSelector)}
if isNamespaced {
opts = append(opts, client.InNamespace(ns))
}
if err = cli.List(ctx, uns, opts...); err != nil {
return nil, errors.Wrapf(err, "failed to load ref object %s with selector", gvk.Kind)
}
for _, _un := range uns.Items {
@@ -154,7 +163,9 @@ func SelectRefObjectsForDispatch(ctx context.Context, cli client.Client, appNs s
un := &unstructured.Unstructured{}
un.SetGroupVersionKind(gvk)
un.SetName(selector.Name)
un.SetNamespace(ns)
if isNamespaced {
un.SetNamespace(ns)
}
if selector.Name == "" {
un.SetName(compName)
}
@@ -248,3 +259,15 @@ func ConvertUnstructuredsToReferredObjects(uns []*unstructured.Unstructured) (re
}
return refObjs, nil
}
// IsGroupVersionKindNamespaceScoped check if the target GroupVersionKind is namespace scoped resource
func IsGroupVersionKindNamespaceScoped(mapper meta.RESTMapper, gvk schema.GroupVersionKind) (bool, error) {
mappings, err := mapper.RESTMappings(gvk.GroupKind(), gvk.Version)
if err != nil {
return false, err
}
if len(mappings) == 0 {
return false, fmt.Errorf("unable to fund the mappings for gvk %s", gvk)
}
return mappings[0].Scope.Name() == meta.RESTScopeNameNamespace, nil
}

View File

@@ -25,6 +25,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilfeature "k8s.io/apiserver/pkg/util/feature"
@@ -111,6 +112,10 @@ var _ = Describe("Test ref-objects functions", func() {
Namespace: "test",
Labels: map[string]string{"key": "value"},
},
}, &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster-role",
},
}} {
Expect(k8sClient.Create(context.Background(), obj)).Should(Succeed())
}
@@ -119,25 +124,26 @@ var _ = Describe("Test ref-objects functions", func() {
Object: map[string]interface{}{
"apiVersion": apiVersion,
"kind": kind,
"metadata": map[string]interface{}{
"name": name,
"namespace": namespace,
},
"metadata": map[string]interface{}{"name": name},
},
}
if namespace != "" {
un.SetNamespace(namespace)
}
if labels != nil {
un.Object["metadata"].(map[string]interface{})["labels"] = labels
}
return un
}
testcases := map[string]struct {
Input v1alpha1.ObjectReferrer
compName string
appNs string
Output []*unstructured.Unstructured
Error string
Scope string
IsService bool
Input v1alpha1.ObjectReferrer
compName string
appNs string
Output []*unstructured.Unstructured
Error string
Scope string
IsService bool
IsClusterRole bool
}{
"normal": {
Input: v1alpha1.ObjectReferrer{
@@ -259,6 +265,16 @@ var _ = Describe("Test ref-objects functions", func() {
Scope: RefObjectsAvailableScopeCluster,
Error: "cannot refer to objects outside control plane",
},
"test-cluster-scope-resource": {
Input: v1alpha1.ObjectReferrer{
ObjectTypeIdentifier: v1alpha1.ObjectTypeIdentifier{Resource: "clusterrole"},
ObjectSelector: v1alpha1.ObjectSelector{Name: "test-cluster-role"},
},
appNs: "test",
Scope: RefObjectsAvailableScopeCluster,
Output: []*unstructured.Unstructured{createUnstructured("rbac.authorization.k8s.io/v1", "ClusterRole", "test-cluster-role", "", nil)},
IsClusterRole: true,
},
}
for name, tt := range testcases {
By("Test " + name)
@@ -276,6 +292,9 @@ var _ = Describe("Test ref-objects functions", func() {
Expect(output[0].Object["kind"]).Should(Equal("Service"))
Expect(output[0].Object["spec"].(map[string]interface{})["clusterIP"]).Should(BeNil())
} else {
if tt.IsClusterRole {
delete(output[0].Object, "rules")
}
Expect(output).Should(Equal(tt.Output))
}
}