mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 09:52:49 +00:00
Promote endPort to GA
This commit is contained in:
parent
f045fb688f
commit
3e7bdbbf30
@ -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
|
||||
}
|
||||
|
@ -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},
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user