200 lines
6.0 KiB
Go
200 lines
6.0 KiB
Go
/*
|
|
Copyright 2021 The Karmada Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package util
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
coordinationv1 "k8s.io/api/coordination/v1"
|
|
eventsv1 "k8s.io/api/events/v1"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
|
|
appsv1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1"
|
|
autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1"
|
|
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
|
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
|
networkingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/networking/v1alpha1"
|
|
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
|
remedyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1"
|
|
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
|
|
)
|
|
|
|
// SkippedResourceConfig represents the configuration that identifies the API resources should be skipped from propagating.
|
|
type SkippedResourceConfig struct {
|
|
// Groups holds a collection of API group, all resources under this group will be skipped.
|
|
Groups map[string]struct{}
|
|
// GroupVersions holds a collection of API GroupVersion, all resource under this GroupVersion will be skipped.
|
|
GroupVersions map[schema.GroupVersion]struct{}
|
|
// GroupVersionKinds holds a collection of resource that should be skipped.
|
|
GroupVersionKinds map[schema.GroupVersionKind]struct{}
|
|
}
|
|
|
|
var corev1EventGVK = schema.GroupVersionKind{
|
|
Group: "",
|
|
Version: "v1",
|
|
Kind: "Event",
|
|
}
|
|
|
|
// NewSkippedResourceConfig to create SkippedResourceConfig
|
|
func NewSkippedResourceConfig() *SkippedResourceConfig {
|
|
r := &SkippedResourceConfig{
|
|
Groups: map[string]struct{}{},
|
|
GroupVersions: map[schema.GroupVersion]struct{}{},
|
|
GroupVersionKinds: map[schema.GroupVersionKind]struct{}{},
|
|
}
|
|
// disable karmada group by default
|
|
r.DisableGroup(clusterv1alpha1.GroupVersion.Group)
|
|
r.DisableGroup(policyv1alpha1.GroupVersion.Group)
|
|
r.DisableGroup(workv1alpha1.GroupVersion.Group)
|
|
r.DisableGroup(configv1alpha1.GroupVersion.Group)
|
|
r.DisableGroup(networkingv1alpha1.GroupVersion.Group)
|
|
r.DisableGroup(autoscalingv1alpha1.GroupVersion.Group)
|
|
r.DisableGroup(remedyv1alpha1.GroupVersion.Group)
|
|
r.DisableGroup(appsv1alpha1.GroupVersion.Group)
|
|
// disable event by default
|
|
r.DisableGroup(eventsv1.GroupName)
|
|
r.DisableGroupVersionKind(corev1EventGVK)
|
|
|
|
// disable Lease by default
|
|
r.DisableGroupVersion(coordinationv1.SchemeGroupVersion)
|
|
return r
|
|
}
|
|
|
|
// Parse parses the --skipped-propagating-apis input.
|
|
func (r *SkippedResourceConfig) Parse(c string) error {
|
|
// default(empty) input
|
|
if c == "" {
|
|
return nil
|
|
}
|
|
|
|
tokens := strings.Split(c, ";")
|
|
for _, token := range tokens {
|
|
if err := r.parseSingle(token); err != nil {
|
|
return fmt.Errorf("parse --skipped-propagating-apis %w", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *SkippedResourceConfig) parseSingle(token string) error {
|
|
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:
|
|
r.Groups[token] = struct{}{}
|
|
// it should be the case "<group>/<version>"
|
|
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") {
|
|
var kinds []string
|
|
for _, k := range strings.Split(token, ",") {
|
|
if strings.Contains(k, "/") { // "v1/<kind>"
|
|
s := strings.Split(k, "/")
|
|
kinds = append(kinds, s[1])
|
|
} else {
|
|
kinds = append(kinds, k)
|
|
}
|
|
}
|
|
for _, k := range kinds {
|
|
gvk := schema.GroupVersionKind{
|
|
Version: "v1",
|
|
Kind: k,
|
|
}
|
|
r.GroupVersionKinds[gvk] = struct{}{}
|
|
}
|
|
} else { // case "<group>/<version>"
|
|
parts := strings.Split(token, "/")
|
|
if len(parts) != 2 {
|
|
return fmt.Errorf("invalid token: %s", token)
|
|
}
|
|
gv := schema.GroupVersion{
|
|
Group: parts[0],
|
|
Version: parts[1],
|
|
}
|
|
r.GroupVersions[gv] = struct{}{}
|
|
}
|
|
// parameter format: "<group>/<version>/<kind>" or "<group>/<version>/<kind>,<kind>..."
|
|
case 2:
|
|
g := ""
|
|
v := ""
|
|
var kinds []string
|
|
for _, k := range strings.Split(token, ",") {
|
|
if strings.Contains(k, "/") {
|
|
s := strings.Split(k, "/")
|
|
g = s[0]
|
|
v = s[1]
|
|
kinds = append(kinds, s[2])
|
|
} else {
|
|
kinds = append(kinds, k)
|
|
}
|
|
}
|
|
for _, k := range kinds {
|
|
gvk := schema.GroupVersionKind{
|
|
Group: g,
|
|
Version: v,
|
|
Kind: k,
|
|
}
|
|
r.GroupVersionKinds[gvk] = struct{}{}
|
|
}
|
|
default:
|
|
return fmt.Errorf("invalid parameter: %s", token)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GroupVersionDisabled returns whether GroupVersion is disabled.
|
|
func (r *SkippedResourceConfig) GroupVersionDisabled(gv schema.GroupVersion) bool {
|
|
if _, ok := r.GroupVersions[gv]; ok {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GroupVersionKindDisabled returns whether GroupVersionKind is disabled.
|
|
func (r *SkippedResourceConfig) GroupVersionKindDisabled(gvk schema.GroupVersionKind) bool {
|
|
if _, ok := r.GroupVersionKinds[gvk]; ok {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GroupDisabled returns whether Group is disabled.
|
|
func (r *SkippedResourceConfig) GroupDisabled(g string) bool {
|
|
if _, ok := r.Groups[g]; ok {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// DisableGroup to disable group.
|
|
func (r *SkippedResourceConfig) DisableGroup(g string) {
|
|
r.Groups[g] = struct{}{}
|
|
}
|
|
|
|
// DisableGroupVersion to disable GroupVersion.
|
|
func (r *SkippedResourceConfig) DisableGroupVersion(gv schema.GroupVersion) {
|
|
r.GroupVersions[gv] = struct{}{}
|
|
}
|
|
|
|
// DisableGroupVersionKind to disable GroupVersionKind.
|
|
func (r *SkippedResourceConfig) DisableGroupVersionKind(gvk schema.GroupVersionKind) {
|
|
r.GroupVersionKinds[gvk] = struct{}{}
|
|
}
|