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{}
|
||||
if err := c.Client.Get(context.TODO(), req.NamespacedName, svcImport); err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return controllerruntime.Result{}, nil
|
||||
return c.deleteDerivedService(req.NamespacedName)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
newDerivedService := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: svcImport.Namespace,
|
||||
Name: names.GenerateDerivedServiceName(svcImport.Name),
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
*metav1.NewControllerRef(svcImport, svcImport.GroupVersionKind()),
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Type: corev1.ServiceTypeClusterIP,
|
||||
|
@ -77,7 +98,7 @@ func (c *ServiceImportController) deriveServiceFromServiceImport(svcImport *mcsv
|
|||
return controllerruntime.Result{Requeue: true}, err
|
||||
}
|
||||
|
||||
return controllerruntime.Result{}, nil
|
||||
return c.updateServiceStatus(svcImport, newDerivedService)
|
||||
}
|
||||
|
||||
return controllerruntime.Result{Requeue: true}, err
|
||||
|
|
|
@ -92,10 +92,13 @@ const (
|
|||
ReplicaSetKind = "ReplicaSet"
|
||||
// StatefulSetKind indicates the target resource is a statefulset
|
||||
StatefulSetKind = "StatefulSet"
|
||||
// ServiceExportKind indicates the target resource is a serviceexport
|
||||
ServiceExportKind = "ServiceExport"
|
||||
// EndpointSliceKind indicates the target resource is a 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
|
||||
|
|
|
@ -3,10 +3,14 @@ package helper
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
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.
|
||||
|
@ -73,3 +77,46 @@ func IsDependentClusterOverridesPresent(c client.Client, policy *policyv1alpha1.
|
|||
|
||||
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))
|
||||
}
|
||||
|
||||
addedResourceSelectors := helper.GetFollowedResourceSelectorsWhenMatchServiceImport(policy.Spec.ResourceSelectors)
|
||||
if addedResourceSelectors != nil {
|
||||
policy.Spec.ResourceSelectors = append(policy.Spec.ResourceSelectors, addedResourceSelectors...)
|
||||
}
|
||||
|
||||
marshaledBytes, err := json.Marshal(policy)
|
||||
if err != nil {
|
||||
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 {
|
||||
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.
|
||||
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)
|
||||
if err != nil {
|
||||
return admission.Errored(http.StatusInternalServerError, err)
|
||||
|
|
Loading…
Reference in New Issue