Merge pull request #508 from XiShanYongYe-Chang/webhook
Mutate policy's ResourceSelectors in webhook
This commit is contained in:
commit
1f8c6a9bba
|
@ -32,7 +32,7 @@ func (c *ServiceImportController) Reconcile(ctx context.Context, req controllerr
|
||||||
svcImport := &mcsv1alpha1.ServiceImport{}
|
svcImport := &mcsv1alpha1.ServiceImport{}
|
||||||
if err := c.Client.Get(context.TODO(), req.NamespacedName, svcImport); err != nil {
|
if err := c.Client.Get(context.TODO(), req.NamespacedName, svcImport); err != nil {
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
return controllerruntime.Result{}, nil
|
return c.deleteDerivedService(req.NamespacedName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return controllerruntime.Result{Requeue: true}, err
|
return controllerruntime.Result{Requeue: true}, err
|
||||||
|
@ -50,14 +50,35 @@ func (c *ServiceImportController) SetupWithManager(mgr controllerruntime.Manager
|
||||||
return controllerruntime.NewControllerManagedBy(mgr).For(&mcsv1alpha1.ServiceImport{}).Complete(c)
|
return controllerruntime.NewControllerManagedBy(mgr).For(&mcsv1alpha1.ServiceImport{}).Complete(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ServiceImportController) deleteDerivedService(svcImport types.NamespacedName) (controllerruntime.Result, error) {
|
||||||
|
derivedSvc := &corev1.Service{}
|
||||||
|
derivedSvcNamespacedName := types.NamespacedName{
|
||||||
|
Namespace: svcImport.Namespace,
|
||||||
|
Name: names.GenerateDerivedServiceName(svcImport.Name),
|
||||||
|
}
|
||||||
|
err := c.Client.Get(context.TODO(), derivedSvcNamespacedName, derivedSvc)
|
||||||
|
if err != nil {
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
return controllerruntime.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return controllerruntime.Result{Requeue: true}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.Client.Delete(context.TODO(), derivedSvc)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Delete derived service(%s) failed, Error: %v", derivedSvcNamespacedName, err)
|
||||||
|
return controllerruntime.Result{Requeue: true}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return controllerruntime.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *ServiceImportController) deriveServiceFromServiceImport(svcImport *mcsv1alpha1.ServiceImport) (controllerruntime.Result, error) {
|
func (c *ServiceImportController) deriveServiceFromServiceImport(svcImport *mcsv1alpha1.ServiceImport) (controllerruntime.Result, error) {
|
||||||
newDerivedService := &corev1.Service{
|
newDerivedService := &corev1.Service{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Namespace: svcImport.Namespace,
|
Namespace: svcImport.Namespace,
|
||||||
Name: names.GenerateDerivedServiceName(svcImport.Name),
|
Name: names.GenerateDerivedServiceName(svcImport.Name),
|
||||||
OwnerReferences: []metav1.OwnerReference{
|
|
||||||
*metav1.NewControllerRef(svcImport, svcImport.GroupVersionKind()),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Spec: corev1.ServiceSpec{
|
Spec: corev1.ServiceSpec{
|
||||||
Type: corev1.ServiceTypeClusterIP,
|
Type: corev1.ServiceTypeClusterIP,
|
||||||
|
@ -77,7 +98,7 @@ func (c *ServiceImportController) deriveServiceFromServiceImport(svcImport *mcsv
|
||||||
return controllerruntime.Result{Requeue: true}, err
|
return controllerruntime.Result{Requeue: true}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return controllerruntime.Result{}, nil
|
return c.updateServiceStatus(svcImport, newDerivedService)
|
||||||
}
|
}
|
||||||
|
|
||||||
return controllerruntime.Result{Requeue: true}, err
|
return controllerruntime.Result{Requeue: true}, err
|
||||||
|
|
|
@ -92,10 +92,13 @@ const (
|
||||||
ReplicaSetKind = "ReplicaSet"
|
ReplicaSetKind = "ReplicaSet"
|
||||||
// StatefulSetKind indicates the target resource is a statefulset
|
// StatefulSetKind indicates the target resource is a statefulset
|
||||||
StatefulSetKind = "StatefulSet"
|
StatefulSetKind = "StatefulSet"
|
||||||
// ServiceExportKind indicates the target resource is a serviceexport
|
|
||||||
ServiceExportKind = "ServiceExport"
|
|
||||||
// EndpointSliceKind indicates the target resource is a endpointslice
|
// EndpointSliceKind indicates the target resource is a endpointslice
|
||||||
EndpointSliceKind = "EndpointSlice"
|
EndpointSliceKind = "EndpointSlice"
|
||||||
|
|
||||||
|
// ServiceExportKind indicates the target resource is a serviceexport crd
|
||||||
|
ServiceExportKind = "ServiceExport"
|
||||||
|
// ServiceImportKind indicates the target resource is a serviceimport crd
|
||||||
|
ServiceImportKind = "ServiceImport"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Define resource filed
|
// Define resource filed
|
||||||
|
|
|
@ -3,10 +3,14 @@ package helper
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||||
|
"github.com/karmada-io/karmada/pkg/util"
|
||||||
|
"github.com/karmada-io/karmada/pkg/util/names"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DenyReasonResourceSelectorsModify constructs a reason indicating that modify ResourceSelectors is not allowed.
|
// DenyReasonResourceSelectorsModify constructs a reason indicating that modify ResourceSelectors is not allowed.
|
||||||
|
@ -73,3 +77,46 @@ func IsDependentClusterOverridesPresent(c client.Client, policy *policyv1alpha1.
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFollowedResourceSelectorsWhenMatchServiceImport get followed derived-service and endpointSlices resource selectors
|
||||||
|
// when policy's ResourceSelectors contains ResourceSelector, whose kind is ServiceImport.
|
||||||
|
func GetFollowedResourceSelectorsWhenMatchServiceImport(resourceSelectors []policyv1alpha1.ResourceSelector) []policyv1alpha1.ResourceSelector {
|
||||||
|
var addedResourceSelectors []policyv1alpha1.ResourceSelector
|
||||||
|
|
||||||
|
for _, resourceSelector := range resourceSelectors {
|
||||||
|
if resourceSelector.Kind != util.ServiceImportKind {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if resourceSelector.Namespace == "" || resourceSelector.Name == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
addedResourceSelectors = append(addedResourceSelectors, GenerateResourceSelectorForServiceImport(resourceSelector)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return addedResourceSelectors
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateResourceSelectorForServiceImport generates resource selectors for ServiceImport.
|
||||||
|
func GenerateResourceSelectorForServiceImport(svcImport policyv1alpha1.ResourceSelector) []policyv1alpha1.ResourceSelector {
|
||||||
|
derivedServiceName := names.GenerateDerivedServiceName(svcImport.Name)
|
||||||
|
return []policyv1alpha1.ResourceSelector{
|
||||||
|
{
|
||||||
|
APIVersion: "v1",
|
||||||
|
Kind: util.ServiceKind,
|
||||||
|
Namespace: svcImport.Namespace,
|
||||||
|
Name: derivedServiceName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
APIVersion: "discovery.k8s.io/v1beta1",
|
||||||
|
Kind: util.EndpointSliceKind,
|
||||||
|
Namespace: svcImport.Namespace,
|
||||||
|
LabelSelector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
discoveryv1beta1.LabelServiceName: derivedServiceName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,11 @@ func (a *MutatingAdmission) Handle(ctx context.Context, req admission.Request) a
|
||||||
return admission.Errored(http.StatusBadRequest, fmt.Errorf("ClusterPropagationPolicy's name should be no more than %d characters", validation.LabelValueMaxLength))
|
return admission.Errored(http.StatusBadRequest, fmt.Errorf("ClusterPropagationPolicy's name should be no more than %d characters", validation.LabelValueMaxLength))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addedResourceSelectors := helper.GetFollowedResourceSelectorsWhenMatchServiceImport(policy.Spec.ResourceSelectors)
|
||||||
|
if addedResourceSelectors != nil {
|
||||||
|
policy.Spec.ResourceSelectors = append(policy.Spec.ResourceSelectors, addedResourceSelectors...)
|
||||||
|
}
|
||||||
|
|
||||||
marshaledBytes, err := json.Marshal(policy)
|
marshaledBytes, err := json.Marshal(policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return admission.Errored(http.StatusInternalServerError, err)
|
return admission.Errored(http.StatusInternalServerError, err)
|
||||||
|
|
|
@ -41,11 +41,16 @@ func (a *MutatingAdmission) Handle(ctx context.Context, req admission.Request) a
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(policy.Name) > validation.LabelValueMaxLength {
|
if len(policy.Name) > validation.LabelValueMaxLength {
|
||||||
return admission.Errored(http.StatusBadRequest, fmt.Errorf("PropagationPolicy's name and should be no more than %d characters", validation.LabelValueMaxLength))
|
return admission.Errored(http.StatusBadRequest, fmt.Errorf("PropagationPolicy's name should be no more than %d characters", validation.LabelValueMaxLength))
|
||||||
}
|
}
|
||||||
// Set default spread constraints if both 'SpreadByField' and 'SpreadByLabel' not set.
|
// Set default spread constraints if both 'SpreadByField' and 'SpreadByLabel' not set.
|
||||||
helper.SetDefaultSpreadConstraints(policy.Spec.Placement.SpreadConstraints)
|
helper.SetDefaultSpreadConstraints(policy.Spec.Placement.SpreadConstraints)
|
||||||
|
|
||||||
|
addedResourceSelectors := helper.GetFollowedResourceSelectorsWhenMatchServiceImport(policy.Spec.ResourceSelectors)
|
||||||
|
if addedResourceSelectors != nil {
|
||||||
|
policy.Spec.ResourceSelectors = append(policy.Spec.ResourceSelectors, addedResourceSelectors...)
|
||||||
|
}
|
||||||
|
|
||||||
marshaledBytes, err := json.Marshal(policy)
|
marshaledBytes, err := json.Marshal(policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return admission.Errored(http.StatusInternalServerError, err)
|
return admission.Errored(http.StatusInternalServerError, err)
|
||||||
|
|
Loading…
Reference in New Issue