Merge pull request #112895 from nokia/kep-1435-GA
KEP-1435 Mixed Protocol values in LoadBalancer Service GA
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
// ValidateConditionalService validates conditionally valid fields.
|
||||
func ValidateConditionalService(service, oldService *api.Service) field.ErrorList {
|
||||
var errs field.ErrorList
|
||||
|
||||
errs = append(errs, validateMixedProtocolLBService(service, oldService)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// validateMixedProtocolLBService checks if the old Service has type=LoadBalancer and whether the Service has different Protocols
|
||||
// on its ports. If the MixedProtocolLBService feature flag is disabled the usage of different Protocols in the new Service is
|
||||
// valid only if the old Service has different Protocols, too.
|
||||
func validateMixedProtocolLBService(service, oldService *api.Service) (errs field.ErrorList) {
|
||||
if service.Spec.Type != api.ServiceTypeLoadBalancer {
|
||||
return
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.MixedProtocolLBService) {
|
||||
return
|
||||
}
|
||||
|
||||
if serviceHasMixedProtocols(service) && !serviceHasMixedProtocols(oldService) {
|
||||
errs = append(errs, field.Invalid(field.NewPath("spec", "ports"), service.Spec.Ports, "may not contain more than 1 protocol when type is 'LoadBalancer'"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func serviceHasMixedProtocols(service *api.Service) bool {
|
||||
if service == nil {
|
||||
return false
|
||||
}
|
||||
protos := map[string]bool{}
|
||||
for _, port := range service.Spec.Ports {
|
||||
protos[string(port.Protocol)] = true
|
||||
}
|
||||
return len(protos) > 1
|
||||
}
|
@@ -1,277 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
func TestValidateMixedProtocolLBService(t *testing.T) {
|
||||
newLBServiceDifferentProtocols := &api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
},
|
||||
},
|
||||
Type: api.ServiceTypeLoadBalancer,
|
||||
},
|
||||
}
|
||||
newLBServiceSameProtocols := &api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Protocol: api.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
Type: api.ServiceTypeLoadBalancer,
|
||||
},
|
||||
}
|
||||
newNonLBServiceDifferentProtocols := &api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
},
|
||||
},
|
||||
Type: api.ServiceTypeNodePort,
|
||||
},
|
||||
}
|
||||
newNonLBServiceSameProtocols := &api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
},
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
},
|
||||
},
|
||||
Type: api.ServiceTypeNodePort,
|
||||
},
|
||||
}
|
||||
oldLBServiceDifferentProtocols := &api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
},
|
||||
},
|
||||
Type: api.ServiceTypeLoadBalancer,
|
||||
},
|
||||
}
|
||||
oldLBServiceSameProtocols := &api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Protocol: api.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
Type: api.ServiceTypeLoadBalancer,
|
||||
},
|
||||
}
|
||||
oldNonLBServiceDifferentProtocols := &api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
},
|
||||
},
|
||||
Type: api.ServiceTypeNodePort,
|
||||
},
|
||||
}
|
||||
oldNonLBServiceSameProtocols := &api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
},
|
||||
{
|
||||
Protocol: api.ProtocolUDP,
|
||||
},
|
||||
},
|
||||
Type: api.ServiceTypeNodePort,
|
||||
},
|
||||
}
|
||||
cases := map[string]struct {
|
||||
oldService *api.Service
|
||||
newService *api.Service
|
||||
fgEnabled bool
|
||||
expectedError []string
|
||||
}{
|
||||
"Old service is nil, new service has different protocols, feature gate false": {
|
||||
oldService: nil,
|
||||
newService: newLBServiceDifferentProtocols,
|
||||
fgEnabled: false,
|
||||
expectedError: []string{`spec.ports: Invalid value: []core.ServicePort{core.ServicePort{Name:"", Protocol:"TCP", AppProtocol:(*string)(nil), Port:0, TargetPort:intstr.IntOrString{Type:0, IntVal:0, StrVal:""}, NodePort:0}, core.ServicePort{Name:"", Protocol:"UDP", AppProtocol:(*string)(nil), Port:0, TargetPort:intstr.IntOrString{Type:0, IntVal:0, StrVal:""}, NodePort:0}}: may not contain more than 1 protocol when type is 'LoadBalancer'`},
|
||||
},
|
||||
"Old service is nil, new service has different protocols, feature gate true": {
|
||||
oldService: nil,
|
||||
newService: newLBServiceDifferentProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"Old service is nil, new service does not have different protocols, feature gate false": {
|
||||
oldService: nil,
|
||||
newService: newLBServiceSameProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"Old service is nil, new service does not have different protocols, feature gate true": {
|
||||
oldService: nil,
|
||||
newService: newLBServiceSameProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"Old service is nil, new non-LB service has different protocols, feature gate false": {
|
||||
oldService: nil,
|
||||
newService: newNonLBServiceDifferentProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"Old service is nil, new non-LB service has different protocols, feature gate true": {
|
||||
oldService: nil,
|
||||
newService: newNonLBServiceDifferentProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"Old service is nil, new non-LB service does not have different protocols, feature gate false": {
|
||||
oldService: nil,
|
||||
newService: newNonLBServiceSameProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"Old service is nil, new non-LB service does not have different protocols, feature gate true": {
|
||||
oldService: nil,
|
||||
newService: newNonLBServiceSameProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"Non-LB services, both services have different protocols, feature gate false": {
|
||||
oldService: oldNonLBServiceDifferentProtocols,
|
||||
newService: newNonLBServiceDifferentProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"Non-LB services, old service has same protocols, new service has different protocols, feature gate false": {
|
||||
oldService: oldNonLBServiceSameProtocols,
|
||||
newService: newNonLBServiceDifferentProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"Non-LB services, old service has different protocols, new service has identical protocols, feature gate false": {
|
||||
oldService: oldNonLBServiceDifferentProtocols,
|
||||
newService: newNonLBServiceSameProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"Non-LB services, both services have same protocols, feature gate false": {
|
||||
oldService: oldNonLBServiceSameProtocols,
|
||||
newService: newNonLBServiceSameProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"Non-LB services, both services have different protocols, feature gate true": {
|
||||
oldService: oldNonLBServiceDifferentProtocols,
|
||||
newService: newNonLBServiceDifferentProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"Non-LB services, old service has same protocols, new service has different protocols, feature gate true": {
|
||||
oldService: oldNonLBServiceSameProtocols,
|
||||
newService: newNonLBServiceDifferentProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"Non-LB services, old service has different protocols, new service has identical protocols, feature gate true": {
|
||||
oldService: oldNonLBServiceDifferentProtocols,
|
||||
newService: newNonLBServiceSameProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"Non-LB services, both services have same protocols, feature gate true": {
|
||||
oldService: oldNonLBServiceSameProtocols,
|
||||
newService: newNonLBServiceSameProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"LB service, neither service has different protocols, feature gate false": {
|
||||
oldService: oldLBServiceSameProtocols,
|
||||
newService: newLBServiceSameProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"LB service, old service does not have different protocols, new service has different protocols, feature gate false": {
|
||||
oldService: oldLBServiceSameProtocols,
|
||||
newService: newLBServiceDifferentProtocols,
|
||||
fgEnabled: false,
|
||||
expectedError: []string{`spec.ports: Invalid value: []core.ServicePort{core.ServicePort{Name:"", Protocol:"TCP", AppProtocol:(*string)(nil), Port:0, TargetPort:intstr.IntOrString{Type:0, IntVal:0, StrVal:""}, NodePort:0}, core.ServicePort{Name:"", Protocol:"UDP", AppProtocol:(*string)(nil), Port:0, TargetPort:intstr.IntOrString{Type:0, IntVal:0, StrVal:""}, NodePort:0}}: may not contain more than 1 protocol when type is 'LoadBalancer'`},
|
||||
},
|
||||
"LB service, old service has different protocols, new service does not have different protocols, feature gate false": {
|
||||
oldService: oldLBServiceDifferentProtocols,
|
||||
newService: newLBServiceSameProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"LB service, both services have different protocols, feature gate false": {
|
||||
oldService: oldLBServiceDifferentProtocols,
|
||||
newService: newLBServiceDifferentProtocols,
|
||||
fgEnabled: false,
|
||||
},
|
||||
"LB service, neither service has different protocols, feature gate true": {
|
||||
oldService: oldLBServiceSameProtocols,
|
||||
newService: newLBServiceSameProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"LB service, old service has different protocols, new service does not have different protocols, feature gate true": {
|
||||
oldService: oldLBServiceDifferentProtocols,
|
||||
newService: newLBServiceSameProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"LB service, old service does not have different protocols, new service has different protocols, feature gate true": {
|
||||
oldService: oldLBServiceSameProtocols,
|
||||
newService: newLBServiceDifferentProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
"LB service, both services have different protocols, feature gate true": {
|
||||
oldService: oldLBServiceDifferentProtocols,
|
||||
newService: newLBServiceDifferentProtocols,
|
||||
fgEnabled: true,
|
||||
},
|
||||
}
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MixedProtocolLBService, tc.fgEnabled)()
|
||||
errs := validateMixedProtocolLBService(tc.newService, tc.oldService)
|
||||
if len(errs) != len(tc.expectedError) {
|
||||
t.Fatalf("unexpected number of errors: %v", errs)
|
||||
}
|
||||
for i := range errs {
|
||||
if !strings.Contains(errs[i].Error(), tc.expectedError[i]) {
|
||||
t.Errorf("unexpected error %d: %v", i, errs[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@@ -571,6 +571,7 @@ const (
|
||||
// kep: https://kep.k8s.io/1435
|
||||
// alpha: v1.20
|
||||
// beta: v1.24
|
||||
// ga: v1.26
|
||||
//
|
||||
// Enables the usage of different protocols in the same Service with type=LoadBalancer
|
||||
MixedProtocolLBService featuregate.Feature = "MixedProtocolLBService"
|
||||
@@ -973,7 +974,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
MinimizeIPTablesRestore: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
MixedProtocolLBService: {Default: true, PreRelease: featuregate.Beta},
|
||||
MixedProtocolLBService: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||
|
||||
MultiCIDRRangeAllocator: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
|
@@ -39,12 +39,9 @@ import (
|
||||
genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
epstest "k8s.io/kubernetes/pkg/api/endpoints/testing"
|
||||
svctest "k8s.io/kubernetes/pkg/api/service/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
endpointstore "k8s.io/kubernetes/pkg/registry/core/endpoint/storage"
|
||||
podstore "k8s.io/kubernetes/pkg/registry/core/pod/storage"
|
||||
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||
@@ -6113,11 +6110,10 @@ func TestCreateDeleteReuse(t *testing.T) {
|
||||
|
||||
func TestCreateInitNodePorts(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
svc *api.Service
|
||||
expectError bool
|
||||
expectNodePorts bool
|
||||
gateMixedProtocolLBService bool
|
||||
name string
|
||||
svc *api.Service
|
||||
expectError bool
|
||||
expectNodePorts bool
|
||||
}{{
|
||||
name: "type:ExternalName",
|
||||
svc: svctest.MakeService("foo"),
|
||||
@@ -6281,66 +6277,31 @@ func TestCreateInitNodePorts(t *testing.T) {
|
||||
svctest.SetNodePorts(30080, 30080)),
|
||||
expectError: true,
|
||||
}, {
|
||||
// When the MixedProtocolLBService gate is locked, this can be removed.
|
||||
name: "type:LoadBalancer_multiport_multiproto_unspecified_MixedProtocolLBService:off",
|
||||
name: "type:LoadBalancer_multiport_multiproto_unspecified",
|
||||
svc: svctest.MakeService("foo",
|
||||
svctest.SetTypeLoadBalancer,
|
||||
svctest.SetPorts(
|
||||
svctest.MakeServicePort("p", 53, intstr.FromInt(53), api.ProtocolTCP),
|
||||
svctest.MakeServicePort("q", 53, intstr.FromInt(53), api.ProtocolUDP))),
|
||||
gateMixedProtocolLBService: false,
|
||||
expectError: true,
|
||||
expectNodePorts: true,
|
||||
}, {
|
||||
// When the MixedProtocolLBService gate is locked, this can be removed.
|
||||
name: "type:LoadBalancer_multiport_multiproto_specified_MixedProtocolLBService:off",
|
||||
name: "type:LoadBalancer_multiport_multiproto_specified",
|
||||
svc: svctest.MakeService("foo",
|
||||
svctest.SetTypeLoadBalancer,
|
||||
svctest.SetPorts(
|
||||
svctest.MakeServicePort("p", 53, intstr.FromInt(53), api.ProtocolTCP),
|
||||
svctest.MakeServicePort("q", 53, intstr.FromInt(53), api.ProtocolUDP)),
|
||||
svctest.SetUniqueNodePorts),
|
||||
gateMixedProtocolLBService: false,
|
||||
expectError: true,
|
||||
expectNodePorts: true,
|
||||
}, {
|
||||
// When the MixedProtocolLBService gate is locked, this can be removed.
|
||||
name: "type:LoadBalancer_multiport_multiproto_same_MixedProtocolLBService:off",
|
||||
name: "type:LoadBalancer_multiport_multiproto_same",
|
||||
svc: svctest.MakeService("foo",
|
||||
svctest.SetTypeLoadBalancer,
|
||||
svctest.SetPorts(
|
||||
svctest.MakeServicePort("p", 53, intstr.FromInt(53), api.ProtocolTCP),
|
||||
svctest.MakeServicePort("q", 53, intstr.FromInt(53), api.ProtocolUDP)),
|
||||
svctest.SetNodePorts(30053, 30053)),
|
||||
gateMixedProtocolLBService: false,
|
||||
expectError: true,
|
||||
}, {
|
||||
name: "type:LoadBalancer_multiport_multiproto_unspecified_MixedProtocolLBService:on",
|
||||
svc: svctest.MakeService("foo",
|
||||
svctest.SetTypeLoadBalancer,
|
||||
svctest.SetPorts(
|
||||
svctest.MakeServicePort("p", 53, intstr.FromInt(53), api.ProtocolTCP),
|
||||
svctest.MakeServicePort("q", 53, intstr.FromInt(53), api.ProtocolUDP))),
|
||||
gateMixedProtocolLBService: true,
|
||||
expectNodePorts: true,
|
||||
}, {
|
||||
name: "type:LoadBalancer_multiport_multiproto_specified_MixedProtocolLBService:on",
|
||||
svc: svctest.MakeService("foo",
|
||||
svctest.SetTypeLoadBalancer,
|
||||
svctest.SetPorts(
|
||||
svctest.MakeServicePort("p", 53, intstr.FromInt(53), api.ProtocolTCP),
|
||||
svctest.MakeServicePort("q", 53, intstr.FromInt(53), api.ProtocolUDP)),
|
||||
svctest.SetUniqueNodePorts),
|
||||
gateMixedProtocolLBService: true,
|
||||
expectNodePorts: true,
|
||||
}, {
|
||||
name: "type:LoadBalancer_multiport_multiproto_same_MixedProtocolLBService:on",
|
||||
svc: svctest.MakeService("foo",
|
||||
svctest.SetTypeLoadBalancer,
|
||||
svctest.SetPorts(
|
||||
svctest.MakeServicePort("p", 53, intstr.FromInt(53), api.ProtocolTCP),
|
||||
svctest.MakeServicePort("q", 53, intstr.FromInt(53), api.ProtocolUDP)),
|
||||
svctest.SetNodePorts(30053, 30053)),
|
||||
gateMixedProtocolLBService: true,
|
||||
expectNodePorts: true,
|
||||
expectNodePorts: true,
|
||||
}, {
|
||||
name: "type:LoadBalancer_multiport_multiproto_conflict",
|
||||
svc: svctest.MakeService("foo",
|
||||
@@ -6358,8 +6319,6 @@ func TestCreateInitNodePorts(t *testing.T) {
|
||||
defer storage.Store.DestroyFunc()
|
||||
|
||||
for _, tc := range testCases {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MixedProtocolLBService, tc.gateMixedProtocolLBService)()
|
||||
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
createdObj, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{})
|
||||
|
@@ -81,7 +81,6 @@ func (svcStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object
|
||||
func (svcStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||
service := obj.(*api.Service)
|
||||
allErrs := validation.ValidateServiceCreate(service)
|
||||
allErrs = append(allErrs, validation.ValidateConditionalService(service, nil)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@@ -98,7 +97,6 @@ func (svcStrategy) AllowCreateOnUpdate() bool {
|
||||
|
||||
func (strategy svcStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||
allErrs := validation.ValidateServiceUpdate(obj.(*api.Service), old.(*api.Service))
|
||||
allErrs = append(allErrs, validation.ValidateConditionalService(obj.(*api.Service), old.(*api.Service))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
@@ -119,17 +117,6 @@ func (svcStrategy) AllowUnconditionalUpdate() bool {
|
||||
// }
|
||||
func dropServiceDisabledFields(newSvc *api.Service, oldSvc *api.Service) {
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.MixedProtocolLBService) {
|
||||
if !serviceConditionsInUse(oldSvc) {
|
||||
newSvc.Status.Conditions = nil
|
||||
}
|
||||
if !loadBalancerPortsInUse(oldSvc) {
|
||||
for i := range newSvc.Status.LoadBalancer.Ingress {
|
||||
newSvc.Status.LoadBalancer.Ingress[i].Ports = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear InternalTrafficPolicy if not enabled
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
|
||||
if !serviceInternalTrafficPolicyInUse(oldSvc) {
|
||||
@@ -138,27 +125,6 @@ func dropServiceDisabledFields(newSvc *api.Service, oldSvc *api.Service) {
|
||||
}
|
||||
}
|
||||
|
||||
// returns true when the svc.Status.Conditions field is in use.
|
||||
func serviceConditionsInUse(svc *api.Service) bool {
|
||||
if svc == nil {
|
||||
return false
|
||||
}
|
||||
return svc.Status.Conditions != nil
|
||||
}
|
||||
|
||||
// returns true when the svc.Status.LoadBalancer.Ingress.Ports field is in use.
|
||||
func loadBalancerPortsInUse(svc *api.Service) bool {
|
||||
if svc == nil {
|
||||
return false
|
||||
}
|
||||
for _, ing := range svc.Status.LoadBalancer.Ingress {
|
||||
if ing.Ports != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func serviceInternalTrafficPolicyInUse(svc *api.Service) bool {
|
||||
if svc == nil {
|
||||
return false
|
||||
|
@@ -166,7 +166,6 @@ func TestDropDisabledField(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
enableMixedProtocol bool
|
||||
enableInternalTrafficPolicy bool
|
||||
svc *api.Service
|
||||
oldSvc *api.Service
|
||||
@@ -174,117 +173,53 @@ func TestDropDisabledField(t *testing.T) {
|
||||
}{
|
||||
/* svc.Status.Conditions */
|
||||
{
|
||||
name: "mixed protocol not enabled, field not used in old, not used in new",
|
||||
enableMixedProtocol: false,
|
||||
svc: makeServiceWithConditions(nil),
|
||||
oldSvc: makeServiceWithConditions(nil),
|
||||
compareSvc: makeServiceWithConditions(nil),
|
||||
name: "mixed protocol enabled, field not used in old, not used in new",
|
||||
svc: makeServiceWithConditions(nil),
|
||||
oldSvc: makeServiceWithConditions(nil),
|
||||
compareSvc: makeServiceWithConditions(nil),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol not enabled, field used in old and in new",
|
||||
enableMixedProtocol: false,
|
||||
svc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
oldSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
compareSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
name: "mixed protocol enabled, field used in old and in new",
|
||||
svc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
oldSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
compareSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol not enabled, field not used in old, used in new",
|
||||
enableMixedProtocol: false,
|
||||
svc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
oldSvc: makeServiceWithConditions(nil),
|
||||
compareSvc: makeServiceWithConditions(nil),
|
||||
name: "mixed protocol enabled, field not used in old, used in new",
|
||||
svc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
oldSvc: makeServiceWithConditions(nil),
|
||||
compareSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol not enabled, field used in old, not used in new",
|
||||
enableMixedProtocol: false,
|
||||
svc: makeServiceWithConditions(nil),
|
||||
oldSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
compareSvc: makeServiceWithConditions(nil),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol enabled, field not used in old, not used in new",
|
||||
enableMixedProtocol: true,
|
||||
svc: makeServiceWithConditions(nil),
|
||||
oldSvc: makeServiceWithConditions(nil),
|
||||
compareSvc: makeServiceWithConditions(nil),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol enabled, field used in old and in new",
|
||||
enableMixedProtocol: true,
|
||||
svc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
oldSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
compareSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol enabled, field not used in old, used in new",
|
||||
enableMixedProtocol: true,
|
||||
svc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
oldSvc: makeServiceWithConditions(nil),
|
||||
compareSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol enabled, field used in old, not used in new",
|
||||
enableMixedProtocol: true,
|
||||
svc: makeServiceWithConditions(nil),
|
||||
oldSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
compareSvc: makeServiceWithConditions(nil),
|
||||
name: "mixed protocol enabled, field used in old, not used in new",
|
||||
svc: makeServiceWithConditions(nil),
|
||||
oldSvc: makeServiceWithConditions([]metav1.Condition{}),
|
||||
compareSvc: makeServiceWithConditions(nil),
|
||||
},
|
||||
/* svc.Status.LoadBalancer.Ingress.Ports */
|
||||
{
|
||||
name: "mixed protocol not enabled, field not used in old, not used in new",
|
||||
enableMixedProtocol: false,
|
||||
svc: makeServiceWithPorts(nil),
|
||||
oldSvc: makeServiceWithPorts(nil),
|
||||
compareSvc: makeServiceWithPorts(nil),
|
||||
name: "mixed protocol enabled, field not used in old, not used in new",
|
||||
svc: makeServiceWithPorts(nil),
|
||||
oldSvc: makeServiceWithPorts(nil),
|
||||
compareSvc: makeServiceWithPorts(nil),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol not enabled, field used in old and in new",
|
||||
enableMixedProtocol: false,
|
||||
svc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
oldSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
compareSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
name: "mixed protocol enabled, field used in old and in new",
|
||||
svc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
oldSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
compareSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol not enabled, field not used in old, used in new",
|
||||
enableMixedProtocol: false,
|
||||
svc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
oldSvc: makeServiceWithPorts(nil),
|
||||
compareSvc: makeServiceWithPorts(nil),
|
||||
name: "mixed protocol enabled, field not used in old, used in new",
|
||||
svc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
oldSvc: makeServiceWithPorts(nil),
|
||||
compareSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol not enabled, field used in old, not used in new",
|
||||
enableMixedProtocol: false,
|
||||
svc: makeServiceWithPorts(nil),
|
||||
oldSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
compareSvc: makeServiceWithPorts(nil),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol enabled, field not used in old, not used in new",
|
||||
enableMixedProtocol: true,
|
||||
svc: makeServiceWithPorts(nil),
|
||||
oldSvc: makeServiceWithPorts(nil),
|
||||
compareSvc: makeServiceWithPorts(nil),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol enabled, field used in old and in new",
|
||||
enableMixedProtocol: true,
|
||||
svc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
oldSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
compareSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol enabled, field not used in old, used in new",
|
||||
enableMixedProtocol: true,
|
||||
svc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
oldSvc: makeServiceWithPorts(nil),
|
||||
compareSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
},
|
||||
{
|
||||
name: "mixed protocol enabled, field used in old, not used in new",
|
||||
enableMixedProtocol: true,
|
||||
svc: makeServiceWithPorts(nil),
|
||||
oldSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
compareSvc: makeServiceWithPorts(nil),
|
||||
name: "mixed protocol enabled, field used in old, not used in new",
|
||||
svc: makeServiceWithPorts(nil),
|
||||
oldSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||
compareSvc: makeServiceWithPorts(nil),
|
||||
},
|
||||
/* svc.spec.internalTrafficPolicy */
|
||||
{
|
||||
@@ -312,7 +247,6 @@ func TestDropDisabledField(t *testing.T) {
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
func() {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MixedProtocolLBService, tc.enableMixedProtocol)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, tc.enableInternalTrafficPolicy)()
|
||||
old := tc.oldSvc.DeepCopy()
|
||||
|
||||
|
Reference in New Issue
Block a user