diff --git a/pkg/apis/networking/types.go b/pkg/apis/networking/types.go index cd9a8347588..43d2d83645a 100644 --- a/pkg/apis/networking/types.go +++ b/pkg/apis/networking/types.go @@ -154,8 +154,6 @@ type NetworkPolicyPort struct { // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. - // This feature is in Beta state and is enabled by default. - // It can be disabled using the Feature Gate "NetworkPolicyEndPort". // +optional EndPort *int32 } diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 31d73f3512c..d73b417e7dd 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -545,6 +545,7 @@ const ( // kep: http://kep.k8s.io/2079 // alpha: v1.21 // beta: v1.22 + // ga: v1.25 // // Enables the endPort field in NetworkPolicy to enable a Port Range behavior in Network Policies. NetworkPolicyEndPort featuregate.Feature = "NetworkPolicyEndPort" @@ -945,7 +946,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS MixedProtocolLBService: {Default: true, PreRelease: featuregate.Beta}, - NetworkPolicyEndPort: {Default: true, PreRelease: featuregate.Beta}, + NetworkPolicyEndPort: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 NetworkPolicyStatus: {Default: false, PreRelease: featuregate.Alpha}, diff --git a/pkg/registry/networking/networkpolicy/strategy.go b/pkg/registry/networking/networkpolicy/strategy.go index cb85fab6a88..71d9b260301 100644 --- a/pkg/registry/networking/networkpolicy/strategy.go +++ b/pkg/registry/networking/networkpolicy/strategy.go @@ -71,9 +71,6 @@ func (networkPolicyStrategy) PrepareForCreate(ctx context.Context, obj runtime.O networkPolicy.Generation = 1 - if !utilfeature.DefaultFeatureGate.Enabled(features.NetworkPolicyEndPort) { - dropNetworkPolicyEndPort(networkPolicy) - } } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -88,10 +85,6 @@ func (networkPolicyStrategy) PrepareForUpdate(ctx context.Context, obj, old runt newNetworkPolicy.Status = oldNetworkPolicy.Status } - if !utilfeature.DefaultFeatureGate.Enabled(features.NetworkPolicyEndPort) && !endPortInUse(oldNetworkPolicy) { - dropNetworkPolicyEndPort(newNetworkPolicy) - } - // Any changes to the spec increment the generation number, any changes to the // status should reflect the generation number of the corresponding object. // See metav1.ObjectMeta description for more information on Generation. @@ -187,42 +180,3 @@ func (networkPolicyStatusStrategy) ValidateUpdate(ctx context.Context, obj, old func (networkPolicyStatusStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { return nil } - -// Drops Network Policy EndPort fields if Feature Gate is also disabled. -// This should be used in future Network Policy evolutions -func dropNetworkPolicyEndPort(netPol *networking.NetworkPolicy) { - for idx, ingressSpec := range netPol.Spec.Ingress { - for idxPort, port := range ingressSpec.Ports { - if port.EndPort != nil { - netPol.Spec.Ingress[idx].Ports[idxPort].EndPort = nil - } - } - } - - for idx, egressSpec := range netPol.Spec.Egress { - for idxPort, port := range egressSpec.Ports { - if port.EndPort != nil { - netPol.Spec.Egress[idx].Ports[idxPort].EndPort = nil - } - } - } -} - -func endPortInUse(netPol *networking.NetworkPolicy) bool { - for _, ingressSpec := range netPol.Spec.Ingress { - for _, port := range ingressSpec.Ports { - if port.EndPort != nil { - return true - } - } - } - - for _, egressSpec := range netPol.Spec.Egress { - for _, port := range egressSpec.Ports { - if port.EndPort != nil { - return true - } - } - } - return false -} diff --git a/pkg/registry/networking/networkpolicy/strategy_test.go b/pkg/registry/networking/networkpolicy/strategy_test.go index 8fda233679a..1f03838acc4 100644 --- a/pkg/registry/networking/networkpolicy/strategy_test.go +++ b/pkg/registry/networking/networkpolicy/strategy_test.go @@ -18,7 +18,6 @@ package networkpolicy import ( "context" - "fmt" "reflect" "testing" "time" @@ -94,173 +93,14 @@ func makeNetworkPolicy(isIngress, isEgress, hasEndPort bool) *networking.Network } func TestNetworkPolicyStrategy(t *testing.T) { - for _, tc := range []struct { - name string - hasEndPort bool - enableFeatureGate bool - isIngress bool - isEgress bool - }{ - { - name: "Create Ingress Rule with EndPort Feature Gate enabled and with EndPort defined", - hasEndPort: true, - enableFeatureGate: true, - isIngress: true, - isEgress: false, - }, - { - name: "Create Ingress Rule with EndPort Feature Gate disabled and with EndPort defined", - hasEndPort: true, - enableFeatureGate: false, - isIngress: true, - isEgress: false, - }, - { - name: "Create Ingress Rule with EndPort Feature Gate enabled and with endPort undefined", - hasEndPort: false, - enableFeatureGate: true, - isIngress: true, - isEgress: false, - }, - { - name: "Create Ingress Rule with EndPort Feature Gate disabled and with endPort undefined", - hasEndPort: false, - enableFeatureGate: false, - isIngress: true, - isEgress: false, - }, - { - name: "Create Egress Rule with EndPort Feature Gate enabled and with endPort defined", - hasEndPort: true, - enableFeatureGate: true, - isIngress: false, - isEgress: true, - }, - { - name: "Create Egress Rule with EndPort Feature Gate enabled and with endPort defined", - hasEndPort: true, - enableFeatureGate: false, - isIngress: false, - isEgress: true, - }, - { - name: "Create Egress Rule with EndPort Feature Gate true and with endPort undefined", - hasEndPort: false, - enableFeatureGate: true, - isIngress: false, - isEgress: true, - }, - { - name: "Create Egress Rule with EndPort Feature Gate disabled and with endPort undefined", - hasEndPort: false, - enableFeatureGate: false, - isIngress: false, - isEgress: true, - }, - { - name: "Create Ingress and Egress Rule with EndPort Feature Gate enabled and endPort defined", - hasEndPort: true, - enableFeatureGate: true, - isIngress: true, - isEgress: true, - }, - { - name: "Create Ingress and Egress Rule with EndPort Feature Gate disabled and endPort defined", - hasEndPort: true, - enableFeatureGate: false, - isIngress: true, - isEgress: true, - }, - { - name: "Create Ingress and Egress Rule with EndPort Feature Gate enabled and endPort undefined", - hasEndPort: false, - enableFeatureGate: true, - isIngress: true, - isEgress: true, - }, - { - name: "Create Ingress and Egress Rule with EndPort Feature Gate disabled and endPort undefined", - hasEndPort: false, - enableFeatureGate: false, - isIngress: true, - isEgress: true, - }, - { - name: "Create a null rule with EndPort Feature Gate enabled", - hasEndPort: false, - enableFeatureGate: true, - isIngress: false, - isEgress: false, - }, - { - name: "Create a null rule with EndPort Feature Gate disabled", - hasEndPort: false, - enableFeatureGate: false, - isIngress: false, - isEgress: false, - }, - } { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NetworkPolicyEndPort, tc.enableFeatureGate)() - // Create a Network Policy containing EndPort defined to compare with the generated by the tests - expectedNewNetPol := makeNetworkPolicy(tc.isIngress, tc.isEgress, - (tc.hasEndPort && tc.enableFeatureGate)) - netPol := makeNetworkPolicy(tc.isIngress, tc.isEgress, tc.hasEndPort) - Strategy.PrepareForCreate(context.Background(), netPol) - if !reflect.DeepEqual(netPol.Spec, expectedNewNetPol.Spec) { - t.Errorf("Create: %s failed. Spec from NetworkPolicy is not equal to the expected. \nGot: %+v \nExpected: %+v", - tc.name, netPol, expectedNewNetPol) - } - - if netPol.Generation != 1 { - t.Errorf("Create: Test %s failed. Network Policy Generation should be 1, got %d", - tc.name, netPol.Generation) - } - - errs := Strategy.Validate(context.Background(), netPol) - if len(errs) != 0 { - t.Errorf("Unexpected error from validation for created Network Policy: %v", errs) - } - - // Test when an updated Network Policy drops the EndPort field even if the FG has been disabled - // but the field is present - oldNetPol := makeNetworkPolicy(tc.isIngress, tc.isEgress, tc.hasEndPort) - updatedNetPol := makeNetworkPolicy(tc.isIngress, tc.isEgress, tc.hasEndPort) - expectedUpdatedNetPol := makeNetworkPolicy(tc.isIngress, tc.isEgress, tc.hasEndPort) - Strategy.PrepareForUpdate(context.Background(), updatedNetPol, oldNetPol) - - if !reflect.DeepEqual(updatedNetPol.Spec, expectedUpdatedNetPol.Spec) { - t.Errorf("Update: %s failed. Spec from NetworkPolicy is not equal to the expected. \nGot: %+v \nExpected: %+v", - tc.name, updatedNetPol, expectedUpdatedNetPol) - } - - if updatedNetPol.Generation != 0 && !tc.enableFeatureGate { - t.Errorf("Update: Test %s failed. Network Policy Generation should be 1, got %d", - tc.name, updatedNetPol.Generation) - } - - errs = Strategy.Validate(context.Background(), updatedNetPol) - if len(errs) != 0 { - t.Errorf("Unexpected error from validation for updated Network Policy: %v", errs) - } - } -} - -func TestNetworkPolicyEndPortEnablement(t *testing.T) { - // Enable the Feature Gate during the first rule creation - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NetworkPolicyEndPort, true)() - netPol := makeNetworkPolicy(true, true, true) - // We always expect the EndPort to be present, even if the FG is disabled later - expectedNetPol := makeNetworkPolicy(true, true, true) + // Create a Network Policy containing EndPort defined to compare with the generated by the tests + netPol := makeNetworkPolicy(true, true, false) Strategy.PrepareForCreate(context.Background(), netPol) - if !reflect.DeepEqual(netPol.Spec, expectedNetPol.Spec) { - t.Errorf("Create with enabled FG failed. Spec from NetworkPolicy is not equal to the expected. \nGot: %+v \nExpected: %+v", - netPol, expectedNetPol) - } if netPol.Generation != 1 { - t.Errorf("Create with enabled FG failed. Network Policy Generation should be 1, got %d", + t.Errorf("Create: Test failed. Network Policy Generation should be 1, got %d", netPol.Generation) } @@ -269,18 +109,15 @@ func TestNetworkPolicyEndPortEnablement(t *testing.T) { t.Errorf("Unexpected error from validation for created Network Policy: %v", errs) } - // Now let's disable the Feature Gate, update some other field from NetPol and expect the EndPort is already present - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NetworkPolicyEndPort, false)() - updateNetPol, err := testUpdateEndPort(netPol) - if err != nil { - t.Errorf("Update with disabled FG failed. %v", err) - } - // And let's enable the FG again, add another from and check if the EndPort field is still present - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NetworkPolicyEndPort, true)() - _, err = testUpdateEndPort(updateNetPol) - if err != nil { - t.Errorf("Update with enabled FG failed. %v", err) + updatedNetPol := makeNetworkPolicy(true, true, true) + updatedNetPol.ObjectMeta.SetResourceVersion("1") + Strategy.PrepareForUpdate(context.Background(), updatedNetPol, netPol) + + errs = Strategy.ValidateUpdate(context.Background(), updatedNetPol, netPol) + if len(errs) != 0 { + t.Errorf("Unexpected error from validation for updated Network Policy: %v", errs) } + } func TestNetworkPolicyStatusStrategy(t *testing.T) { @@ -450,40 +287,3 @@ func TestNetworkPolicyStatusStrategyEnablement(t *testing.T) { } } - -func testUpdateEndPort(oldNetPol *networking.NetworkPolicy) (*networking.NetworkPolicy, error) { - updatedNetPol := makeNetworkPolicy(true, true, true) - expectedNetPol := makeNetworkPolicy(true, true, true) - - if oldNetPol == nil { - return nil, fmt.Errorf("Nil Network Policy received") - } - expectedGeneration := oldNetPol.GetGeneration() + 1 - labelValue := fmt.Sprintf("bla%d", expectedGeneration) - - updateFrom := networking.NetworkPolicyPeer{ - NamespaceSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"e": labelValue}, - }, - } - - updatedNetPol.Spec.Ingress[0].From = append(updatedNetPol.Spec.Ingress[0].From, updateFrom) - expectedNetPol.Spec.Ingress[0].From = append(expectedNetPol.Spec.Ingress[0].From, updateFrom) - - Strategy.PrepareForUpdate(context.Background(), updatedNetPol, oldNetPol) - if !reflect.DeepEqual(updatedNetPol.Spec, expectedNetPol.Spec) { - return nil, fmt.Errorf("Spec from NetworkPolicy is not equal to the expected. \nGot: %+v \nExpected: %+v", - updatedNetPol, expectedNetPol) - } - if updatedNetPol.Generation != expectedGeneration { - return nil, fmt.Errorf("Network Policy Generation should be %d, got %d", - expectedGeneration, updatedNetPol.Generation) - } - - errs := Strategy.Validate(context.Background(), updatedNetPol) - if len(errs) != 0 { - return nil, fmt.Errorf("Unexpected error from validation for created Network Policy: %v", errs) - } - return updatedNetPol, nil - -} diff --git a/staging/src/k8s.io/api/extensions/v1beta1/types.go b/staging/src/k8s.io/api/extensions/v1beta1/types.go index c63cf0d6713..0674dae8b33 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/types.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/types.go @@ -1498,8 +1498,6 @@ type NetworkPolicyPort struct { // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. - // This feature is in Beta state and is enabled by default. - // It can be disabled using the Feature Gate "NetworkPolicyEndPort". // +optional EndPort *int32 `json:"endPort,omitempty" protobuf:"bytes,3,opt,name=endPort"` } diff --git a/staging/src/k8s.io/api/networking/v1/types.go b/staging/src/k8s.io/api/networking/v1/types.go index 1177df98fda..0c67aa2fd16 100644 --- a/staging/src/k8s.io/api/networking/v1/types.go +++ b/staging/src/k8s.io/api/networking/v1/types.go @@ -158,8 +158,6 @@ type NetworkPolicyPort struct { // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. - // This feature is in Beta state and is enabled by default. - // It can be disabled using the Feature Gate "NetworkPolicyEndPort". // +optional EndPort *int32 `json:"endPort,omitempty" protobuf:"bytes,3,opt,name=endPort"` } diff --git a/test/e2e/network/netpol/network_policy_api.go b/test/e2e/network/netpol/network_policy_api.go index 35eaa664b9a..de91aa24e3a 100644 --- a/test/e2e/network/netpol/network_policy_api.go +++ b/test/e2e/network/netpol/network_policy_api.go @@ -219,7 +219,7 @@ var _ = common.SIGDescribe("Netpol API", func() { - EndPort field cannot be defined if the Port field is defined as a named (string) port. - EndPort field must be equal or greater than port. */ - ginkgo.It("should support creating NetworkPolicy API with endport field [Feature:NetworkPolicyEndPort]", func() { + ginkgo.It("should support creating NetworkPolicy API with endport field", func() { ns := f.Namespace.Name npClient := f.ClientSet.NetworkingV1().NetworkPolicies(ns)