feat: prevent updates to mcs.types or when multiple types are involved.
Signed-off-by: jwcesign <jwcesign@gmail.com>
This commit is contained in:
parent
33c98a4e44
commit
dc4338398a
|
@ -19,6 +19,7 @@ package multiclusterservice
|
|||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
|
@ -73,11 +74,21 @@ func (v *ValidatingAdmission) Handle(ctx context.Context, req admission.Request)
|
|||
|
||||
func (v *ValidatingAdmission) validateMCSUpdate(oldMcs, newMcs *networkingv1alpha1.MultiClusterService) field.ErrorList {
|
||||
allErrs := apimachineryvalidation.ValidateObjectMetaUpdate(&newMcs.ObjectMeta, &oldMcs.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, v.validateMCSTypesUpdate(oldMcs, newMcs)...)
|
||||
allErrs = append(allErrs, v.validateMCS(newMcs)...)
|
||||
allErrs = append(allErrs, lifted.ValidateLoadBalancerStatus(&newMcs.Status.LoadBalancer, field.NewPath("status", "loadBalancer"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func (v *ValidatingAdmission) validateMCSTypesUpdate(oldMcs, newMcs *networkingv1alpha1.MultiClusterService) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if !reflect.DeepEqual(oldMcs.Spec.Types, newMcs.Spec.Types) {
|
||||
typePath := field.NewPath("spec").Child("types")
|
||||
allErrs = append(allErrs, field.Invalid(typePath, oldMcs.Spec.Types, "MultiClusterService types are immutable"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func (v *ValidatingAdmission) validateMCS(mcs *networkingv1alpha1.MultiClusterService) field.ErrorList {
|
||||
allErrs := apimachineryvalidation.ValidateObjectMeta(&mcs.ObjectMeta, true,
|
||||
apimachineryvalidation.NameIsDNS1035Label, field.NewPath("metadata"))
|
||||
|
@ -97,12 +108,19 @@ func (v *ValidatingAdmission) validateMultiClusterServiceSpec(mcs *networkingv1a
|
|||
port := mcs.Spec.Ports[i]
|
||||
allErrs = append(allErrs, v.validateExposurePort(&port, allPortNames, portPath)...)
|
||||
}
|
||||
|
||||
typesSet := sets.Set[string]{}
|
||||
typesPath := specPath.Child("types")
|
||||
for i := range mcs.Spec.Types {
|
||||
typePath := typesPath.Index(i)
|
||||
exposureType := mcs.Spec.Types[i]
|
||||
typesSet.Insert(string(exposureType))
|
||||
allErrs = append(allErrs, v.validateExposureType(&exposureType, typePath)...)
|
||||
}
|
||||
if len(typesSet) > 1 {
|
||||
allErrs = append(allErrs, field.Invalid(typesPath, mcs.Spec.Types, "MultiClusterService types should not contain more than one type"))
|
||||
}
|
||||
|
||||
clusterNamesPath := specPath.Child("range").Child("providerClusters")
|
||||
for i := range mcs.Spec.ProviderClusters {
|
||||
clusterNamePath := clusterNamesPath.Index(i)
|
||||
|
|
|
@ -51,7 +51,6 @@ func TestValidateMultiClusterServiceSpec(t *testing.T) {
|
|||
},
|
||||
Types: []networkingv1alpha1.ExposureType{
|
||||
networkingv1alpha1.ExposureTypeLoadBalancer,
|
||||
networkingv1alpha1.ExposureTypeCrossCluster,
|
||||
},
|
||||
ProviderClusters: []networkingv1alpha1.ClusterSelector{
|
||||
{Name: "member1"},
|
||||
|
@ -65,6 +64,39 @@ func TestValidateMultiClusterServiceSpec(t *testing.T) {
|
|||
},
|
||||
expectedErr: field.ErrorList{},
|
||||
},
|
||||
{
|
||||
name: "multiple exposure type mcs",
|
||||
mcs: &networkingv1alpha1.MultiClusterService{
|
||||
Spec: networkingv1alpha1.MultiClusterServiceSpec{
|
||||
Ports: []networkingv1alpha1.ExposurePort{
|
||||
{
|
||||
Name: "foo",
|
||||
Port: 16312,
|
||||
},
|
||||
{
|
||||
Name: "bar",
|
||||
Port: 16313,
|
||||
},
|
||||
},
|
||||
Types: []networkingv1alpha1.ExposureType{
|
||||
networkingv1alpha1.ExposureTypeLoadBalancer,
|
||||
networkingv1alpha1.ExposureTypeCrossCluster,
|
||||
},
|
||||
ProviderClusters: []networkingv1alpha1.ClusterSelector{
|
||||
{Name: "member1"},
|
||||
{Name: "member2"},
|
||||
},
|
||||
ConsumerClusters: []networkingv1alpha1.ClusterSelector{
|
||||
{Name: "member1"},
|
||||
{Name: "member2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: field.ErrorList{field.Invalid(specFld.Child("types"), []networkingv1alpha1.ExposureType{
|
||||
networkingv1alpha1.ExposureTypeLoadBalancer,
|
||||
networkingv1alpha1.ExposureTypeCrossCluster,
|
||||
}, "MultiClusterService types should not contain more than one type")},
|
||||
},
|
||||
{
|
||||
name: "duplicated svc name",
|
||||
mcs: &networkingv1alpha1.MultiClusterService{
|
||||
|
|
Loading…
Reference in New Issue