Update resourece interpreter pkg/file name and variable/parameter/comment naming
Signed-off-by: changzhen <changzhen5@huawei.com>
This commit is contained in:
parent
f8af0363f6
commit
7224234a74
|
|
@ -116,10 +116,10 @@ webhooks:
|
|||
- operations: ["CREATE", "UPDATE"]
|
||||
apiGroups: ["config.karmada.io"]
|
||||
apiVersions: ["*"]
|
||||
resources: ["resourceexploringwebhookconfigurations"]
|
||||
resources: ["resourceinterpreterwebhookconfigurations"]
|
||||
scope: "Cluster"
|
||||
clientConfig:
|
||||
url: https://karmada-webhook.karmada-system.svc:443/validate-resourceexploringwebhookconfiguration
|
||||
url: https://karmada-webhook.karmada-system.svc:443/validate-resourceinterpreterwebhookconfiguration
|
||||
caBundle: {{caBundle}}
|
||||
failurePolicy: Fail
|
||||
sideEffects: None
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ spec:
|
|||
and query parameters (\"?...\") are not allowed, either."
|
||||
type: string
|
||||
type: object
|
||||
exploreReviewVersions:
|
||||
description: ExploreReviewVersions is an ordered list of preferred
|
||||
interpreterContextVersions:
|
||||
description: InterpreterContextVersions is an ordered list of preferred
|
||||
`ResourceInterpreterContext` versions the Webhook expects. Karmada
|
||||
will try to use first version in the list which it supports. If
|
||||
none of the versions specified in this list supported by Karmada,
|
||||
|
|
@ -112,11 +112,6 @@ spec:
|
|||
items:
|
||||
type: string
|
||||
type: array
|
||||
failurePolicy:
|
||||
description: FailurePolicy defines how unrecognized errors from
|
||||
the webhook are handled, allowed values are Ignore or Fail. Defaults
|
||||
to Fail.
|
||||
type: string
|
||||
name:
|
||||
description: Name is the full-qualified name of the webhook.
|
||||
type: string
|
||||
|
|
@ -180,7 +175,7 @@ spec:
|
|||
type: integer
|
||||
required:
|
||||
- clientConfig
|
||||
- exploreReviewVersions
|
||||
- interpreterContextVersions
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ resources:
|
|||
- bases/work.karmada.io_resourcebindings.yaml
|
||||
- bases/work.karmada.io_clusterresourcebindings.yaml
|
||||
- bases/work.karmada.io_works.yaml
|
||||
- bases/config.karmada.io_resourceexploringwebhookconfigurations.yaml
|
||||
- bases/config.karmada.io_resourceinterpreterwebhookconfigurations.yaml
|
||||
|
||||
patchesStrategicMerge:
|
||||
- patches/webhook_in_resourcebindings.yaml
|
||||
|
|
|
|||
|
|
@ -120,10 +120,10 @@ webhooks:
|
|||
- operations: ["CREATE", "UPDATE"]
|
||||
apiGroups: ["config.karmada.io"]
|
||||
apiVersions: ["*"]
|
||||
resources: ["resourceexploringwebhookconfigurations"]
|
||||
resources: ["resourceinterpreterwebhookconfigurations"]
|
||||
scope: "Cluster"
|
||||
clientConfig:
|
||||
url: https://{{ $name }}-webhook.{{ $namespace }}.svc:443/validate-resourceexploringwebhookconfiguration
|
||||
url: https://{{ $name }}-webhook.{{ $namespace }}.svc:443/validate-resourceinterpreterwebhookconfiguration
|
||||
{{- include "karmada.webhook.caBundle" . | nindent 6 }}
|
||||
failurePolicy: Fail
|
||||
sideEffects: None
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ import (
|
|||
"github.com/karmada-io/karmada/pkg/controllers/execution"
|
||||
"github.com/karmada-io/karmada/pkg/controllers/mcs"
|
||||
"github.com/karmada-io/karmada/pkg/controllers/status"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter"
|
||||
"github.com/karmada-io/karmada/pkg/util"
|
||||
"github.com/karmada-io/karmada/pkg/util/gclient"
|
||||
"github.com/karmada-io/karmada/pkg/util/helper"
|
||||
|
|
@ -131,12 +131,12 @@ func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stop
|
|||
restConfig := mgr.GetConfig()
|
||||
dynamicClientSet := dynamic.NewForConfigOrDie(restConfig)
|
||||
controlPlaneInformerManager := informermanager.NewSingleClusterInformerManager(dynamicClientSet, 0, stopChan)
|
||||
crdExplorer := crdexplorer.NewCustomResourceExplorer("", controlPlaneInformerManager)
|
||||
if err := mgr.Add(crdExplorer); err != nil {
|
||||
klog.Fatalf("Failed to setup custom resource explorer: %v", err)
|
||||
resourceInterpreter := resourceinterpreter.NewResourceInterpreter("", controlPlaneInformerManager)
|
||||
if err := mgr.Add(resourceInterpreter); err != nil {
|
||||
klog.Fatalf("Failed to setup custom resource interpreter: %v", err)
|
||||
}
|
||||
|
||||
objectWatcher := objectwatcher.NewObjectWatcher(mgr.GetClient(), mgr.GetRESTMapper(), util.NewClusterDynamicClientSetForAgent, crdExplorer)
|
||||
objectWatcher := objectwatcher.NewObjectWatcher(mgr.GetClient(), mgr.GetRESTMapper(), util.NewClusterDynamicClientSetForAgent, resourceInterpreter)
|
||||
executionController := &execution.Controller{
|
||||
Client: mgr.GetClient(),
|
||||
EventRecorder: mgr.GetEventRecorderFor(execution.ControllerName),
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ import (
|
|||
"github.com/karmada-io/karmada/pkg/controllers/mcs"
|
||||
"github.com/karmada-io/karmada/pkg/controllers/namespace"
|
||||
"github.com/karmada-io/karmada/pkg/controllers/status"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer"
|
||||
"github.com/karmada-io/karmada/pkg/detector"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter"
|
||||
"github.com/karmada-io/karmada/pkg/util"
|
||||
"github.com/karmada-io/karmada/pkg/util/gclient"
|
||||
"github.com/karmada-io/karmada/pkg/util/helper"
|
||||
|
|
@ -124,12 +124,12 @@ func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stop
|
|||
|
||||
controlPlaneInformerManager := informermanager.NewSingleClusterInformerManager(dynamicClientSet, 0, stopChan)
|
||||
|
||||
crdExplorer := crdexplorer.NewCustomResourceExplorer("", controlPlaneInformerManager)
|
||||
if err := mgr.Add(crdExplorer); err != nil {
|
||||
klog.Fatalf("Failed to setup custom resource explorer: %v", err)
|
||||
resourceInterpreter := resourceinterpreter.NewResourceInterpreter("", controlPlaneInformerManager)
|
||||
if err := mgr.Add(resourceInterpreter); err != nil {
|
||||
klog.Fatalf("Failed to setup custom resource interpreter: %v", err)
|
||||
}
|
||||
|
||||
objectWatcher := objectwatcher.NewObjectWatcher(mgr.GetClient(), mgr.GetRESTMapper(), util.NewClusterDynamicClientSet, crdExplorer)
|
||||
objectWatcher := objectwatcher.NewObjectWatcher(mgr.GetClient(), mgr.GetRESTMapper(), util.NewClusterDynamicClientSet, resourceInterpreter)
|
||||
|
||||
resourceDetector := &detector.ResourceDetector{
|
||||
DiscoveryClientSet: discoverClientSet,
|
||||
|
|
@ -139,7 +139,7 @@ func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stop
|
|||
DynamicClient: dynamicClientSet,
|
||||
SkippedResourceConfig: skippedResourceConfig,
|
||||
SkippedPropagatingNamespaces: skippedPropagatingNamespaces,
|
||||
ResourceExplorer: crdExplorer,
|
||||
ResourceInterpreter: resourceInterpreter,
|
||||
}
|
||||
if err := mgr.Add(resourceDetector); err != nil {
|
||||
klog.Fatalf("Failed to setup resource detector: %v", err)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import (
|
|||
"github.com/karmada-io/karmada/pkg/version/sharedcommand"
|
||||
"github.com/karmada-io/karmada/pkg/webhook/cluster"
|
||||
"github.com/karmada-io/karmada/pkg/webhook/clusterpropagationpolicy"
|
||||
"github.com/karmada-io/karmada/pkg/webhook/crdexplorer"
|
||||
"github.com/karmada-io/karmada/pkg/webhook/configuration"
|
||||
"github.com/karmada-io/karmada/pkg/webhook/overridepolicy"
|
||||
"github.com/karmada-io/karmada/pkg/webhook/propagationpolicy"
|
||||
"github.com/karmada-io/karmada/pkg/webhook/work"
|
||||
|
|
@ -79,7 +79,7 @@ func Run(ctx context.Context, opts *options.Options) error {
|
|||
hookServer.Register("/mutate-overridepolicy", &webhook.Admission{Handler: &overridepolicy.MutatingAdmission{}})
|
||||
hookServer.Register("/mutate-work", &webhook.Admission{Handler: &work.MutatingAdmission{}})
|
||||
hookServer.Register("/convert", &conversion.Webhook{})
|
||||
hookServer.Register("/validate-resourceexploringwebhookconfiguration", &webhook.Admission{Handler: &crdexplorer.ValidatingAdmission{}})
|
||||
hookServer.Register("/validate-resourceinterpreterwebhookconfiguration", &webhook.Admission{Handler: &configuration.ValidatingAdmission{}})
|
||||
hookServer.WebhookMux.Handle("/readyz/", http.StripPrefix("/readyz/", &healthz.Handler{}))
|
||||
|
||||
// blocks until the context is done.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Examples
|
||||
|
||||
### Custom Resource Explorer
|
||||
This example implements a new CustomResourceDefinition(CRD), `Workload`, and creates a custom resource explorer webhook.
|
||||
### Resource Interpreter
|
||||
This example implements a new CustomResourceDefinition(CRD), `Workload`, and creates a resource interpreter webhook.
|
||||
|
|
@ -40,8 +40,8 @@ deepcopy-gen \
|
|||
--output-file-base=zz_generated.deepcopy
|
||||
deepcopy-gen \
|
||||
--go-header-file hack/boilerplate/boilerplate.go.txt \
|
||||
--input-dirs=github.com/karmada-io/karmada/examples/customresourceexplorer/apis/workload/v1alpha1 \
|
||||
--output-package=github.com/karmada-io/karmada/examples/customresourceexplorer/apis/workload/v1alpha1 \
|
||||
--input-dirs=github.com/karmada-io/karmada/examples/customresourceinterpreter/apis/workload/v1alpha1 \
|
||||
--output-package=github.com/karmada-io/karmada/examples/customresourceinterpreter/apis/workload/v1alpha1 \
|
||||
--output-file-base=zz_generated.deepcopy
|
||||
|
||||
echo "Generating with register-gen"
|
||||
|
|
@ -73,8 +73,8 @@ register-gen \
|
|||
--output-file-base=zz_generated.register
|
||||
register-gen \
|
||||
--go-header-file hack/boilerplate/boilerplate.go.txt \
|
||||
--input-dirs=github.com/karmada-io/karmada/examples/customresourceexplorer/apis/workload/v1alpha1 \
|
||||
--output-package=github.com/karmada-io/karmada/examples/customresourceexplorer/apis/workload/v1alpha1 \
|
||||
--input-dirs=github.com/karmada-io/karmada/examples/customresourceinterpreter/apis/workload/v1alpha1 \
|
||||
--output-package=github.com/karmada-io/karmada/examples/customresourceinterpreter/apis/workload/v1alpha1 \
|
||||
--output-file-base=zz_generated.register
|
||||
|
||||
echo "Generating with client-gen"
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ util::install_tools ${CONTROLLER_GEN_PKG} ${CONTROLLER_GEN_VER} >/dev/null 2>&1
|
|||
|
||||
# Unify the crds used by helm chart and the installation scripts
|
||||
controller-gen crd paths=./pkg/apis/... output:crd:dir=./charts/_crds/bases
|
||||
controller-gen crd paths=./examples/customresourceexplorer/apis/... output:crd:dir=./examples/customresourceexplorer/apis/
|
||||
controller-gen crd paths=./examples/customresourceinterpreter/apis/... output:crd:dir=./examples/customresourceinterpreter/apis/
|
||||
|
|
|
|||
|
|
@ -11,20 +11,20 @@ import (
|
|||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ResourceInterpreterContext describes an explore review request and response.
|
||||
// ResourceInterpreterContext describes an interpreter context request and response.
|
||||
type ResourceInterpreterContext struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// Request describes the attributes for the explore request.
|
||||
// Request describes the attributes for the interpreter request.
|
||||
// +optional
|
||||
Request *ResourceInterpreterRequest `json:"request,omitempty"`
|
||||
|
||||
// Response describes the attributes for the explore response.
|
||||
// Response describes the attributes for the interpreter response.
|
||||
// +optional
|
||||
Response *ResourceInterpreterResponse `json:"response,omitempty"`
|
||||
}
|
||||
|
||||
// ResourceInterpreterRequest describes the explore.Attributes for the explore request.
|
||||
// ResourceInterpreterRequest describes the interpreter.Attributes for the interpreter request.
|
||||
type ResourceInterpreterRequest struct {
|
||||
// UID is an identifier for the individual request/response.
|
||||
// The UID is meant to track the round trip (request/response) between the karmada and the WebHook, not the user request.
|
||||
|
|
@ -53,7 +53,7 @@ type ResourceInterpreterRequest struct {
|
|||
Object runtime.RawExtension `json:"object,omitempty"`
|
||||
|
||||
// ObservedObject is the object observed from the kube-apiserver of member clusters.
|
||||
// Not nil only when InterpreterOperation is InterpreterOperationRetention.
|
||||
// Not nil only when InterpreterOperation is InterpreterOperationRetain.
|
||||
// +optional
|
||||
ObservedObject *runtime.RawExtension `json:"observedObject,omitempty"`
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ type ResourceInterpreterRequest struct {
|
|||
AggregatedStatus []workv1alpha1.AggregatedStatusItem `json:"aggregatedStatus,omitempty"`
|
||||
}
|
||||
|
||||
// ResourceInterpreterResponse describes an explore response.
|
||||
// ResourceInterpreterResponse describes an interpreter response.
|
||||
type ResourceInterpreterResponse struct {
|
||||
// UID is an identifier for the individual request/response.
|
||||
// This must be copied over from the corresponding ResourceInterpreterRequest.
|
||||
|
|
|
|||
|
|
@ -37,11 +37,6 @@ type ResourceInterpreterWebhook struct {
|
|||
// +optional
|
||||
Rules []RuleWithOperations `json:"rules,omitempty"`
|
||||
|
||||
// FailurePolicy defines how unrecognized errors from the webhook are handled,
|
||||
// allowed values are Ignore or Fail. Defaults to Fail.
|
||||
// +optional
|
||||
FailurePolicy *admissionregistrationv1.FailurePolicyType `json:"failurePolicy,omitempty"`
|
||||
|
||||
// TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
|
||||
// the webhook call will be ignored or the API call will fail based on the
|
||||
// failure policy.
|
||||
|
|
@ -50,14 +45,14 @@ type ResourceInterpreterWebhook struct {
|
|||
// +optional
|
||||
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"`
|
||||
|
||||
// ExploreReviewVersions is an ordered list of preferred `ResourceInterpreterContext`
|
||||
// InterpreterContextVersions is an ordered list of preferred `ResourceInterpreterContext`
|
||||
// versions the Webhook expects. Karmada will try to use first version in
|
||||
// the list which it supports. If none of the versions specified in this list
|
||||
// supported by Karmada, validation will fail for this object.
|
||||
// If a persisted webhook configuration specifies allowed versions and does not
|
||||
// include any versions known to the Karmada, calls to the webhook will fail
|
||||
// and be subject to the failure policy.
|
||||
ExploreReviewVersions []string `json:"exploreReviewVersions"`
|
||||
InterpreterContextVersions []string `json:"interpreterContextVersions"`
|
||||
}
|
||||
|
||||
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
|
||||
|
|
@ -94,9 +89,9 @@ const (
|
|||
// InterpreterOperationPrune indicates that karmada want to figure out how to package resource template to Work.
|
||||
InterpreterOperationPrune InterpreterOperation = "Prune"
|
||||
|
||||
// InterpreterOperationRetention indicates that karmada request webhook to retain the desired resource template.
|
||||
// InterpreterOperationRetain indicates that karmada request webhook to retain the desired resource template.
|
||||
// Only necessary for those resources which specification will be updated by their controllers running in member cluster.
|
||||
InterpreterOperationRetention InterpreterOperation = "Retention"
|
||||
InterpreterOperationRetain InterpreterOperation = "Retain"
|
||||
|
||||
// InterpreterOperationAggregateStatus indicates that karmada want to figure out how to aggregate status to resource template.
|
||||
// Only necessary for those resource types that want to aggregate status to resource template.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ package v1alpha1
|
|||
import (
|
||||
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
|
||||
v1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -180,18 +179,13 @@ func (in *ResourceInterpreterWebhook) DeepCopyInto(out *ResourceInterpreterWebho
|
|||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.FailurePolicy != nil {
|
||||
in, out := &in.FailurePolicy, &out.FailurePolicy
|
||||
*out = new(v1.FailurePolicyType)
|
||||
**out = **in
|
||||
}
|
||||
if in.TimeoutSeconds != nil {
|
||||
in, out := &in.TimeoutSeconds, &out.TimeoutSeconds
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.ExploreReviewVersions != nil {
|
||||
in, out := &in.ExploreReviewVersions, &out.ExploreReviewVersions
|
||||
if in.InterpreterContextVersions != nil {
|
||||
in, out := &in.InterpreterContextVersions, &out.InterpreterContextVersions
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
package defaultexplorer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
)
|
||||
|
||||
// DefaultExplorer contains all default operation explorer factory
|
||||
// for exploring common resource.
|
||||
type DefaultExplorer struct {
|
||||
replicaHandlers map[schema.GroupVersionKind]replicaExplorer
|
||||
retentionHandlers map[schema.GroupVersionKind]retentionExplorer
|
||||
}
|
||||
|
||||
// NewDefaultExplorer return a new DefaultExplorer.
|
||||
func NewDefaultExplorer() *DefaultExplorer {
|
||||
return &DefaultExplorer{
|
||||
replicaHandlers: getAllDefaultReplicaExplorer(),
|
||||
retentionHandlers: getAllDefaultRetentionExplorer(),
|
||||
}
|
||||
}
|
||||
|
||||
// HookEnabled tells if any hook exist for specific resource type and operation type.
|
||||
func (e *DefaultExplorer) HookEnabled(kind schema.GroupVersionKind, operationType configv1alpha1.InterpreterOperation) bool {
|
||||
switch operationType {
|
||||
case configv1alpha1.InterpreterOperationInterpretReplica:
|
||||
if _, exist := e.replicaHandlers[kind]; exist {
|
||||
return true
|
||||
}
|
||||
case configv1alpha1.InterpreterOperationRetention:
|
||||
if _, exist := e.retentionHandlers[kind]; exist {
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO(RainbowMango): more cases should be added here
|
||||
}
|
||||
|
||||
klog.V(4).Infof("Default explorer is not enabled for kind %q with operation %q.", kind, operationType)
|
||||
return false
|
||||
}
|
||||
|
||||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
|
||||
func (e *DefaultExplorer) GetReplicas(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error) {
|
||||
handler, exist := e.replicaHandlers[object.GroupVersionKind()]
|
||||
if !exist {
|
||||
return 0, &workv1alpha2.ReplicaRequirements{}, fmt.Errorf("defalut explorer for operation %s not found", configv1alpha1.InterpreterOperationInterpretReplica)
|
||||
}
|
||||
return handler(object)
|
||||
}
|
||||
|
||||
// Retain returns the objects that based on the "desired" object but with values retained from the "observed" object.
|
||||
func (e *DefaultExplorer) Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error) {
|
||||
handler, exist := e.retentionHandlers[desired.GroupVersionKind()]
|
||||
if !exist {
|
||||
return nil, fmt.Errorf("default retain explorer for %q not found", desired.GroupVersionKind())
|
||||
}
|
||||
|
||||
return handler(desired, observed)
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ import (
|
|||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter"
|
||||
"github.com/karmada-io/karmada/pkg/util"
|
||||
"github.com/karmada-io/karmada/pkg/util/helper"
|
||||
"github.com/karmada-io/karmada/pkg/util/informermanager"
|
||||
|
|
@ -50,8 +50,8 @@ type ResourceDetector struct {
|
|||
Processor util.AsyncWorker
|
||||
SkippedResourceConfig *util.SkippedResourceConfig
|
||||
SkippedPropagatingNamespaces map[string]struct{}
|
||||
// ResourceExplorer knows the details of resource structure.
|
||||
ResourceExplorer crdexplorer.CustomResourceExplorer
|
||||
// ResourceInterpreter knows the details of resource structure.
|
||||
ResourceInterpreter resourceinterpreter.ResourceInterpreter
|
||||
|
||||
// policyReconcileWorker maintains a rate limited queue which used to store PropagationPolicy's key and
|
||||
// a reconcile function to consume the items in queue.
|
||||
|
|
@ -642,8 +642,8 @@ func (d *ResourceDetector) BuildResourceBinding(object *unstructured.Unstructure
|
|||
},
|
||||
}
|
||||
|
||||
if d.ResourceExplorer.HookEnabled(object, configv1alpha1.InterpreterOperationInterpretReplica) {
|
||||
replicas, replicaRequirements, err := d.ResourceExplorer.GetReplicas(object)
|
||||
if d.ResourceInterpreter.HookEnabled(object, configv1alpha1.InterpreterOperationInterpretReplica) {
|
||||
replicas, replicaRequirements, err := d.ResourceInterpreter.GetReplicas(object)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to customize replicas for %s(%s), %v", object.GroupVersionKind(), object.GetName(), err)
|
||||
return nil, err
|
||||
|
|
@ -677,8 +677,8 @@ func (d *ResourceDetector) BuildClusterResourceBinding(object *unstructured.Unst
|
|||
},
|
||||
}
|
||||
|
||||
if d.ResourceExplorer.HookEnabled(object, configv1alpha1.InterpreterOperationInterpretReplica) {
|
||||
replicas, replicaRequirements, err := d.ResourceExplorer.GetReplicas(object)
|
||||
if d.ResourceInterpreter.HookEnabled(object, configv1alpha1.InterpreterOperationInterpretReplica) {
|
||||
replicas, replicaRequirements, err := d.ResourceInterpreter.GetReplicas(object)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to customize replicas for %s(%s), %v", object.GroupVersionKind(), object.GetName(), err)
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -1,106 +0,0 @@
|
|||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeResourceExploringWebhookConfigurations implements ResourceExploringWebhookConfigurationInterface
|
||||
type FakeResourceExploringWebhookConfigurations struct {
|
||||
Fake *FakeConfigV1alpha1
|
||||
}
|
||||
|
||||
var resourceexploringwebhookconfigurationsResource = schema.GroupVersionResource{Group: "config.karmada.io", Version: "v1alpha1", Resource: "resourceexploringwebhookconfigurations"}
|
||||
|
||||
var resourceexploringwebhookconfigurationsKind = schema.GroupVersionKind{Group: "config.karmada.io", Version: "v1alpha1", Kind: "ResourceInterpreterWebhookConfiguration"}
|
||||
|
||||
// Get takes name of the resourceExploringWebhookConfiguration, and returns the corresponding resourceExploringWebhookConfiguration object, and an error if there is any.
|
||||
func (c *FakeResourceExploringWebhookConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(resourceexploringwebhookconfigurationsResource, name), &v1alpha1.ResourceInterpreterWebhookConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ResourceInterpreterWebhookConfiguration), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ResourceExploringWebhookConfigurations that match those selectors.
|
||||
func (c *FakeResourceExploringWebhookConfigurations) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceInterpreterWebhookConfigurationList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(resourceexploringwebhookconfigurationsResource, resourceexploringwebhookconfigurationsKind, opts), &v1alpha1.ResourceInterpreterWebhookConfigurationList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.ResourceInterpreterWebhookConfigurationList{ListMeta: obj.(*v1alpha1.ResourceInterpreterWebhookConfigurationList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.ResourceInterpreterWebhookConfigurationList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested resourceExploringWebhookConfigurations.
|
||||
func (c *FakeResourceExploringWebhookConfigurations) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(resourceexploringwebhookconfigurationsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a resourceExploringWebhookConfiguration and creates it. Returns the server's representation of the resourceExploringWebhookConfiguration, and an error, if there is any.
|
||||
func (c *FakeResourceExploringWebhookConfigurations) Create(ctx context.Context, resourceExploringWebhookConfiguration *v1alpha1.ResourceInterpreterWebhookConfiguration, opts v1.CreateOptions) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(resourceexploringwebhookconfigurationsResource, resourceExploringWebhookConfiguration), &v1alpha1.ResourceInterpreterWebhookConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ResourceInterpreterWebhookConfiguration), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a resourceExploringWebhookConfiguration and updates it. Returns the server's representation of the resourceExploringWebhookConfiguration, and an error, if there is any.
|
||||
func (c *FakeResourceExploringWebhookConfigurations) Update(ctx context.Context, resourceExploringWebhookConfiguration *v1alpha1.ResourceInterpreterWebhookConfiguration, opts v1.UpdateOptions) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(resourceexploringwebhookconfigurationsResource, resourceExploringWebhookConfiguration), &v1alpha1.ResourceInterpreterWebhookConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ResourceInterpreterWebhookConfiguration), err
|
||||
}
|
||||
|
||||
// Delete takes name of the resourceExploringWebhookConfiguration and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeResourceExploringWebhookConfigurations) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(resourceexploringwebhookconfigurationsResource, name), &v1alpha1.ResourceInterpreterWebhookConfiguration{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeResourceExploringWebhookConfigurations) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(resourceexploringwebhookconfigurationsResource, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.ResourceInterpreterWebhookConfigurationList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched resourceExploringWebhookConfiguration.
|
||||
func (c *FakeResourceExploringWebhookConfigurations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(resourceexploringwebhookconfigurationsResource, name, pt, data, subresources...), &v1alpha1.ResourceInterpreterWebhookConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.ResourceInterpreterWebhookConfiguration), err
|
||||
}
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
scheme "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// ResourceExploringWebhookConfigurationsGetter has a method to return a ResourceExploringWebhookConfigurationInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ResourceExploringWebhookConfigurationsGetter interface {
|
||||
ResourceExploringWebhookConfigurations() ResourceExploringWebhookConfigurationInterface
|
||||
}
|
||||
|
||||
// ResourceExploringWebhookConfigurationInterface has methods to work with ResourceInterpreterWebhookConfiguration resources.
|
||||
type ResourceExploringWebhookConfigurationInterface interface {
|
||||
Create(ctx context.Context, resourceExploringWebhookConfiguration *v1alpha1.ResourceInterpreterWebhookConfiguration, opts v1.CreateOptions) (*v1alpha1.ResourceInterpreterWebhookConfiguration, error)
|
||||
Update(ctx context.Context, resourceExploringWebhookConfiguration *v1alpha1.ResourceInterpreterWebhookConfiguration, opts v1.UpdateOptions) (*v1alpha1.ResourceInterpreterWebhookConfiguration, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ResourceInterpreterWebhookConfiguration, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ResourceInterpreterWebhookConfigurationList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error)
|
||||
ResourceExploringWebhookConfigurationExpansion
|
||||
}
|
||||
|
||||
// resourceExploringWebhookConfigurations implements ResourceExploringWebhookConfigurationInterface
|
||||
type resourceExploringWebhookConfigurations struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newResourceExploringWebhookConfigurations returns a ResourceExploringWebhookConfigurations
|
||||
func newResourceExploringWebhookConfigurations(c *ConfigV1alpha1Client) *resourceExploringWebhookConfigurations {
|
||||
return &resourceExploringWebhookConfigurations{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the resourceExploringWebhookConfiguration, and returns the corresponding resourceExploringWebhookConfiguration object, and an error if there is any.
|
||||
func (c *resourceExploringWebhookConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
result = &v1alpha1.ResourceInterpreterWebhookConfiguration{}
|
||||
err = c.client.Get().
|
||||
Resource("resourceexploringwebhookconfigurations").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ResourceExploringWebhookConfigurations that match those selectors.
|
||||
func (c *resourceExploringWebhookConfigurations) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceInterpreterWebhookConfigurationList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.ResourceInterpreterWebhookConfigurationList{}
|
||||
err = c.client.Get().
|
||||
Resource("resourceexploringwebhookconfigurations").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested resourceExploringWebhookConfigurations.
|
||||
func (c *resourceExploringWebhookConfigurations) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("resourceexploringwebhookconfigurations").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a resourceExploringWebhookConfiguration and creates it. Returns the server's representation of the resourceExploringWebhookConfiguration, and an error, if there is any.
|
||||
func (c *resourceExploringWebhookConfigurations) Create(ctx context.Context, resourceExploringWebhookConfiguration *v1alpha1.ResourceInterpreterWebhookConfiguration, opts v1.CreateOptions) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
result = &v1alpha1.ResourceInterpreterWebhookConfiguration{}
|
||||
err = c.client.Post().
|
||||
Resource("resourceexploringwebhookconfigurations").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(resourceExploringWebhookConfiguration).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a resourceExploringWebhookConfiguration and updates it. Returns the server's representation of the resourceExploringWebhookConfiguration, and an error, if there is any.
|
||||
func (c *resourceExploringWebhookConfigurations) Update(ctx context.Context, resourceExploringWebhookConfiguration *v1alpha1.ResourceInterpreterWebhookConfiguration, opts v1.UpdateOptions) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
result = &v1alpha1.ResourceInterpreterWebhookConfiguration{}
|
||||
err = c.client.Put().
|
||||
Resource("resourceexploringwebhookconfigurations").
|
||||
Name(resourceExploringWebhookConfiguration.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(resourceExploringWebhookConfiguration).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the resourceExploringWebhookConfiguration and deletes it. Returns an error if one occurs.
|
||||
func (c *resourceExploringWebhookConfigurations) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("resourceexploringwebhookconfigurations").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *resourceExploringWebhookConfigurations) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("resourceexploringwebhookconfigurations").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched resourceExploringWebhookConfiguration.
|
||||
func (c *resourceExploringWebhookConfigurations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
result = &v1alpha1.ResourceInterpreterWebhookConfiguration{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("resourceexploringwebhookconfigurations").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
versioned "github.com/karmada-io/karmada/pkg/generated/clientset/versioned"
|
||||
internalinterfaces "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/internalinterfaces"
|
||||
v1alpha1 "github.com/karmada-io/karmada/pkg/generated/listers/config/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ResourceExploringWebhookConfigurationInformer provides access to a shared informer and lister for
|
||||
// ResourceExploringWebhookConfigurations.
|
||||
type ResourceExploringWebhookConfigurationInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.ResourceExploringWebhookConfigurationLister
|
||||
}
|
||||
|
||||
type resourceExploringWebhookConfigurationInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewResourceExploringWebhookConfigurationInformer constructs a new informer for ResourceInterpreterWebhookConfiguration type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewResourceExploringWebhookConfigurationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredResourceExploringWebhookConfigurationInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredResourceExploringWebhookConfigurationInformer constructs a new informer for ResourceInterpreterWebhookConfiguration type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredResourceExploringWebhookConfigurationInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.ConfigV1alpha1().ResourceExploringWebhookConfigurations().List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.ConfigV1alpha1().ResourceExploringWebhookConfigurations().Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&configv1alpha1.ResourceInterpreterWebhookConfiguration{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *resourceExploringWebhookConfigurationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredResourceExploringWebhookConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *resourceExploringWebhookConfigurationInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&configv1alpha1.ResourceInterpreterWebhookConfiguration{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *resourceExploringWebhookConfigurationInformer) Lister() v1alpha1.ResourceExploringWebhookConfigurationLister {
|
||||
return v1alpha1.NewResourceExploringWebhookConfigurationLister(f.Informer().GetIndexer())
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ResourceExploringWebhookConfigurationLister helps list ResourceExploringWebhookConfigurations.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type ResourceExploringWebhookConfigurationLister interface {
|
||||
// List lists all ResourceExploringWebhookConfigurations in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.ResourceInterpreterWebhookConfiguration, err error)
|
||||
// Get retrieves the ResourceInterpreterWebhookConfiguration from the index for a given name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v1alpha1.ResourceInterpreterWebhookConfiguration, error)
|
||||
ResourceExploringWebhookConfigurationListerExpansion
|
||||
}
|
||||
|
||||
// resourceExploringWebhookConfigurationLister implements the ResourceExploringWebhookConfigurationLister interface.
|
||||
type resourceExploringWebhookConfigurationLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewResourceExploringWebhookConfigurationLister returns a new ResourceExploringWebhookConfigurationLister.
|
||||
func NewResourceExploringWebhookConfigurationLister(indexer cache.Indexer) ResourceExploringWebhookConfigurationLister {
|
||||
return &resourceExploringWebhookConfigurationLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all ResourceExploringWebhookConfigurations in the indexer.
|
||||
func (s *resourceExploringWebhookConfigurationLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceInterpreterWebhookConfiguration, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.ResourceInterpreterWebhookConfiguration))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the ResourceInterpreterWebhookConfiguration from the index for a given name.
|
||||
func (s *resourceExploringWebhookConfigurationLister) Get(name string) (*v1alpha1.ResourceInterpreterWebhookConfiguration, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("resourceexploringwebhookconfiguration"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.ResourceInterpreterWebhookConfiguration), nil
|
||||
}
|
||||
|
|
@ -22,12 +22,10 @@ type WebhookAccessor interface {
|
|||
GetClientConfig() admissionregistrationv1.WebhookClientConfig
|
||||
// GetRules gets the webhook Rules field.
|
||||
GetRules() []configv1alpha1.RuleWithOperations
|
||||
// GetFailurePolicy gets the webhook FailurePolicy field.
|
||||
GetFailurePolicy() *admissionregistrationv1.FailurePolicyType
|
||||
// GetTimeoutSeconds gets the webhook TimeoutSeconds field.
|
||||
GetTimeoutSeconds() *int32
|
||||
// GetExploreReviewVersions gets the webhook ExploreReviewVersions field.
|
||||
GetExploreReviewVersions() []string
|
||||
// GetInterpreterContextVersions gets the webhook InterpreterContextVersions field.
|
||||
GetInterpreterContextVersions() []string
|
||||
|
||||
// GetRESTClient gets the webhook client.
|
||||
GetRESTClient(clientManager *webhookutil.ClientManager) (*rest.RESTClient, error)
|
||||
|
|
@ -73,19 +71,14 @@ func (a *resourceExploringAccessor) GetRules() []configv1alpha1.RuleWithOperatio
|
|||
return a.Rules
|
||||
}
|
||||
|
||||
// GetFailurePolicy gets the webhook FailurePolicy field.
|
||||
func (a *resourceExploringAccessor) GetFailurePolicy() *admissionregistrationv1.FailurePolicyType {
|
||||
return a.FailurePolicy
|
||||
}
|
||||
|
||||
// GetTimeoutSeconds gets the webhook TimeoutSeconds field.
|
||||
func (a *resourceExploringAccessor) GetTimeoutSeconds() *int32 {
|
||||
return a.TimeoutSeconds
|
||||
}
|
||||
|
||||
// GetExploreReviewVersions gets the webhook ExploreReviewVersions field.
|
||||
func (a *resourceExploringAccessor) GetExploreReviewVersions() []string {
|
||||
return a.ExploreReviewVersions
|
||||
// GetExploreReviewVersions gets the webhook InterpreterContextVersions field.
|
||||
func (a *resourceExploringAccessor) GetInterpreterContextVersions() []string {
|
||||
return a.InterpreterContextVersions
|
||||
}
|
||||
|
||||
// GetRESTClient gets the webhook client.
|
||||
|
|
@ -21,7 +21,7 @@ import (
|
|||
var resourceExploringWebhookConfigurationsGVR = schema.GroupVersionResource{
|
||||
Group: configv1alpha1.GroupVersion.Group,
|
||||
Version: configv1alpha1.GroupVersion.Version,
|
||||
Resource: "resourceexploringwebhookconfigurations",
|
||||
Resource: "resourceinterpreterwebhookconfigurations",
|
||||
}
|
||||
|
||||
// ConfigManager can list dynamic webhooks.
|
||||
|
|
@ -30,20 +30,20 @@ type ConfigManager interface {
|
|||
HasSynced() bool
|
||||
}
|
||||
|
||||
// exploreConfigManager collect the resource explore webhook configuration.
|
||||
type exploreConfigManager struct {
|
||||
// interpreterConfigManager collect the resource interpreter webhook configuration.
|
||||
type interpreterConfigManager struct {
|
||||
configuration *atomic.Value
|
||||
lister cache.GenericLister
|
||||
initialSynced *atomic.Value
|
||||
}
|
||||
|
||||
// HookAccessors return all configured resource explore webhook.
|
||||
func (m *exploreConfigManager) HookAccessors() []WebhookAccessor {
|
||||
// HookAccessors return all configured resource interpreter webhook.
|
||||
func (m *interpreterConfigManager) HookAccessors() []WebhookAccessor {
|
||||
return m.configuration.Load().([]WebhookAccessor)
|
||||
}
|
||||
|
||||
// HasSynced return true when the manager is synced with existing configuration.
|
||||
func (m *exploreConfigManager) HasSynced() bool {
|
||||
func (m *interpreterConfigManager) HasSynced() bool {
|
||||
if m.initialSynced.Load().(bool) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -60,9 +60,9 @@ func (m *exploreConfigManager) HasSynced() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// NewExploreConfigManager return a new exploreConfigManager with resourceexploringwebhookconfigurations handlers.
|
||||
// NewExploreConfigManager return a new interpreterConfigManager with resourceinterpreterwebhookconfigurations handlers.
|
||||
func NewExploreConfigManager(inform informermanager.SingleClusterInformerManager) ConfigManager {
|
||||
manager := &exploreConfigManager{
|
||||
manager := &interpreterConfigManager{
|
||||
configuration: &atomic.Value{},
|
||||
lister: inform.Lister(resourceExploringWebhookConfigurationsGVR),
|
||||
initialSynced: &atomic.Value{},
|
||||
|
|
@ -80,7 +80,7 @@ func NewExploreConfigManager(inform informermanager.SingleClusterInformerManager
|
|||
return manager
|
||||
}
|
||||
|
||||
func (m *exploreConfigManager) updateConfiguration() {
|
||||
func (m *interpreterConfigManager) updateConfiguration() {
|
||||
configurations, err := m.lister.List(labels.Everything())
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("error updating configuration: %v", err))
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package customizedexplorer
|
||||
package customizedinterpreter
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -15,20 +15,20 @@ import (
|
|||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer/customizedexplorer/configmanager"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer/customizedexplorer/webhook"
|
||||
crdexplorerutil "github.com/karmada-io/karmada/pkg/util/crdexplorer"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter/customizedinterpreter/configmanager"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter/customizedinterpreter/webhook"
|
||||
"github.com/karmada-io/karmada/pkg/util/informermanager"
|
||||
interpreterutil "github.com/karmada-io/karmada/pkg/util/interpreter"
|
||||
)
|
||||
|
||||
// CustomizedExplorer explore custom resource with webhook configuration.
|
||||
type CustomizedExplorer struct {
|
||||
// CustomizedInterpreter interpret custom resource with webhook configuration.
|
||||
type CustomizedInterpreter struct {
|
||||
hookManager configmanager.ConfigManager
|
||||
configManager *webhookutil.ClientManager
|
||||
}
|
||||
|
||||
// NewCustomizedExplorer return a new CustomizedExplorer.
|
||||
func NewCustomizedExplorer(kubeconfig string, informer informermanager.SingleClusterInformerManager) (*CustomizedExplorer, error) {
|
||||
// NewCustomizedInterpreter return a new CustomizedInterpreter.
|
||||
func NewCustomizedInterpreter(kubeconfig string, informer informermanager.SingleClusterInformerManager) (*CustomizedInterpreter, error) {
|
||||
cm, err := webhookutil.NewClientManager(
|
||||
[]schema.GroupVersion{configv1alpha1.SchemeGroupVersion},
|
||||
configv1alpha1.AddToScheme,
|
||||
|
|
@ -43,14 +43,14 @@ func NewCustomizedExplorer(kubeconfig string, informer informermanager.SingleClu
|
|||
cm.SetAuthenticationInfoResolver(authInfoResolver)
|
||||
cm.SetServiceResolver(webhookutil.NewDefaultServiceResolver())
|
||||
|
||||
return &CustomizedExplorer{
|
||||
return &CustomizedInterpreter{
|
||||
hookManager: configmanager.NewExploreConfigManager(informer),
|
||||
configManager: &cm,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// HookEnabled tells if any hook exist for specific resource type and operation type.
|
||||
func (e *CustomizedExplorer) HookEnabled(attributes *webhook.RequestAttributes) bool {
|
||||
func (e *CustomizedInterpreter) HookEnabled(attributes *webhook.RequestAttributes) bool {
|
||||
if !e.hookManager.HasSynced() {
|
||||
klog.Errorf("not yet ready to handle request")
|
||||
return false
|
||||
|
|
@ -58,7 +58,7 @@ func (e *CustomizedExplorer) HookEnabled(attributes *webhook.RequestAttributes)
|
|||
|
||||
hook := e.getFirstRelevantHook(attributes)
|
||||
if hook == nil {
|
||||
klog.V(4).Infof("Hook explorer is not enabled for kind %q with operation %q.",
|
||||
klog.V(4).Infof("Hook interpreter is not enabled for kind %q with operation %q.",
|
||||
attributes.Object.GroupVersionKind(), attributes.Operation)
|
||||
}
|
||||
return hook != nil
|
||||
|
|
@ -66,9 +66,9 @@ func (e *CustomizedExplorer) HookEnabled(attributes *webhook.RequestAttributes)
|
|||
|
||||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
|
||||
// return matched value to indicate whether there is a matching hook.
|
||||
func (e *CustomizedExplorer) GetReplicas(ctx context.Context, attributes *webhook.RequestAttributes) (replica int32, requires *workv1alpha2.ReplicaRequirements, matched bool, err error) {
|
||||
func (e *CustomizedInterpreter) GetReplicas(ctx context.Context, attributes *webhook.RequestAttributes) (replica int32, requires *workv1alpha2.ReplicaRequirements, matched bool, err error) {
|
||||
var response *webhook.ResponseAttributes
|
||||
response, matched, err = e.explore(ctx, attributes)
|
||||
response, matched, err = e.interpret(ctx, attributes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -81,9 +81,9 @@ func (e *CustomizedExplorer) GetReplicas(ctx context.Context, attributes *webhoo
|
|||
|
||||
// Retain returns the patch that based on the "desired" object but with values retained from the "observed" object.
|
||||
// return matched value to indicate whether there is a matching hook.
|
||||
func (e *CustomizedExplorer) Retain(ctx context.Context, attributes *webhook.RequestAttributes) (patch []byte, patchType configv1alpha1.PatchType, matched bool, err error) {
|
||||
func (e *CustomizedInterpreter) Retain(ctx context.Context, attributes *webhook.RequestAttributes) (patch []byte, patchType configv1alpha1.PatchType, matched bool, err error) {
|
||||
var response *webhook.ResponseAttributes
|
||||
response, matched, err = e.explore(ctx, attributes)
|
||||
response, matched, err = e.interpret(ctx, attributes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@ func (e *CustomizedExplorer) Retain(ctx context.Context, attributes *webhook.Req
|
|||
return response.Patch, response.PatchType, matched, nil
|
||||
}
|
||||
|
||||
func (e *CustomizedExplorer) getFirstRelevantHook(attributes *webhook.RequestAttributes) configmanager.WebhookAccessor {
|
||||
func (e *CustomizedInterpreter) getFirstRelevantHook(attributes *webhook.RequestAttributes) configmanager.WebhookAccessor {
|
||||
relevantHooks := make([]configmanager.WebhookAccessor, 0)
|
||||
for _, hook := range e.hookManager.HookAccessors() {
|
||||
if shouldCallHook(hook, attributes) {
|
||||
|
|
@ -113,7 +113,7 @@ func (e *CustomizedExplorer) getFirstRelevantHook(attributes *webhook.RequestAtt
|
|||
return relevantHooks[0]
|
||||
}
|
||||
|
||||
func (e *CustomizedExplorer) explore(ctx context.Context, attributes *webhook.RequestAttributes) (*webhook.ResponseAttributes, bool, error) {
|
||||
func (e *CustomizedInterpreter) interpret(ctx context.Context, attributes *webhook.RequestAttributes) (*webhook.ResponseAttributes, bool, error) {
|
||||
if !e.hookManager.HasSynced() {
|
||||
return nil, false, fmt.Errorf("not yet ready to handle request")
|
||||
}
|
||||
|
|
@ -158,7 +158,7 @@ func (e *CustomizedExplorer) explore(ctx context.Context, attributes *webhook.Re
|
|||
|
||||
func shouldCallHook(hook configmanager.WebhookAccessor, attributes *webhook.RequestAttributes) bool {
|
||||
for _, rule := range hook.GetRules() {
|
||||
matcher := crdexplorerutil.Matcher{
|
||||
matcher := interpreterutil.Matcher{
|
||||
Operation: attributes.Operation,
|
||||
Object: attributes.Object,
|
||||
Rule: rule,
|
||||
|
|
@ -170,8 +170,8 @@ func shouldCallHook(hook configmanager.WebhookAccessor, attributes *webhook.Requ
|
|||
return false
|
||||
}
|
||||
|
||||
func (e *CustomizedExplorer) callHook(ctx context.Context, hook configmanager.WebhookAccessor, attributes *webhook.RequestAttributes) (*webhook.ResponseAttributes, error) {
|
||||
uid, req, err := webhook.CreateExploreReview(hook.GetExploreReviewVersions(), attributes)
|
||||
func (e *CustomizedInterpreter) callHook(ctx context.Context, hook configmanager.WebhookAccessor, attributes *webhook.RequestAttributes) (*webhook.ResponseAttributes, error) {
|
||||
uid, req, err := webhook.CreateResourceInterpreterContext(hook.GetInterpreterContextVersions(), attributes)
|
||||
if err != nil {
|
||||
return nil, &webhookutil.ErrCallingWebhook{
|
||||
WebhookName: hook.GetUID(),
|
||||
|
|
@ -187,7 +187,7 @@ func (e *CustomizedExplorer) callHook(ctx context.Context, hook configmanager.We
|
|||
}
|
||||
}
|
||||
|
||||
trace := utiltrace.New("Call resource explore webhook",
|
||||
trace := utiltrace.New("Call resource interpret webhook",
|
||||
utiltrace.Field{Key: "configuration", Value: hook.GetConfigurationName()},
|
||||
utiltrace.Field{Key: "webhook", Value: hook.GetName()},
|
||||
utiltrace.Field{Key: "kind", Value: attributes.Object.GroupVersionKind()},
|
||||
|
|
@ -226,7 +226,7 @@ func (e *CustomizedExplorer) callHook(ctx context.Context, hook configmanager.We
|
|||
trace.Step("Request completed")
|
||||
|
||||
var res *webhook.ResponseAttributes
|
||||
res, err = webhook.VerifyExploreReview(uid, attributes.Operation, response)
|
||||
res, err = webhook.VerifyResourceInterpreterContext(uid, attributes.Operation, response)
|
||||
if err != nil {
|
||||
return nil, &webhookutil.ErrCallingWebhook{
|
||||
WebhookName: hook.GetUID(),
|
||||
|
|
@ -11,14 +11,14 @@ import (
|
|||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
)
|
||||
|
||||
// CreateExploreReview returns the unique request uid, the ResourceInterpreterContext object to send the webhook,
|
||||
// CreateResourceInterpreterContext returns the unique request uid, the ResourceInterpreterContext object to send the webhook,
|
||||
// or an error if the webhook does not support receiving any of the versions we know to send.
|
||||
func CreateExploreReview(versions []string, attributes *RequestAttributes) (uid types.UID, request runtime.Object, err error) {
|
||||
func CreateResourceInterpreterContext(versions []string, attributes *RequestAttributes) (uid types.UID, request runtime.Object, err error) {
|
||||
for _, version := range versions {
|
||||
switch version {
|
||||
case configv1alpha1.GroupVersion.Version:
|
||||
uid = uuid.NewUUID()
|
||||
request = CreateV1alpha1ExploreReview(uid, attributes)
|
||||
request = CreateV1alpha1ResourceInterpreterContext(uid, attributes)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -27,9 +27,9 @@ func CreateExploreReview(versions []string, attributes *RequestAttributes) (uid
|
|||
return
|
||||
}
|
||||
|
||||
// CreateV1alpha1ExploreReview creates an ResourceInterpreterContext for the provided RequestAttributes.
|
||||
func CreateV1alpha1ExploreReview(uid types.UID, attributes *RequestAttributes) *configv1alpha1.ResourceInterpreterContext {
|
||||
review := &configv1alpha1.ResourceInterpreterContext{
|
||||
// CreateV1alpha1ResourceInterpreterContext creates an ResourceInterpreterContext for the provided RequestAttributes.
|
||||
func CreateV1alpha1ResourceInterpreterContext(uid types.UID, attributes *RequestAttributes) *configv1alpha1.ResourceInterpreterContext {
|
||||
r := &configv1alpha1.ResourceInterpreterContext{
|
||||
Request: &configv1alpha1.ResourceInterpreterRequest{
|
||||
UID: uid,
|
||||
Kind: metav1.GroupVersionKind{
|
||||
|
|
@ -49,15 +49,15 @@ func CreateV1alpha1ExploreReview(uid types.UID, attributes *RequestAttributes) *
|
|||
}
|
||||
|
||||
if attributes.ObservedObj != nil {
|
||||
review.Request.ObservedObject = &runtime.RawExtension{Object: attributes.ObservedObj.DeepCopyObject()}
|
||||
r.Request.ObservedObject = &runtime.RawExtension{Object: attributes.ObservedObj.DeepCopyObject()}
|
||||
}
|
||||
return review
|
||||
return r
|
||||
}
|
||||
|
||||
// VerifyExploreReview checks the validity of the provided explore review object, and returns ResponseAttributes,
|
||||
// or an error if the provided explore review was not valid.
|
||||
func VerifyExploreReview(uid types.UID, operation configv1alpha1.InterpreterOperation, review runtime.Object) (response *ResponseAttributes, err error) {
|
||||
switch r := review.(type) {
|
||||
// VerifyResourceInterpreterContext checks the validity of the provided resourceInterpreterContext, and returns ResponseAttributes,
|
||||
// or an error if the provided resourceInterpreterContext was not valid.
|
||||
func VerifyResourceInterpreterContext(uid types.UID, operation configv1alpha1.InterpreterOperation, interpreterContext runtime.Object) (response *ResponseAttributes, err error) {
|
||||
switch r := interpreterContext.(type) {
|
||||
case *configv1alpha1.ResourceInterpreterContext:
|
||||
if r.Response == nil {
|
||||
return nil, fmt.Errorf("webhook resonse was absent")
|
||||
|
|
@ -67,17 +67,17 @@ func VerifyExploreReview(uid types.UID, operation configv1alpha1.InterpreterOper
|
|||
return nil, fmt.Errorf("expected response.uid %q, got %q", uid, r.Response.UID)
|
||||
}
|
||||
|
||||
res, err := verifyExploreResponse(operation, r.Response)
|
||||
res, err := verifyResourceInterpreterContext(operation, r.Response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected response type %T", review)
|
||||
return nil, fmt.Errorf("unexpected response type %T", interpreterContext)
|
||||
}
|
||||
}
|
||||
|
||||
func verifyExploreResponse(operation configv1alpha1.InterpreterOperation, response *configv1alpha1.ResourceInterpreterResponse) (*ResponseAttributes, error) {
|
||||
func verifyResourceInterpreterContext(operation configv1alpha1.InterpreterOperation, response *configv1alpha1.ResourceInterpreterResponse) (*ResponseAttributes, error) {
|
||||
res := &ResponseAttributes{}
|
||||
|
||||
res.Successful = response.Successful
|
||||
|
|
@ -101,8 +101,8 @@ func verifyExploreResponse(operation configv1alpha1.InterpreterOperation, respon
|
|||
res.Dependencies = response.Dependencies
|
||||
return res, nil
|
||||
case configv1alpha1.InterpreterOperationPrune, configv1alpha1.InterpreterOperationReviseReplica,
|
||||
configv1alpha1.InterpreterOperationRetention, configv1alpha1.InterpreterOperationAggregateStatus:
|
||||
err := verifyExploreResponseWithPatch(response)
|
||||
configv1alpha1.InterpreterOperationRetain, configv1alpha1.InterpreterOperationAggregateStatus:
|
||||
err := verifyResourceInterpreterContextWithPatch(response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ func verifyExploreResponse(operation configv1alpha1.InterpreterOperation, respon
|
|||
}
|
||||
}
|
||||
|
||||
func verifyExploreResponseWithPatch(response *configv1alpha1.ResourceInterpreterResponse) error {
|
||||
func verifyResourceInterpreterContextWithPatch(response *configv1alpha1.ResourceInterpreterResponse) error {
|
||||
if len(response.Patch) == 0 && response.PatchType == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package defaultinterpreter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
)
|
||||
|
||||
// DefaultInterpreter contains all default operation interpreter factory
|
||||
// for interpreting common resource.
|
||||
type DefaultInterpreter struct {
|
||||
replicaHandlers map[schema.GroupVersionKind]replicaInterpreter
|
||||
retentionHandlers map[schema.GroupVersionKind]retentionInterpreter
|
||||
}
|
||||
|
||||
// NewDefaultInterpreter return a new DefaultInterpreter.
|
||||
func NewDefaultInterpreter() *DefaultInterpreter {
|
||||
return &DefaultInterpreter{
|
||||
replicaHandlers: getAllDefaultReplicaInterpreter(),
|
||||
retentionHandlers: getAllDefaultRetentionInterpreter(),
|
||||
}
|
||||
}
|
||||
|
||||
// HookEnabled tells if any hook exist for specific resource type and operation type.
|
||||
func (e *DefaultInterpreter) HookEnabled(kind schema.GroupVersionKind, operationType configv1alpha1.InterpreterOperation) bool {
|
||||
switch operationType {
|
||||
case configv1alpha1.InterpreterOperationInterpretReplica:
|
||||
if _, exist := e.replicaHandlers[kind]; exist {
|
||||
return true
|
||||
}
|
||||
case configv1alpha1.InterpreterOperationRetain:
|
||||
if _, exist := e.retentionHandlers[kind]; exist {
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO(RainbowMango): more cases should be added here
|
||||
}
|
||||
|
||||
klog.V(4).Infof("Default interpreter is not enabled for kind %q with operation %q.", kind, operationType)
|
||||
return false
|
||||
}
|
||||
|
||||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
|
||||
func (e *DefaultInterpreter) GetReplicas(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error) {
|
||||
handler, exist := e.replicaHandlers[object.GroupVersionKind()]
|
||||
if !exist {
|
||||
return 0, &workv1alpha2.ReplicaRequirements{}, fmt.Errorf("defalut interpreter for operation %s not found", configv1alpha1.InterpreterOperationInterpretReplica)
|
||||
}
|
||||
return handler(object)
|
||||
}
|
||||
|
||||
// Retain returns the objects that based on the "desired" object but with values retained from the "observed" object.
|
||||
func (e *DefaultInterpreter) Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error) {
|
||||
handler, exist := e.retentionHandlers[desired.GroupVersionKind()]
|
||||
if !exist {
|
||||
return nil, fmt.Errorf("default retain interpreter for %q not found", desired.GroupVersionKind())
|
||||
}
|
||||
|
||||
return handler(desired, observed)
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package defaultexplorer
|
||||
package defaultinterpreter
|
||||
|
||||
import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
|
|
@ -12,17 +12,17 @@ import (
|
|||
"github.com/karmada-io/karmada/pkg/util/helper"
|
||||
)
|
||||
|
||||
// replicaExplorer is the function that used to parse replica and requirements from object.
|
||||
type replicaExplorer func(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error)
|
||||
// replicaInterpreter is the function that used to parse replica and requirements from object.
|
||||
type replicaInterpreter func(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error)
|
||||
|
||||
func getAllDefaultReplicaExplorer() map[schema.GroupVersionKind]replicaExplorer {
|
||||
explorers := make(map[schema.GroupVersionKind]replicaExplorer)
|
||||
explorers[appsv1.SchemeGroupVersion.WithKind(util.DeploymentKind)] = deployReplicaExplorer
|
||||
explorers[batchv1.SchemeGroupVersion.WithKind(util.JobKind)] = jobReplicaExplorer
|
||||
return explorers
|
||||
func getAllDefaultReplicaInterpreter() map[schema.GroupVersionKind]replicaInterpreter {
|
||||
s := make(map[schema.GroupVersionKind]replicaInterpreter)
|
||||
s[appsv1.SchemeGroupVersion.WithKind(util.DeploymentKind)] = deployReplica
|
||||
s[batchv1.SchemeGroupVersion.WithKind(util.JobKind)] = jobReplica
|
||||
return s
|
||||
}
|
||||
|
||||
func deployReplicaExplorer(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error) {
|
||||
func deployReplica(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error) {
|
||||
deploy, err := helper.ConvertToDeployment(object)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to convert object(%s), err", object.GroupVersionKind().String(), err)
|
||||
|
|
@ -38,7 +38,7 @@ func deployReplicaExplorer(object *unstructured.Unstructured) (int32, *workv1alp
|
|||
return replica, requirement, nil
|
||||
}
|
||||
|
||||
func jobReplicaExplorer(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error) {
|
||||
func jobReplica(object *unstructured.Unstructured) (int32, *workv1alpha2.ReplicaRequirements, error) {
|
||||
job, err := helper.ConvertToJob(object)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to convert object(%s), err", object.GroupVersionKind().String(), err)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package defaultexplorer
|
||||
package defaultinterpreter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -13,17 +13,17 @@ import (
|
|||
"github.com/karmada-io/karmada/pkg/util/helper"
|
||||
)
|
||||
|
||||
// retentionExplorer is the function that retains values from "observed" object.
|
||||
type retentionExplorer func(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error)
|
||||
// retentionInterpreter is the function that retains values from "observed" object.
|
||||
type retentionInterpreter func(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error)
|
||||
|
||||
func getAllDefaultRetentionExplorer() map[schema.GroupVersionKind]retentionExplorer {
|
||||
explorers := make(map[schema.GroupVersionKind]retentionExplorer)
|
||||
explorers[corev1.SchemeGroupVersion.WithKind(util.PodKind)] = retainPodFields
|
||||
explorers[corev1.SchemeGroupVersion.WithKind(util.ServiceKind)] = retainServiceFields
|
||||
explorers[corev1.SchemeGroupVersion.WithKind(util.ServiceAccountKind)] = retainServiceAccountFields
|
||||
explorers[corev1.SchemeGroupVersion.WithKind(util.PersistentVolumeClaimKind)] = retainPersistentVolumeClaimFields
|
||||
explorers[batchv1.SchemeGroupVersion.WithKind(util.JobKind)] = retainJobSelectorFields
|
||||
return explorers
|
||||
func getAllDefaultRetentionInterpreter() map[schema.GroupVersionKind]retentionInterpreter {
|
||||
s := make(map[schema.GroupVersionKind]retentionInterpreter)
|
||||
s[corev1.SchemeGroupVersion.WithKind(util.PodKind)] = retainPodFields
|
||||
s[corev1.SchemeGroupVersion.WithKind(util.ServiceKind)] = retainServiceFields
|
||||
s[corev1.SchemeGroupVersion.WithKind(util.ServiceAccountKind)] = retainServiceAccountFields
|
||||
s[corev1.SchemeGroupVersion.WithKind(util.PersistentVolumeClaimKind)] = retainPersistentVolumeClaimFields
|
||||
s[batchv1.SchemeGroupVersion.WithKind(util.JobKind)] = retainJobSelectorFields
|
||||
return s
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package crdexplorer
|
||||
package resourceinterpreter
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -10,18 +10,18 @@ import (
|
|||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer/customizedexplorer"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer/customizedexplorer/webhook"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer/defaultexplorer"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter/customizedinterpreter"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter/customizedinterpreter/webhook"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter/defaultinterpreter"
|
||||
"github.com/karmada-io/karmada/pkg/util/informermanager"
|
||||
)
|
||||
|
||||
// CustomResourceExplorer manages both default and customized webhooks to explore custom resource structure.
|
||||
type CustomResourceExplorer interface {
|
||||
// ResourceInterpreter manages both default and customized webhooks to interpret custom resource structure.
|
||||
type ResourceInterpreter interface {
|
||||
// Start starts running the component and will never stop running until the context is closed or an error occurs.
|
||||
Start(ctx context.Context) (err error)
|
||||
|
||||
// HookEnabled tells if any hook exist for specific resource type and operation type.
|
||||
// HookEnabled tells if any hook exist for specific resource type and operation.
|
||||
HookEnabled(object *unstructured.Unstructured, operationType configv1alpha1.InterpreterOperation) bool
|
||||
|
||||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
|
||||
|
|
@ -33,32 +33,32 @@ type CustomResourceExplorer interface {
|
|||
// other common method
|
||||
}
|
||||
|
||||
// NewCustomResourceExplorer builds a new CustomResourceExplorer object.
|
||||
func NewCustomResourceExplorer(kubeconfig string, informer informermanager.SingleClusterInformerManager) CustomResourceExplorer {
|
||||
return &customResourceExplorerImpl{
|
||||
// NewResourceInterpreter builds a new ResourceInterpreter object.
|
||||
func NewResourceInterpreter(kubeconfig string, informer informermanager.SingleClusterInformerManager) ResourceInterpreter {
|
||||
return &customResourceInterpreterImpl{
|
||||
kubeconfig: kubeconfig,
|
||||
informer: informer,
|
||||
}
|
||||
}
|
||||
|
||||
type customResourceExplorerImpl struct {
|
||||
type customResourceInterpreterImpl struct {
|
||||
kubeconfig string
|
||||
informer informermanager.SingleClusterInformerManager
|
||||
|
||||
customizedExplorer *customizedexplorer.CustomizedExplorer
|
||||
defaultExplorer *defaultexplorer.DefaultExplorer
|
||||
customizedInterpreter *customizedinterpreter.CustomizedInterpreter
|
||||
defaultInterpreter *defaultinterpreter.DefaultInterpreter
|
||||
}
|
||||
|
||||
// Start starts running the component and will never stop running until the context is closed or an error occurs.
|
||||
func (i *customResourceExplorerImpl) Start(ctx context.Context) (err error) {
|
||||
klog.Infof("Starting custom resource explorer.")
|
||||
func (i *customResourceInterpreterImpl) Start(ctx context.Context) (err error) {
|
||||
klog.Infof("Starting custom resource interpreter.")
|
||||
|
||||
i.customizedExplorer, err = customizedexplorer.NewCustomizedExplorer(i.kubeconfig, i.informer)
|
||||
i.customizedInterpreter, err = customizedinterpreter.NewCustomizedInterpreter(i.kubeconfig, i.informer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
i.defaultExplorer = defaultexplorer.NewDefaultExplorer()
|
||||
i.defaultInterpreter = defaultinterpreter.NewDefaultInterpreter()
|
||||
|
||||
i.informer.Start()
|
||||
<-ctx.Done()
|
||||
|
|
@ -66,21 +66,21 @@ func (i *customResourceExplorerImpl) Start(ctx context.Context) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// HookEnabled tells if any hook exist for specific resource type and operation type.
|
||||
func (i *customResourceExplorerImpl) HookEnabled(object *unstructured.Unstructured, operationType configv1alpha1.InterpreterOperation) bool {
|
||||
// HookEnabled tells if any hook exist for specific resource type and operation.
|
||||
func (i *customResourceInterpreterImpl) HookEnabled(object *unstructured.Unstructured, operation configv1alpha1.InterpreterOperation) bool {
|
||||
attributes := &webhook.RequestAttributes{
|
||||
Operation: operationType,
|
||||
Operation: operation,
|
||||
Object: object,
|
||||
}
|
||||
return i.customizedExplorer.HookEnabled(attributes) || i.defaultExplorer.HookEnabled(object.GroupVersionKind(), operationType)
|
||||
return i.customizedInterpreter.HookEnabled(attributes) || i.defaultInterpreter.HookEnabled(object.GroupVersionKind(), operation)
|
||||
}
|
||||
|
||||
// GetReplicas returns the desired replicas of the object as well as the requirements of each replica.
|
||||
func (i *customResourceExplorerImpl) GetReplicas(object *unstructured.Unstructured) (replica int32, requires *workv1alpha2.ReplicaRequirements, err error) {
|
||||
func (i *customResourceInterpreterImpl) GetReplicas(object *unstructured.Unstructured) (replica int32, requires *workv1alpha2.ReplicaRequirements, err error) {
|
||||
klog.V(4).Infof("Begin to get replicas for request object: %v %s/%s.", object.GroupVersionKind(), object.GetNamespace(), object.GetName())
|
||||
|
||||
var hookEnabled bool
|
||||
replica, requires, hookEnabled, err = i.customizedExplorer.GetReplicas(context.TODO(), &webhook.RequestAttributes{
|
||||
replica, requires, hookEnabled, err = i.customizedInterpreter.GetReplicas(context.TODO(), &webhook.RequestAttributes{
|
||||
Operation: configv1alpha1.InterpreterOperationInterpretReplica,
|
||||
Object: object,
|
||||
})
|
||||
|
|
@ -91,19 +91,19 @@ func (i *customResourceExplorerImpl) GetReplicas(object *unstructured.Unstructur
|
|||
return
|
||||
}
|
||||
|
||||
replica, requires, err = i.defaultExplorer.GetReplicas(object)
|
||||
replica, requires, err = i.defaultInterpreter.GetReplicas(object)
|
||||
return
|
||||
}
|
||||
|
||||
// Retain returns the objects that based on the "desired" object but with values retained from the "observed" object.
|
||||
func (i *customResourceExplorerImpl) Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error) {
|
||||
func (i *customResourceInterpreterImpl) Retain(desired *unstructured.Unstructured, observed *unstructured.Unstructured) (retained *unstructured.Unstructured, err error) {
|
||||
klog.V(4).Infof("Begin to retain object: %v %s/%s.", desired.GroupVersionKind(), desired.GetNamespace(), desired.GetName())
|
||||
|
||||
var hookEnabled bool
|
||||
var patch []byte
|
||||
var patchType configv1alpha1.PatchType
|
||||
patch, patchType, hookEnabled, err = i.customizedExplorer.Retain(context.TODO(), &webhook.RequestAttributes{
|
||||
Operation: configv1alpha1.InterpreterOperationRetention,
|
||||
patch, patchType, hookEnabled, err = i.customizedInterpreter.Retain(context.TODO(), &webhook.RequestAttributes{
|
||||
Operation: configv1alpha1.InterpreterOperationRetain,
|
||||
Object: desired,
|
||||
ObservedObj: observed,
|
||||
})
|
||||
|
|
@ -114,10 +114,11 @@ func (i *customResourceExplorerImpl) Retain(desired *unstructured.Unstructured,
|
|||
return applyPatch(desired, patch, patchType)
|
||||
}
|
||||
|
||||
return i.defaultExplorer.Retain(desired, observed)
|
||||
return i.defaultInterpreter.Retain(desired, observed)
|
||||
}
|
||||
|
||||
func applyPatch(desired *unstructured.Unstructured, patch []byte, patchType configv1alpha1.PatchType) (*unstructured.Unstructured, error) {
|
||||
// applyPatch uses patchType mode to patch object.
|
||||
func applyPatch(object *unstructured.Unstructured, patch []byte, patchType configv1alpha1.PatchType) (*unstructured.Unstructured, error) {
|
||||
switch patchType {
|
||||
case configv1alpha1.PatchTypeJSONPatch:
|
||||
patchObj, err := jsonpatch.DecodePatch(patch)
|
||||
|
|
@ -125,10 +126,10 @@ func applyPatch(desired *unstructured.Unstructured, patch []byte, patchType conf
|
|||
return nil, err
|
||||
}
|
||||
if len(patchObj) == 0 {
|
||||
return desired, nil
|
||||
return object, nil
|
||||
}
|
||||
|
||||
objectJSONBytes, err := desired.MarshalJSON()
|
||||
objectJSONBytes, err := object.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -137,8 +138,8 @@ func applyPatch(desired *unstructured.Unstructured, patch []byte, patchType conf
|
|||
return nil, err
|
||||
}
|
||||
|
||||
err = desired.UnmarshalJSON(patchedObjectJSONBytes)
|
||||
return desired, err
|
||||
err = object.UnmarshalJSON(patchedObjectJSONBytes)
|
||||
return object, err
|
||||
default:
|
||||
return nil, fmt.Errorf("return patch type %s is not support", patchType)
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package crdexplorer
|
||||
package interpreter
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
|
||||
"github.com/karmada-io/karmada/pkg/crdexplorer"
|
||||
"github.com/karmada-io/karmada/pkg/resourceinterpreter"
|
||||
"github.com/karmada-io/karmada/pkg/util"
|
||||
"github.com/karmada-io/karmada/pkg/util/restmapper"
|
||||
)
|
||||
|
|
@ -43,17 +43,17 @@ type objectWatcherImpl struct {
|
|||
KubeClientSet client.Client
|
||||
VersionRecord map[string]map[string]string
|
||||
ClusterClientSetFunc ClientSetFunc
|
||||
resourceExplorer crdexplorer.CustomResourceExplorer
|
||||
resourceInterpreter resourceinterpreter.ResourceInterpreter
|
||||
}
|
||||
|
||||
// NewObjectWatcher returns an instance of ObjectWatcher
|
||||
func NewObjectWatcher(kubeClientSet client.Client, restMapper meta.RESTMapper, clusterClientSetFunc ClientSetFunc, explorer crdexplorer.CustomResourceExplorer) ObjectWatcher {
|
||||
func NewObjectWatcher(kubeClientSet client.Client, restMapper meta.RESTMapper, clusterClientSetFunc ClientSetFunc, interpreter resourceinterpreter.ResourceInterpreter) ObjectWatcher {
|
||||
return &objectWatcherImpl{
|
||||
KubeClientSet: kubeClientSet,
|
||||
VersionRecord: make(map[string]map[string]string),
|
||||
RESTMapper: restMapper,
|
||||
ClusterClientSetFunc: clusterClientSetFunc,
|
||||
resourceExplorer: explorer,
|
||||
resourceInterpreter: interpreter,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,8 +113,8 @@ func (o *objectWatcherImpl) retainClusterFields(desired, observed *unstructured.
|
|||
// and be set by user in karmada-controller-plane.
|
||||
util.MergeAnnotations(desired, observed)
|
||||
|
||||
if o.resourceExplorer.HookEnabled(desired, configv1alpha1.InterpreterOperationRetention) {
|
||||
return o.resourceExplorer.Retain(desired, observed)
|
||||
if o.resourceInterpreter.HookEnabled(desired, configv1alpha1.InterpreterOperationRetain) {
|
||||
return o.resourceInterpreter.Retain(desired, observed)
|
||||
}
|
||||
|
||||
return desired, nil
|
||||
|
|
|
|||
|
|
@ -1,18 +1,11 @@
|
|||
package crdexplorer
|
||||
package configuration
|
||||
|
||||
import (
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
|
||||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
)
|
||||
|
||||
var supportedFailurePolicies = sets.NewString(
|
||||
string(admissionregistrationv1.Ignore),
|
||||
string(admissionregistrationv1.Fail),
|
||||
)
|
||||
|
||||
func hasWildcard(slice []string) bool {
|
||||
for _, s := range slice {
|
||||
if s == "*" {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package crdexplorer
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package crdexplorer
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -62,19 +62,13 @@ func (v *ValidatingAdmission) InjectDecoder(d *admission.Decoder) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var supportedOperationType = sets.NewString(
|
||||
var supportedInterpreterOperation = sets.NewString(
|
||||
string(configv1alpha1.InterpreterOperationAll),
|
||||
string(configv1alpha1.InterpreterOperationInterpretReplica),
|
||||
string(configv1alpha1.InterpreterOperationInterpretStatus),
|
||||
string(configv1alpha1.InterpreterOperationPrune),
|
||||
string(configv1alpha1.InterpreterOperationReviseReplica),
|
||||
string(configv1alpha1.InterpreterOperationRetention),
|
||||
string(configv1alpha1.InterpreterOperationAggregateStatus),
|
||||
string(configv1alpha1.InterpreterOperationInterpretHealthy),
|
||||
string(configv1alpha1.InterpreterOperationInterpretDependency),
|
||||
string(configv1alpha1.InterpreterOperationRetain),
|
||||
)
|
||||
|
||||
var acceptedExploreReviewVersions = []string{configv1alpha1.GroupVersion.Version}
|
||||
var acceptedInterpreterContextVersions = []string{configv1alpha1.GroupVersion.Version}
|
||||
|
||||
func validateWebhook(hook *configv1alpha1.ResourceInterpreterWebhook, fldPath *field.Path) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
|
|
@ -85,10 +79,6 @@ func validateWebhook(hook *configv1alpha1.ResourceInterpreterWebhook, fldPath *f
|
|||
allErrors = append(allErrors, validateRuleWithOperations(&hook.Rules[i], fldPath.Child("rules").Index(i))...)
|
||||
}
|
||||
|
||||
if hook.FailurePolicy != nil && !supportedFailurePolicies.Has(string(*hook.FailurePolicy)) {
|
||||
allErrors = append(allErrors, field.NotSupported(fldPath.Child("matchPolicy"), *hook.FailurePolicy, supportedFailurePolicies.List()))
|
||||
}
|
||||
|
||||
if hook.TimeoutSeconds != nil && (*hook.TimeoutSeconds > 30 || *hook.TimeoutSeconds < 1) {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath.Child("timeoutSeconds"), *hook.TimeoutSeconds, "the timeout value must be between 1 and 30 seconds"))
|
||||
}
|
||||
|
|
@ -103,7 +93,7 @@ func validateWebhook(hook *configv1alpha1.ResourceInterpreterWebhook, fldPath *f
|
|||
allErrors = append(allErrors, webhook.ValidateWebhookService(fldPath.Child("clientConfig").Child("service"), cc.Service.Name, cc.Service.Namespace, cc.Service.Path, *cc.Service.Port)...)
|
||||
}
|
||||
|
||||
allErrors = append(allErrors, validateExploreReviewVersions(hook.ExploreReviewVersions, fldPath.Child("exploreReviewVersions"))...)
|
||||
allErrors = append(allErrors, validateInterpreterContextVersions(hook.InterpreterContextVersions, fldPath.Child("interpreterContextVersions"))...)
|
||||
return allErrors
|
||||
}
|
||||
|
||||
|
|
@ -125,20 +115,20 @@ func validateRuleWithOperations(ruleWithOperations *configv1alpha1.RuleWithOpera
|
|||
allErrors = append(allErrors, field.Invalid(fldPath.Child("operations"), ruleWithOperations.Operations, "if '*' is present, must not specify other operations"))
|
||||
}
|
||||
for i, operation := range ruleWithOperations.Operations {
|
||||
if !supportedOperationType.Has(string(operation)) {
|
||||
allErrors = append(allErrors, field.NotSupported(fldPath.Child("operations").Index(i), operation, supportedOperationType.List()))
|
||||
if !supportedInterpreterOperation.Has(string(operation)) {
|
||||
allErrors = append(allErrors, field.NotSupported(fldPath.Child("operations").Index(i), operation, supportedInterpreterOperation.List()))
|
||||
}
|
||||
}
|
||||
allErrors = append(allErrors, validateRule(&ruleWithOperations.Rule, fldPath)...)
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func validateExploreReviewVersions(versions []string, fldPath *field.Path) field.ErrorList {
|
||||
func validateInterpreterContextVersions(versions []string, fldPath *field.Path) field.ErrorList {
|
||||
allErrors := field.ErrorList{}
|
||||
|
||||
// Currently, only v1alpha1 accepted in ExploreReviewVersions
|
||||
// Currently, only v1alpha1 accepted in InterpreterContextVersions
|
||||
if len(versions) < 1 {
|
||||
allErrors = append(allErrors, field.Required(fldPath, fmt.Sprintf("must specify one of %v", strings.Join(acceptedExploreReviewVersions, ", "))))
|
||||
allErrors = append(allErrors, field.Required(fldPath, fmt.Sprintf("must specify one of %v", strings.Join(acceptedInterpreterContextVersions, ", "))))
|
||||
} else {
|
||||
visited := map[string]bool{}
|
||||
hasAcceptedVersion := false
|
||||
|
|
@ -158,14 +148,14 @@ func validateExploreReviewVersions(versions []string, fldPath *field.Path) field
|
|||
if !hasAcceptedVersion {
|
||||
allErrors = append(allErrors, field.Invalid(
|
||||
fldPath, versions,
|
||||
fmt.Sprintf("must include at least one of %v", strings.Join(acceptedExploreReviewVersions, ", "))))
|
||||
fmt.Sprintf("must include at least one of %v", strings.Join(acceptedInterpreterContextVersions, ", "))))
|
||||
}
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func isAcceptedExploreReviewVersions(v string) bool {
|
||||
for _, version := range acceptedExploreReviewVersions {
|
||||
for _, version := range acceptedInterpreterContextVersions {
|
||||
if v == version {
|
||||
return true
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package crdexplorer
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -59,12 +59,12 @@ func TestIsAcceptedExploreReviewVersions(t *testing.T) {
|
|||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "is accepted explore review versions",
|
||||
version: acceptedExploreReviewVersions[0],
|
||||
name: "is accepted interpreter context versions",
|
||||
version: acceptedInterpreterContextVersions[0],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "is not accepted explore review versions",
|
||||
name: "is not accepted interpreter context versions",
|
||||
version: "",
|
||||
expected: false,
|
||||
},
|
||||
|
|
@ -140,7 +140,7 @@ func TestValidateRuleWithOperations(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestValidateExploreReviewVersions(t *testing.T) {
|
||||
fldPath := field.NewPath("webhooks").Child("exploreReviewVersions")
|
||||
fldPath := field.NewPath("webhooks").Child("interpreterContextVersions")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -150,7 +150,7 @@ func TestValidateExploreReviewVersions(t *testing.T) {
|
|||
{
|
||||
name: "no versions",
|
||||
versions: nil,
|
||||
expectedError: fmt.Sprintf("must specify one of %v", strings.Join(acceptedExploreReviewVersions, ", ")),
|
||||
expectedError: fmt.Sprintf("must specify one of %v", strings.Join(acceptedInterpreterContextVersions, ", ")),
|
||||
},
|
||||
{
|
||||
name: "duplicate versions",
|
||||
|
|
@ -160,7 +160,7 @@ func TestValidateExploreReviewVersions(t *testing.T) {
|
|||
{
|
||||
name: "invalid versions",
|
||||
versions: []string{"test", "test"},
|
||||
expectedError: fmt.Sprintf("must include at least one of %v", strings.Join(acceptedExploreReviewVersions, ", ")),
|
||||
expectedError: fmt.Sprintf("must include at least one of %v", strings.Join(acceptedInterpreterContextVersions, ", ")),
|
||||
},
|
||||
{
|
||||
name: "invalid DNS (RFC 1035) label",
|
||||
|
|
@ -171,7 +171,7 @@ func TestValidateExploreReviewVersions(t *testing.T) {
|
|||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
errs := validateExploreReviewVersions(test.versions, fldPath)
|
||||
errs := validateInterpreterContextVersions(test.versions, fldPath)
|
||||
err := errs.ToAggregate()
|
||||
if err != nil {
|
||||
if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" {
|
||||
|
|
@ -188,7 +188,6 @@ func TestValidateExploreReviewVersions(t *testing.T) {
|
|||
|
||||
func TestValidateWebhook(t *testing.T) {
|
||||
fldPath := field.NewPath("webhooks")
|
||||
policy := admissionregistrationv1.FailurePolicyType("fake policy")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -213,13 +212,6 @@ func TestValidateWebhook(t *testing.T) {
|
|||
},
|
||||
expectedError: "operations: Required value",
|
||||
},
|
||||
{
|
||||
name: "invalid policy",
|
||||
hook: &configv1alpha1.ResourceInterpreterWebhook{
|
||||
FailurePolicy: &policy,
|
||||
},
|
||||
expectedError: "matchPolicy",
|
||||
},
|
||||
{
|
||||
name: "invalid timeout",
|
||||
hook: &configv1alpha1.ResourceInterpreterWebhook{
|
||||
|
|
@ -257,11 +249,11 @@ func TestValidateWebhook(t *testing.T) {
|
|||
expectedError: "service name is required",
|
||||
},
|
||||
{
|
||||
name: "invalid explore review versions",
|
||||
name: "invalid interpreter context versions",
|
||||
hook: &configv1alpha1.ResourceInterpreterWebhook{
|
||||
ExploreReviewVersions: []string{""},
|
||||
InterpreterContextVersions: []string{""},
|
||||
},
|
||||
expectedError: fmt.Sprintf("must include at least one of %v", strings.Join(acceptedExploreReviewVersions, ", ")),
|
||||
expectedError: fmt.Sprintf("must include at least one of %v", strings.Join(acceptedInterpreterContextVersions, ", ")),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package explorer
|
||||
package interpreter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/json"
|
||||
)
|
||||
|
||||
// Decoder knows how to decode the contents of an explorer
|
||||
// Decoder knows how to decode the contents of an resource interpreter
|
||||
// request into a concrete object.
|
||||
type Decoder struct {
|
||||
codecs serializer.CodecFactory
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package explorer
|
||||
package interpreter
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
|
@ -24,20 +24,20 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
var err error
|
||||
ctx := r.Context()
|
||||
|
||||
var reviewResponse Response
|
||||
var res Response
|
||||
if r.Body == nil {
|
||||
err = errors.New("request body is empty")
|
||||
klog.Errorf("bad request: %w", err)
|
||||
reviewResponse = Errored(http.StatusBadRequest, err)
|
||||
wh.writeResponse(w, reviewResponse)
|
||||
res = Errored(http.StatusBadRequest, err)
|
||||
wh.writeResponse(w, res)
|
||||
return
|
||||
}
|
||||
|
||||
defer r.Body.Close()
|
||||
if body, err = ioutil.ReadAll(r.Body); err != nil {
|
||||
klog.Errorf("unable to read the body from the incoming request: %w", err)
|
||||
reviewResponse = Errored(http.StatusBadRequest, err)
|
||||
wh.writeResponse(w, reviewResponse)
|
||||
res = Errored(http.StatusBadRequest, err)
|
||||
wh.writeResponse(w, res)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -45,42 +45,42 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
if contentType := r.Header.Get("Content-Type"); contentType != "application/json" {
|
||||
err = fmt.Errorf("contentType=%s, expected application/json", contentType)
|
||||
klog.Errorf("unable to process a request with an unknown content type: %w", err)
|
||||
reviewResponse = Errored(http.StatusBadRequest, err)
|
||||
wh.writeResponse(w, reviewResponse)
|
||||
res = Errored(http.StatusBadRequest, err)
|
||||
wh.writeResponse(w, res)
|
||||
return
|
||||
}
|
||||
|
||||
request := Request{}
|
||||
er := configv1alpha1.ResourceInterpreterContext{}
|
||||
interpreterContext := configv1alpha1.ResourceInterpreterContext{}
|
||||
// avoid an extra copy
|
||||
er.Request = &request.ResourceInterpreterRequest
|
||||
_, _, err = admissionCodecs.UniversalDeserializer().Decode(body, nil, &er)
|
||||
interpreterContext.Request = &request.ResourceInterpreterRequest
|
||||
_, _, err = admissionCodecs.UniversalDeserializer().Decode(body, nil, &interpreterContext)
|
||||
if err != nil {
|
||||
klog.Errorf("unable to decode the request: %w", err)
|
||||
reviewResponse = Errored(http.StatusBadRequest, err)
|
||||
wh.writeResponse(w, reviewResponse)
|
||||
res = Errored(http.StatusBadRequest, err)
|
||||
wh.writeResponse(w, res)
|
||||
return
|
||||
}
|
||||
klog.V(1).Infof("received request UID: %q, kind: %s", request.UID, request.Kind)
|
||||
|
||||
reviewResponse = wh.Handle(ctx, request)
|
||||
wh.writeResponse(w, reviewResponse)
|
||||
res = wh.Handle(ctx, request)
|
||||
wh.writeResponse(w, res)
|
||||
}
|
||||
|
||||
// writeResponse writes response to w generically, i.e. without encoding GVK information.
|
||||
func (wh *Webhook) writeResponse(w io.Writer, response Response) {
|
||||
wh.writeExploreResponse(w, configv1alpha1.ResourceInterpreterContext{
|
||||
wh.writeResourceInterpreterResponse(w, configv1alpha1.ResourceInterpreterContext{
|
||||
Response: &response.ResourceInterpreterResponse,
|
||||
})
|
||||
}
|
||||
|
||||
// writeExploreResponse writes ar to w.
|
||||
func (wh *Webhook) writeExploreResponse(w io.Writer, review configv1alpha1.ResourceInterpreterContext) {
|
||||
if err := json.NewEncoder(w).Encode(review); err != nil {
|
||||
// writeResourceInterpreterResponse writes ar to w.
|
||||
func (wh *Webhook) writeResourceInterpreterResponse(w io.Writer, interpreterContext configv1alpha1.ResourceInterpreterContext) {
|
||||
if err := json.NewEncoder(w).Encode(interpreterContext); err != nil {
|
||||
klog.Errorf("unable to encode the response: %w", err)
|
||||
wh.writeResponse(w, Errored(http.StatusInternalServerError, err))
|
||||
} else {
|
||||
response := review.Response
|
||||
response := interpreterContext.Response
|
||||
if response.Successful {
|
||||
klog.V(4).Infof("wrote response UID: %q, successful: %t", response.UID, response.Successful)
|
||||
} else {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package explorer
|
||||
package interpreter
|
||||
|
||||
// DecoderInjector is used by the ControllerManager to inject decoder into webhook handlers.
|
||||
type DecoderInjector interface {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package explorer
|
||||
package interpreter
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
|
@ -27,7 +27,7 @@ func Succeeded(msg string) Response {
|
|||
return ValidationResponse(true, msg)
|
||||
}
|
||||
|
||||
// ValidationResponse returns a response for handle a explore request.
|
||||
// ValidationResponse returns a response for handle a interpret request.
|
||||
func ValidationResponse(successful bool, msg string) Response {
|
||||
code := http.StatusForbidden
|
||||
if successful {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package explorer
|
||||
package interpreter
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -9,7 +9,7 @@ import (
|
|||
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
||||
)
|
||||
|
||||
// Request defines the input for an explorer handler.
|
||||
// Request defines the input for an interpreter handler.
|
||||
// It contains information to identify the object in
|
||||
// question (kind, name, namespace), as well as the
|
||||
// operation in request(e.g. InterpreterOperationInterpretReplica, InterpreterOperationPrune,
|
||||
|
|
@ -18,7 +18,7 @@ type Request struct {
|
|||
configv1alpha1.ResourceInterpreterRequest
|
||||
}
|
||||
|
||||
// Response is the output of an explorer handler.
|
||||
// Response is the output of an interpreter handler.
|
||||
type Response struct {
|
||||
configv1alpha1.ResourceInterpreterResponse
|
||||
}
|
||||
Loading…
Reference in New Issue