Merge pull request #547 from RainbowMango/pr_validate_skipped_resource
Enable validation for --skipped-propagating-apis flag
This commit is contained in:
commit
1cd23bc45a
|
@ -96,6 +96,9 @@ func Run(ctx context.Context, opts *options.Options) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setupControllers initialize controllers and setup one by one.
|
||||||
|
// Note: ignore cyclomatic complexity check(by gocyclo) because it will not effect readability.
|
||||||
|
//nolint:gocyclo
|
||||||
func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stopChan <-chan struct{}) {
|
func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stopChan <-chan struct{}) {
|
||||||
resetConfig := mgr.GetConfig()
|
resetConfig := mgr.GetConfig()
|
||||||
dynamicClientSet := dynamic.NewForConfigOrDie(resetConfig)
|
dynamicClientSet := dynamic.NewForConfigOrDie(resetConfig)
|
||||||
|
@ -103,8 +106,11 @@ func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stop
|
||||||
objectWatcher := objectwatcher.NewObjectWatcher(mgr.GetClient(), mgr.GetRESTMapper(), util.NewClusterDynamicClientSet)
|
objectWatcher := objectwatcher.NewObjectWatcher(mgr.GetClient(), mgr.GetRESTMapper(), util.NewClusterDynamicClientSet)
|
||||||
overrideManager := overridemanager.New(mgr.GetClient())
|
overrideManager := overridemanager.New(mgr.GetClient())
|
||||||
skippedResourceConfig := util.NewSkippedResourceConfig()
|
skippedResourceConfig := util.NewSkippedResourceConfig()
|
||||||
// TODO(pigletfly): add SkippedPropagatingAPIs validation
|
if err := skippedResourceConfig.Parse(opts.SkippedPropagatingAPIs); err != nil {
|
||||||
skippedResourceConfig.Parse(opts.SkippedPropagatingAPIs)
|
// TODO(RainbowMango): the parameter should be checked earlier.
|
||||||
|
// Consider add validation to 'options.Options'
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
skippedPropagatingNamespaces := map[string]struct{}{}
|
skippedPropagatingNamespaces := map[string]struct{}{}
|
||||||
for _, ns := range opts.SkippedPropagatingNamespaces {
|
for _, ns := range opts.SkippedPropagatingNamespaces {
|
||||||
skippedPropagatingNamespaces[ns] = struct{}{}
|
skippedPropagatingNamespaces[ns] = struct{}{}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/klog/v2"
|
|
||||||
|
|
||||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||||
|
@ -35,34 +35,36 @@ func NewSkippedResourceConfig() *SkippedResourceConfig {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse to parse tokens to SkippedResourceConfig
|
// Parse parses the --skipped-propagating-apis input.
|
||||||
func (r *SkippedResourceConfig) Parse(c string) {
|
func (r *SkippedResourceConfig) Parse(c string) error {
|
||||||
// v1/Node,Pod;networking.k8s.io/v1beta1/Ingress,IngressClass
|
// default(empty) input
|
||||||
// group networking.k8s.io
|
|
||||||
// group version networking.k8s.io/v1
|
|
||||||
// group version kind networking.k8s.io/v1/Ingress
|
|
||||||
// corev1 has no group
|
|
||||||
if c == "" {
|
if c == "" {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens := strings.Split(c, ";")
|
tokens := strings.Split(c, ";")
|
||||||
for _, token := range tokens {
|
for _, token := range tokens {
|
||||||
r.parseSingle(token)
|
if err := r.parseSingle(token); err != nil {
|
||||||
|
return fmt.Errorf("parse --skipped-propagating-apis %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SkippedResourceConfig) parseSingle(token string) {
|
func (r *SkippedResourceConfig) parseSingle(token string) error {
|
||||||
switch strings.Count(token, "/") {
|
switch strings.Count(token, "/") {
|
||||||
|
// Assume user don't want to skip the 'core'(no group name) group.
|
||||||
|
// So, it should be the case "<group>".
|
||||||
case 0:
|
case 0:
|
||||||
// Group
|
|
||||||
r.Groups[token] = struct{}{}
|
r.Groups[token] = struct{}{}
|
||||||
|
// it should be the case "<group>/<version>"
|
||||||
case 1:
|
case 1:
|
||||||
|
// for core group which don't have the group name, the case should be "v1/<kind>" or "v1/<kind>,<kind>..."
|
||||||
if strings.HasPrefix(token, "v1") {
|
if strings.HasPrefix(token, "v1") {
|
||||||
// core v1
|
var kinds []string
|
||||||
kinds := []string{}
|
|
||||||
for _, k := range strings.Split(token, ",") {
|
for _, k := range strings.Split(token, ",") {
|
||||||
if strings.Contains(k, "/") {
|
if strings.Contains(k, "/") { // "v1/<kind>"
|
||||||
s := strings.Split(k, "/")
|
s := strings.Split(k, "/")
|
||||||
kinds = append(kinds, s[1])
|
kinds = append(kinds, s[1])
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,20 +78,22 @@ func (r *SkippedResourceConfig) parseSingle(token string) {
|
||||||
}
|
}
|
||||||
r.GroupVersionKinds[gvk] = struct{}{}
|
r.GroupVersionKinds[gvk] = struct{}{}
|
||||||
}
|
}
|
||||||
} else {
|
} else { // case "<group>/<version>"
|
||||||
// GroupVersion
|
parts := strings.Split(token, "/")
|
||||||
i := strings.Index(token, "/")
|
if len(parts) != 2 {
|
||||||
|
return fmt.Errorf("invalid token: %s", token)
|
||||||
|
}
|
||||||
gv := schema.GroupVersion{
|
gv := schema.GroupVersion{
|
||||||
Group: token[:i],
|
Group: parts[0],
|
||||||
Version: token[i+1:],
|
Version: parts[1],
|
||||||
}
|
}
|
||||||
r.GroupVersions[gv] = struct{}{}
|
r.GroupVersions[gv] = struct{}{}
|
||||||
}
|
}
|
||||||
|
// parameter format: "<group>/<version>/<kind>" or "<group>/<version>/<kind>,<kind>..."
|
||||||
case 2:
|
case 2:
|
||||||
// GroupVersionKind
|
|
||||||
g := ""
|
g := ""
|
||||||
v := ""
|
v := ""
|
||||||
kinds := []string{}
|
var kinds []string
|
||||||
for _, k := range strings.Split(token, ",") {
|
for _, k := range strings.Split(token, ",") {
|
||||||
if strings.Contains(k, "/") {
|
if strings.Contains(k, "/") {
|
||||||
s := strings.Split(k, "/")
|
s := strings.Split(k, "/")
|
||||||
|
@ -109,8 +113,10 @@ func (r *SkippedResourceConfig) parseSingle(token string) {
|
||||||
r.GroupVersionKinds[gvk] = struct{}{}
|
r.GroupVersionKinds[gvk] = struct{}{}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
klog.Error("Unsupported SkippedPropagatingAPIs: ", token)
|
return fmt.Errorf("invalid parameter: %s", token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GroupVersionDisabled returns whether GroupVersion is disabled.
|
// GroupVersionDisabled returns whether GroupVersion is disabled.
|
||||||
|
|
|
@ -11,32 +11,36 @@ func TestSkippedResourceConfigGVKParse(t *testing.T) {
|
||||||
input string
|
input string
|
||||||
out []schema.GroupVersionKind
|
out []schema.GroupVersionKind
|
||||||
}{
|
}{
|
||||||
{input: "v1/Node,Pod;networking.k8s.io/v1beta1/Ingress,IngressClass", out: []schema.GroupVersionKind{
|
{
|
||||||
{
|
input: "v1/Node,Pod;networking.k8s.io/v1beta1/Ingress,IngressClass",
|
||||||
Group: "",
|
out: []schema.GroupVersionKind{
|
||||||
Version: "v1",
|
{
|
||||||
Kind: "Node",
|
Group: "",
|
||||||
},
|
Version: "v1",
|
||||||
{
|
Kind: "Node",
|
||||||
Group: "",
|
},
|
||||||
Version: "v1",
|
{
|
||||||
Kind: "Pod",
|
Group: "",
|
||||||
},
|
Version: "v1",
|
||||||
{
|
Kind: "Pod",
|
||||||
Group: "networking.k8s.io",
|
},
|
||||||
Version: "v1beta1",
|
{
|
||||||
Kind: "Ingress",
|
Group: "networking.k8s.io",
|
||||||
},
|
Version: "v1beta1",
|
||||||
{
|
Kind: "Ingress",
|
||||||
Group: "networking.k8s.io",
|
},
|
||||||
Version: "v1beta1",
|
{
|
||||||
Kind: "IngressClass",
|
Group: "networking.k8s.io",
|
||||||
},
|
Version: "v1beta1",
|
||||||
}},
|
Kind: "IngressClass",
|
||||||
|
},
|
||||||
|
}},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
r := NewSkippedResourceConfig()
|
r := NewSkippedResourceConfig()
|
||||||
r.Parse(test.input)
|
if err := r.Parse(test.input); err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
for i, o := range test.out {
|
for i, o := range test.out {
|
||||||
ok := r.GroupVersionKindDisabled(o)
|
ok := r.GroupVersionKindDisabled(o)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -50,28 +54,32 @@ func TestResourceConfigGVParse(t *testing.T) {
|
||||||
input string
|
input string
|
||||||
out []schema.GroupVersion
|
out []schema.GroupVersion
|
||||||
}{
|
}{
|
||||||
{input: "networking.k8s.io/v1;test/v1beta1", out: []schema.GroupVersion{
|
{
|
||||||
{
|
input: "networking.k8s.io/v1;test/v1beta1",
|
||||||
Group: "networking.k8s.io",
|
out: []schema.GroupVersion{
|
||||||
Version: "v1",
|
{
|
||||||
},
|
Group: "networking.k8s.io",
|
||||||
{
|
Version: "v1",
|
||||||
Group: "networking.k8s.io",
|
},
|
||||||
Version: "v1",
|
{
|
||||||
},
|
Group: "networking.k8s.io",
|
||||||
{
|
Version: "v1",
|
||||||
Group: "test",
|
},
|
||||||
Version: "v1beta1",
|
{
|
||||||
},
|
Group: "test",
|
||||||
{
|
Version: "v1beta1",
|
||||||
Group: "test",
|
},
|
||||||
Version: "v1beta1",
|
{
|
||||||
},
|
Group: "test",
|
||||||
}},
|
Version: "v1beta1",
|
||||||
|
},
|
||||||
|
}},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
r := NewSkippedResourceConfig()
|
r := NewSkippedResourceConfig()
|
||||||
r.Parse(test.input)
|
if err := r.Parse(test.input); err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
for i, o := range test.out {
|
for i, o := range test.out {
|
||||||
ok := r.GroupVersionDisabled(o)
|
ok := r.GroupVersionDisabled(o)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -86,13 +94,17 @@ func TestSkippedResourceConfigGroupParse(t *testing.T) {
|
||||||
input string
|
input string
|
||||||
out []string
|
out []string
|
||||||
}{
|
}{
|
||||||
{input: "networking.k8s.io;test", out: []string{
|
{
|
||||||
"networking.k8s.io", "test",
|
input: "networking.k8s.io;test",
|
||||||
}},
|
out: []string{
|
||||||
|
"networking.k8s.io", "test",
|
||||||
|
}},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
r := NewSkippedResourceConfig()
|
r := NewSkippedResourceConfig()
|
||||||
r.Parse(test.input)
|
if err := r.Parse(test.input); err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
for i, o := range test.out {
|
for i, o := range test.out {
|
||||||
ok := r.GroupDisabled(o)
|
ok := r.GroupDisabled(o)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -107,43 +119,47 @@ func TestSkippedResourceConfigMixedParse(t *testing.T) {
|
||||||
input string
|
input string
|
||||||
out SkippedResourceConfig
|
out SkippedResourceConfig
|
||||||
}{
|
}{
|
||||||
{input: "v1/Node,Pod;networking.k8s.io/v1beta1/Ingress,IngressClass;networking.k8s.io;test.com/v1", out: SkippedResourceConfig{
|
{
|
||||||
Groups: map[string]struct{}{
|
input: "v1/Node,Pod;networking.k8s.io/v1beta1/Ingress,IngressClass;networking.k8s.io;test.com/v1",
|
||||||
"networking.k8s.io": {},
|
out: SkippedResourceConfig{
|
||||||
},
|
Groups: map[string]struct{}{
|
||||||
GroupVersions: map[schema.GroupVersion]struct{}{
|
"networking.k8s.io": {},
|
||||||
{
|
},
|
||||||
Group: "test.com",
|
GroupVersions: map[schema.GroupVersion]struct{}{
|
||||||
Version: "v1",
|
{
|
||||||
}: {},
|
Group: "test.com",
|
||||||
},
|
Version: "v1",
|
||||||
GroupVersionKinds: map[schema.GroupVersionKind]struct{}{
|
}: {},
|
||||||
{
|
},
|
||||||
Group: "",
|
GroupVersionKinds: map[schema.GroupVersionKind]struct{}{
|
||||||
Version: "v1",
|
{
|
||||||
Kind: "Node",
|
Group: "",
|
||||||
}: {},
|
Version: "v1",
|
||||||
{
|
Kind: "Node",
|
||||||
Group: "",
|
}: {},
|
||||||
Version: "v1",
|
{
|
||||||
Kind: "Pod",
|
Group: "",
|
||||||
}: {},
|
Version: "v1",
|
||||||
{
|
Kind: "Pod",
|
||||||
Group: "networking.k8s.io",
|
}: {},
|
||||||
Version: "v1beta1",
|
{
|
||||||
Kind: "Ingress",
|
Group: "networking.k8s.io",
|
||||||
}: {},
|
Version: "v1beta1",
|
||||||
{
|
Kind: "Ingress",
|
||||||
Group: "networking.k8s.io",
|
}: {},
|
||||||
Version: "v1beta1",
|
{
|
||||||
Kind: "IngressClass",
|
Group: "networking.k8s.io",
|
||||||
}: {},
|
Version: "v1beta1",
|
||||||
},
|
Kind: "IngressClass",
|
||||||
}},
|
}: {},
|
||||||
|
},
|
||||||
|
}},
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
r := NewSkippedResourceConfig()
|
r := NewSkippedResourceConfig()
|
||||||
r.Parse(test.input)
|
if err := r.Parse(test.input); err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
for g := range r.Groups {
|
for g := range r.Groups {
|
||||||
ok := r.GroupDisabled(g)
|
ok := r.GroupDisabled(g)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -172,13 +188,17 @@ func TestDefaultSkippedResourceConfigGroupParse(t *testing.T) {
|
||||||
input string
|
input string
|
||||||
out []string
|
out []string
|
||||||
}{
|
}{
|
||||||
{input: "", out: []string{
|
{
|
||||||
"cluster.karmada.io", "policy.karmada.io", "work.karmada.io",
|
input: "",
|
||||||
}},
|
out: []string{
|
||||||
|
"cluster.karmada.io", "policy.karmada.io", "work.karmada.io",
|
||||||
|
}},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
r := NewSkippedResourceConfig()
|
r := NewSkippedResourceConfig()
|
||||||
r.Parse(test.input)
|
if err := r.Parse(test.input); err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
for i, o := range test.out {
|
for i, o := range test.out {
|
||||||
ok := r.GroupDisabled(o)
|
ok := r.GroupDisabled(o)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
Loading…
Reference in New Issue