From b044fadf66da7b5c940da417f5d4c527e7d03c2d Mon Sep 17 00:00:00 2001 From: Rob Scott Date: Fri, 6 Nov 2020 17:46:32 -0800 Subject: [PATCH] Graduating AppProtocol to GA --- pkg/apis/core/types.go | 4 - pkg/apis/core/validation/validation.go | 67 +++-------- pkg/apis/core/validation/validation_test.go | 110 +++++------------- .../endpoint/endpoints_controller.go | 10 +- .../endpoint/endpoints_controller_test.go | 19 +-- pkg/features/kube_features.go | 3 +- 6 files changed, 51 insertions(+), 162 deletions(-) diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go index afa9b06a7e4..f6ce7fb2761 100644 --- a/pkg/apis/core/types.go +++ b/pkg/apis/core/types.go @@ -3736,8 +3736,6 @@ type ServicePort struct { // RFC-6335 and http://www.iana.org/assignments/service-names). // Non-standard protocols should use prefixed names such as // mycompany.com/my-custom-protocol. - // This is a beta field that is guarded by the ServiceAppProtocol feature - // gate and enabled by default. // +optional AppProtocol *string @@ -3888,8 +3886,6 @@ type EndpointPort struct { // RFC-6335 and http://www.iana.org/assignments/service-names). // Non-standard protocols should use prefixed names such as // mycompany.com/my-custom-protocol. - // This is a beta field that is guarded by the ServiceAppProtocol feature - // gate and enabled by default. // +optional AppProtocol *string } diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index 930185b9084..dce65decac5 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -4143,7 +4143,7 @@ var supportedServiceIPFamily = sets.NewString(string(core.IPv4Protocol), string( var supportedServiceIPFamilyPolicy = sets.NewString(string(core.IPFamilyPolicySingleStack), string(core.IPFamilyPolicyPreferDualStack), string(core.IPFamilyPolicyRequireDualStack)) // ValidateService tests if required fields/annotations of a Service are valid. -func ValidateService(service *core.Service, allowAppProtocol bool) field.ErrorList { +func ValidateService(service *core.Service) field.ErrorList { allErrs := ValidateObjectMeta(&service.ObjectMeta, true, ValidateServiceName, field.NewPath("metadata")) specPath := field.NewPath("spec") @@ -4197,7 +4197,7 @@ func ValidateService(service *core.Service, allowAppProtocol bool) field.ErrorLi portsPath := specPath.Child("ports") for i := range service.Spec.Ports { portPath := portsPath.Index(i) - allErrs = append(allErrs, validateServicePort(&service.Spec.Ports[i], len(service.Spec.Ports) > 1, isHeadlessService(service), allowAppProtocol, &allPortNames, portPath)...) + allErrs = append(allErrs, validateServicePort(&service.Spec.Ports[i], len(service.Spec.Ports) > 1, isHeadlessService(service), &allPortNames, portPath)...) } if service.Spec.Selector != nil { @@ -4352,7 +4352,7 @@ func ValidateService(service *core.Service, allowAppProtocol bool) field.ErrorLi return allErrs } -func validateServicePort(sp *core.ServicePort, requireName, isHeadlessService, allowAppProtocol bool, allNames *sets.String, fldPath *field.Path) field.ErrorList { +func validateServicePort(sp *core.ServicePort, requireName, isHeadlessService bool, allNames *sets.String, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if requireName && len(sp.Name) == 0 { @@ -4379,12 +4379,8 @@ func validateServicePort(sp *core.ServicePort, requireName, isHeadlessService, a allErrs = append(allErrs, ValidatePortNumOrName(sp.TargetPort, fldPath.Child("targetPort"))...) if sp.AppProtocol != nil { - if allowAppProtocol { - for _, msg := range validation.IsQualifiedName(*sp.AppProtocol) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("appProtocol"), sp.AppProtocol, msg)) - } - } else { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("appProtocol"), "This field can be enabled with the ServiceAppProtocol feature gate")) + for _, msg := range validation.IsQualifiedName(*sp.AppProtocol) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("appProtocol"), sp.AppProtocol, msg)) } } @@ -4446,10 +4442,7 @@ func ValidateServiceExternalTrafficFieldsCombination(service *core.Service) fiel // ValidateServiceCreate validates Services as they are created. func ValidateServiceCreate(service *core.Service) field.ErrorList { - // allow AppProtocol value if the feature gate is set. - allowAppProtocol := utilfeature.DefaultFeatureGate.Enabled(features.ServiceAppProtocol) - - return ValidateService(service, allowAppProtocol) + return ValidateService(service) } // ValidateServiceUpdate tests if required fields in the service are set during an update @@ -4467,19 +4460,7 @@ func ValidateServiceUpdate(service, oldService *core.Service) field.ErrorList { upgradeDowngradeIPFamiliesErrs := validateUpgradeDowngradeIPFamilies(oldService, service) allErrs = append(allErrs, upgradeDowngradeIPFamiliesErrs...) - // allow AppProtocol value if the feature gate is set or the field is - // already set on the resource. - allowAppProtocol := utilfeature.DefaultFeatureGate.Enabled(features.ServiceAppProtocol) - if !allowAppProtocol { - for _, port := range oldService.Spec.Ports { - if port.AppProtocol != nil { - allowAppProtocol = true - break - } - } - } - - return append(allErrs, ValidateService(service, allowAppProtocol)...) + return append(allErrs, ValidateService(service)...) } // ValidateServiceStatusUpdate tests if required fields in the Service are set when updating status. @@ -5657,17 +5638,16 @@ func ValidateNamespaceFinalizeUpdate(newNamespace, oldNamespace *core.Namespace) } // ValidateEndpoints validates Endpoints on create and update. -func ValidateEndpoints(endpoints *core.Endpoints, allowAppProtocol bool) field.ErrorList { +func ValidateEndpoints(endpoints *core.Endpoints) field.ErrorList { allErrs := ValidateObjectMeta(&endpoints.ObjectMeta, true, ValidateEndpointsName, field.NewPath("metadata")) allErrs = append(allErrs, ValidateEndpointsSpecificAnnotations(endpoints.Annotations, field.NewPath("annotations"))...) - allErrs = append(allErrs, validateEndpointSubsets(endpoints.Subsets, allowAppProtocol, field.NewPath("subsets"))...) + allErrs = append(allErrs, validateEndpointSubsets(endpoints.Subsets, field.NewPath("subsets"))...) return allErrs } // ValidateEndpointsCreate validates Endpoints on create. func ValidateEndpointsCreate(endpoints *core.Endpoints) field.ErrorList { - allowAppProtocol := utilfeature.DefaultFeatureGate.Enabled(features.ServiceAppProtocol) - return ValidateEndpoints(endpoints, allowAppProtocol) + return ValidateEndpoints(endpoints) } // ValidateEndpointsUpdate validates Endpoints on update. NodeName changes are @@ -5676,22 +5656,11 @@ func ValidateEndpointsCreate(endpoints *core.Endpoints) field.ErrorList { // happens. func ValidateEndpointsUpdate(newEndpoints, oldEndpoints *core.Endpoints) field.ErrorList { allErrs := ValidateObjectMetaUpdate(&newEndpoints.ObjectMeta, &oldEndpoints.ObjectMeta, field.NewPath("metadata")) - allowAppProtocol := utilfeature.DefaultFeatureGate.Enabled(features.ServiceAppProtocol) - if !allowAppProtocol { - for _, oldSubset := range oldEndpoints.Subsets { - for _, port := range oldSubset.Ports { - if port.AppProtocol != nil { - allowAppProtocol = true - break - } - } - } - } - allErrs = append(allErrs, ValidateEndpoints(newEndpoints, allowAppProtocol)...) + allErrs = append(allErrs, ValidateEndpoints(newEndpoints)...) return allErrs } -func validateEndpointSubsets(subsets []core.EndpointSubset, allowAppProtocol bool, fldPath *field.Path) field.ErrorList { +func validateEndpointSubsets(subsets []core.EndpointSubset, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} for i := range subsets { ss := &subsets[i] @@ -5709,7 +5678,7 @@ func validateEndpointSubsets(subsets []core.EndpointSubset, allowAppProtocol boo allErrs = append(allErrs, validateEndpointAddress(&ss.NotReadyAddresses[addr], idxPath.Child("notReadyAddresses").Index(addr))...) } for port := range ss.Ports { - allErrs = append(allErrs, validateEndpointPort(&ss.Ports[port], len(ss.Ports) > 1, allowAppProtocol, idxPath.Child("ports").Index(port))...) + allErrs = append(allErrs, validateEndpointPort(&ss.Ports[port], len(ss.Ports) > 1, idxPath.Child("ports").Index(port))...) } } @@ -5760,7 +5729,7 @@ func validateNonSpecialIP(ipAddress string, fldPath *field.Path) field.ErrorList return allErrs } -func validateEndpointPort(port *core.EndpointPort, requireName, allowAppProtocol bool, fldPath *field.Path) field.ErrorList { +func validateEndpointPort(port *core.EndpointPort, requireName bool, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if requireName && len(port.Name) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) @@ -5776,12 +5745,8 @@ func validateEndpointPort(port *core.EndpointPort, requireName, allowAppProtocol allErrs = append(allErrs, field.NotSupported(fldPath.Child("protocol"), port.Protocol, supportedPortProtocols.List())) } if port.AppProtocol != nil { - if allowAppProtocol { - for _, msg := range validation.IsQualifiedName(*port.AppProtocol) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("appProtocol"), port.AppProtocol, msg)) - } - } else { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("appProtocol"), "This field can be enabled with the ServiceAppProtocol feature gate")) + for _, msg := range validation.IsQualifiedName(*port.AppProtocol) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("appProtocol"), port.AppProtocol, msg)) } } return allErrs diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index 7f73d3f6877..919594e1dd7 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -9898,10 +9898,9 @@ func TestValidateServiceCreate(t *testing.T) { preferDualStack := core.IPFamilyPolicyPreferDualStack testCases := []struct { - name string - tweakSvc func(svc *core.Service) // given a basic valid service, each test case can customize it - numErrs int - appProtocolEnabled bool + name string + tweakSvc func(svc *core.Service) // given a basic valid service, each test case can customize it + numErrs int }{ { name: "missing namespace", @@ -11008,8 +11007,7 @@ func TestValidateServiceCreate(t *testing.T) { AppProtocol: utilpointer.StringPtr("HTTP"), }} }, - appProtocolEnabled: true, - numErrs: 0, + numErrs: 0, }, { name: `valid custom appProtocol`, @@ -11021,8 +11019,7 @@ func TestValidateServiceCreate(t *testing.T) { AppProtocol: utilpointer.StringPtr("example.com/protocol"), }} }, - appProtocolEnabled: true, - numErrs: 0, + numErrs: 0, }, { name: `invalid appProtocol`, @@ -11034,8 +11031,7 @@ func TestValidateServiceCreate(t *testing.T) { AppProtocol: utilpointer.StringPtr("example.com/protocol_with{invalid}[characters]"), }} }, - appProtocolEnabled: true, - numErrs: 1, + numErrs: 1, }, { @@ -11059,8 +11055,6 @@ func TestValidateServiceCreate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceAppProtocol, true)() - svc := makeValidService() tc.tweakSvc(&svc) errs := ValidateServiceCreate(&svc) @@ -12624,10 +12618,9 @@ func TestValidateServiceUpdate(t *testing.T) { preferDualStack := core.IPFamilyPolicyPreferDualStack singleStack := core.IPFamilyPolicySingleStack testCases := []struct { - name string - tweakSvc func(oldSvc, newSvc *core.Service) // given basic valid services, each test case can customize them - numErrs int - appProtocolEnabled bool + name string + tweakSvc func(oldSvc, newSvc *core.Service) // given basic valid services, each test case can customize them + numErrs int }{ { name: "no change", @@ -13496,47 +13489,26 @@ func TestValidateServiceUpdate(t *testing.T) { }, numErrs: 1, }, - { - name: "update with valid app protocol, field unset, gate disabled", + name: "update to valid app protocol", tweakSvc: func(oldSvc, newSvc *core.Service) { oldSvc.Spec.Ports = []core.ServicePort{{Name: "a", Port: 443, TargetPort: intstr.FromInt(3000), Protocol: "TCP"}} newSvc.Spec.Ports = []core.ServicePort{{Name: "a", Port: 443, TargetPort: intstr.FromInt(3000), Protocol: "TCP", AppProtocol: utilpointer.StringPtr("https")}} }, - numErrs: 1, - }, - { - name: "update to valid app protocol, field set, gate disabled", - tweakSvc: func(oldSvc, newSvc *core.Service) { - oldSvc.Spec.Ports = []core.ServicePort{{Name: "a", Port: 443, TargetPort: intstr.FromInt(3000), Protocol: "TCP", AppProtocol: utilpointer.StringPtr("http")}} - newSvc.Spec.Ports = []core.ServicePort{{Name: "a", Port: 443, TargetPort: intstr.FromInt(3000), Protocol: "TCP", AppProtocol: utilpointer.StringPtr("https")}} - }, numErrs: 0, }, { - name: "update to valid app protocol, gate enabled", - tweakSvc: func(oldSvc, newSvc *core.Service) { - oldSvc.Spec.Ports = []core.ServicePort{{Name: "a", Port: 443, TargetPort: intstr.FromInt(3000), Protocol: "TCP"}} - newSvc.Spec.Ports = []core.ServicePort{{Name: "a", Port: 443, TargetPort: intstr.FromInt(3000), Protocol: "TCP", AppProtocol: utilpointer.StringPtr("https")}} - }, - appProtocolEnabled: true, - numErrs: 0, - }, - { - name: "update to invalid app protocol, gate enabled", + name: "update to invalid app protocol", tweakSvc: func(oldSvc, newSvc *core.Service) { oldSvc.Spec.Ports = []core.ServicePort{{Name: "a", Port: 443, TargetPort: intstr.FromInt(3000), Protocol: "TCP"}} newSvc.Spec.Ports = []core.ServicePort{{Name: "a", Port: 443, TargetPort: intstr.FromInt(3000), Protocol: "TCP", AppProtocol: utilpointer.StringPtr("~https")}} }, - appProtocolEnabled: true, - numErrs: 1, + numErrs: 1, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceAppProtocol, tc.appProtocolEnabled)() - oldSvc := makeValidService() newSvc := makeValidService() tc.tweakSvc(&oldSvc, &newSvc) @@ -14833,8 +14805,7 @@ func TestValidateSSHAuthSecret(t *testing.T) { func TestValidateEndpointsCreate(t *testing.T) { successCases := map[string]struct { - endpoints core.Endpoints - appProtocolEnabled bool + endpoints core.Endpoints }{ "simple endpoint": { endpoints: core.Endpoints{ @@ -14877,7 +14848,6 @@ func TestValidateEndpointsCreate(t *testing.T) { }, }, }, - appProtocolEnabled: true, }, "empty ports": { endpoints: core.Endpoints{ @@ -14893,7 +14863,6 @@ func TestValidateEndpointsCreate(t *testing.T) { for name, tc := range successCases { t.Run(name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceAppProtocol, tc.appProtocolEnabled)() errs := ValidateEndpointsCreate(&tc.endpoints) if len(errs) != 0 { t.Errorf("Expected no validation errors, got %v", errs) @@ -14903,10 +14872,9 @@ func TestValidateEndpointsCreate(t *testing.T) { } errorCases := map[string]struct { - endpoints core.Endpoints - appProtocolEnabled bool - errorType field.ErrorType - errorDetail string + endpoints core.Endpoints + errorType field.ErrorType + errorDetail string }{ "missing namespace": { endpoints: core.Endpoints{ObjectMeta: metav1.ObjectMeta{Name: "mysvc"}}, @@ -15074,15 +15042,13 @@ func TestValidateEndpointsCreate(t *testing.T) { }, }, }, - appProtocolEnabled: true, - errorType: "FieldValueInvalid", - errorDetail: "name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character", + errorType: "FieldValueInvalid", + errorDetail: "name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character", }, } for k, v := range errorCases { t.Run(k, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceAppProtocol, v.appProtocolEnabled)() if errs := ValidateEndpointsCreate(&v.endpoints); len(errs) == 0 || errs[0].Type != v.errorType || !strings.Contains(errs[0].Detail, v.errorDetail) { t.Errorf("Expected error type %s with detail %q, got %v", v.errorType, v.errorDetail, errs) } @@ -15099,54 +15065,32 @@ func TestValidateEndpointsUpdate(t *testing.T) { } testCases := map[string]struct { - tweakOldEndpoints func(ep *core.Endpoints) - tweakNewEndpoints func(ep *core.Endpoints) - appProtocolEnabled bool - numExpectedErrors int + tweakOldEndpoints func(ep *core.Endpoints) + tweakNewEndpoints func(ep *core.Endpoints) + numExpectedErrors int }{ - "update with valid app protocol, field unset, gate not enabled": { + "update to valid app protocol": { tweakOldEndpoints: func(ep *core.Endpoints) { ep.Subsets[0].Ports = []core.EndpointPort{{Name: "a", Port: 8675, Protocol: "TCP"}} }, tweakNewEndpoints: func(ep *core.Endpoints) { ep.Subsets[0].Ports = []core.EndpointPort{{Name: "a", Port: 8675, Protocol: "TCP", AppProtocol: utilpointer.StringPtr("https")}} }, - numExpectedErrors: 1, - }, - "update with valid app protocol, field set, gate not enabled": { - tweakOldEndpoints: func(ep *core.Endpoints) { - ep.Subsets[0].Ports = []core.EndpointPort{{Name: "a", Port: 8675, Protocol: "TCP", AppProtocol: utilpointer.StringPtr("http")}} - }, - tweakNewEndpoints: func(ep *core.Endpoints) { - ep.Subsets[0].Ports = []core.EndpointPort{{Name: "a", Port: 8675, Protocol: "TCP", AppProtocol: utilpointer.StringPtr("https")}} - }, numExpectedErrors: 0, }, - "update to valid app protocol, gate enabled": { - tweakOldEndpoints: func(ep *core.Endpoints) { - ep.Subsets[0].Ports = []core.EndpointPort{{Name: "a", Port: 8675, Protocol: "TCP"}} - }, - tweakNewEndpoints: func(ep *core.Endpoints) { - ep.Subsets[0].Ports = []core.EndpointPort{{Name: "a", Port: 8675, Protocol: "TCP", AppProtocol: utilpointer.StringPtr("https")}} - }, - appProtocolEnabled: true, - numExpectedErrors: 0, - }, - "update to invalid app protocol, gate enabled": { + "update to invalid app protocol": { tweakOldEndpoints: func(ep *core.Endpoints) { ep.Subsets[0].Ports = []core.EndpointPort{{Name: "a", Port: 8675, Protocol: "TCP"}} }, tweakNewEndpoints: func(ep *core.Endpoints) { ep.Subsets[0].Ports = []core.EndpointPort{{Name: "a", Port: 8675, Protocol: "TCP", AppProtocol: utilpointer.StringPtr("~https")}} }, - appProtocolEnabled: true, - numExpectedErrors: 1, + numExpectedErrors: 1, }, } for name, tc := range testCases { t.Run(name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceAppProtocol, tc.appProtocolEnabled)() oldEndpoints := baseEndpoints.DeepCopy() tc.tweakOldEndpoints(oldEndpoints) newEndpoints := baseEndpoints.DeepCopy() @@ -15696,7 +15640,7 @@ func TestEndpointAddressNodeNameUpdateRestrictions(t *testing.T) { updatedEndpoint := newNodeNameEndpoint("kubernetes-changed-nodename") // Check that NodeName can be changed during update, this is to accommodate the case where nodeIP or PodCIDR is reused. // The same ip will now have a different nodeName. - errList := ValidateEndpoints(updatedEndpoint, false) + errList := ValidateEndpoints(updatedEndpoint) errList = append(errList, ValidateEndpointsUpdate(updatedEndpoint, oldEndpoint)...) if len(errList) != 0 { t.Error("Endpoint should allow changing of Subset.Addresses.NodeName on update") @@ -15706,7 +15650,7 @@ func TestEndpointAddressNodeNameUpdateRestrictions(t *testing.T) { func TestEndpointAddressNodeNameInvalidDNSSubdomain(t *testing.T) { // Check NodeName DNS validation endpoint := newNodeNameEndpoint("illegal*.nodename") - errList := ValidateEndpoints(endpoint, false) + errList := ValidateEndpoints(endpoint) if len(errList) == 0 { t.Error("Endpoint should reject invalid NodeName") } @@ -15714,7 +15658,7 @@ func TestEndpointAddressNodeNameInvalidDNSSubdomain(t *testing.T) { func TestEndpointAddressNodeNameCanBeAnIPAddress(t *testing.T) { endpoint := newNodeNameEndpoint("10.10.1.1") - errList := ValidateEndpoints(endpoint, false) + errList := ValidateEndpoints(endpoint) if len(errList) != 0 { t.Error("Endpoint should accept a NodeName that is an IP address") } diff --git a/pkg/controller/endpoint/endpoints_controller.go b/pkg/controller/endpoint/endpoints_controller.go index a1bc0f11980..8399404203c 100644 --- a/pkg/controller/endpoint/endpoints_controller.go +++ b/pkg/controller/endpoint/endpoints_controller.go @@ -639,12 +639,10 @@ func shouldPodBeInEndpoints(pod *v1.Pod) bool { func endpointPortFromServicePort(servicePort *v1.ServicePort, portNum int) *v1.EndpointPort { epp := &v1.EndpointPort{ - Name: servicePort.Name, - Port: int32(portNum), - Protocol: servicePort.Protocol, - } - if utilfeature.DefaultFeatureGate.Enabled(features.ServiceAppProtocol) { - epp.AppProtocol = servicePort.AppProtocol + Name: servicePort.Name, + Port: int32(portNum), + Protocol: servicePort.Protocol, + AppProtocol: servicePort.AppProtocol, } return epp } diff --git a/pkg/controller/endpoint/endpoints_controller_test.go b/pkg/controller/endpoint/endpoints_controller_test.go index 0da4dd1aefd..19fb2c5e7a4 100644 --- a/pkg/controller/endpoint/endpoints_controller_test.go +++ b/pkg/controller/endpoint/endpoints_controller_test.go @@ -1984,27 +1984,14 @@ func TestSyncEndpointsServiceNotFound(t *testing.T) { func TestEndpointPortFromServicePort(t *testing.T) { http := utilpointer.StringPtr("http") testCases := map[string]struct { - featureGateEnabled bool serviceAppProtocol *string expectedEndpointsAppProtocol *string }{ - "feature gate disabled, empty app protocol": { - featureGateEnabled: false, + "empty app protocol": { serviceAppProtocol: nil, expectedEndpointsAppProtocol: nil, }, - "feature gate disabled, http app protocol": { - featureGateEnabled: false, - serviceAppProtocol: http, - expectedEndpointsAppProtocol: nil, - }, - "feature gate enabled, empty app protocol": { - featureGateEnabled: true, - serviceAppProtocol: nil, - expectedEndpointsAppProtocol: nil, - }, - "feature gate enabled, http app protocol": { - featureGateEnabled: true, + "http app protocol": { serviceAppProtocol: http, expectedEndpointsAppProtocol: http, }, @@ -2012,8 +1999,6 @@ func TestEndpointPortFromServicePort(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceAppProtocol, tc.featureGateEnabled)() - epp := endpointPortFromServicePort(&v1.ServicePort{Name: "test", AppProtocol: tc.serviceAppProtocol}, 80) if epp.AppProtocol != tc.expectedEndpointsAppProtocol { diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 53c8bdf19c3..13203340df2 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -576,6 +576,7 @@ const ( // owner: @robscott // alpha: v1.18 // beta: v1.19 + // ga: v1.20 // // Enables AppProtocol field for Services and Endpoints. ServiceAppProtocol featuregate.Feature = "ServiceAppProtocol" @@ -755,7 +756,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS AllowInsecureBackendProxy: {Default: true, PreRelease: featuregate.Beta}, PodDisruptionBudget: {Default: true, PreRelease: featuregate.Beta}, ServiceTopology: {Default: false, PreRelease: featuregate.Alpha}, - ServiceAppProtocol: {Default: true, PreRelease: featuregate.Beta}, + ServiceAppProtocol: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, ImmutableEphemeralVolumes: {Default: true, PreRelease: featuregate.Beta}, HugePageStorageMediumSize: {Default: true, PreRelease: featuregate.Beta}, ExternalPolicyForExternalIP: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22