Promote endPort to GA

This commit is contained in:
Ricardo Katz 2022-06-29 10:58:37 -03:00 committed by Ricardo Pchevuzinske Katz
parent f045fb688f
commit 3e7bdbbf30
7 changed files with 14 additions and 265 deletions

View File

@ -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
}

View File

@ -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},

View File

@ -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
}

View File

@ -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
}

View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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)