mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 18:02:01 +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
|
// 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.
|
// is not defined or if the port field is defined as a named (string) port.
|
||||||
// The endPort must be equal or greater than 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
|
// +optional
|
||||||
EndPort *int32
|
EndPort *int32
|
||||||
}
|
}
|
||||||
|
@ -545,6 +545,7 @@ const (
|
|||||||
// kep: http://kep.k8s.io/2079
|
// kep: http://kep.k8s.io/2079
|
||||||
// alpha: v1.21
|
// alpha: v1.21
|
||||||
// beta: v1.22
|
// beta: v1.22
|
||||||
|
// ga: v1.25
|
||||||
//
|
//
|
||||||
// Enables the endPort field in NetworkPolicy to enable a Port Range behavior in Network Policies.
|
// Enables the endPort field in NetworkPolicy to enable a Port Range behavior in Network Policies.
|
||||||
NetworkPolicyEndPort featuregate.Feature = "NetworkPolicyEndPort"
|
NetworkPolicyEndPort featuregate.Feature = "NetworkPolicyEndPort"
|
||||||
@ -945,7 +946,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
|
|
||||||
MixedProtocolLBService: {Default: true, PreRelease: featuregate.Beta},
|
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},
|
NetworkPolicyStatus: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
|
||||||
|
@ -71,9 +71,6 @@ func (networkPolicyStrategy) PrepareForCreate(ctx context.Context, obj runtime.O
|
|||||||
|
|
||||||
networkPolicy.Generation = 1
|
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.
|
// 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
|
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
|
// Any changes to the spec increment the generation number, any changes to the
|
||||||
// status should reflect the generation number of the corresponding object.
|
// status should reflect the generation number of the corresponding object.
|
||||||
// See metav1.ObjectMeta description for more information on Generation.
|
// 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 {
|
func (networkPolicyStatusStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string {
|
||||||
return nil
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -94,173 +93,14 @@ func makeNetworkPolicy(isIngress, isEgress, hasEndPort bool) *networking.Network
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNetworkPolicyStrategy(t *testing.T) {
|
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)
|
// Create a Network Policy containing EndPort defined to compare with the generated by the tests
|
||||||
Strategy.PrepareForCreate(context.Background(), netPol)
|
netPol := makeNetworkPolicy(true, true, false)
|
||||||
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)
|
|
||||||
|
|
||||||
Strategy.PrepareForCreate(context.Background(), netPol)
|
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 {
|
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)
|
netPol.Generation)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,18 +109,15 @@ func TestNetworkPolicyEndPortEnablement(t *testing.T) {
|
|||||||
t.Errorf("Unexpected error from validation for created Network Policy: %v", errs)
|
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
|
updatedNetPol := makeNetworkPolicy(true, true, true)
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NetworkPolicyEndPort, false)()
|
updatedNetPol.ObjectMeta.SetResourceVersion("1")
|
||||||
updateNetPol, err := testUpdateEndPort(netPol)
|
Strategy.PrepareForUpdate(context.Background(), updatedNetPol, netPol)
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Update with disabled FG failed. %v", err)
|
errs = Strategy.ValidateUpdate(context.Background(), updatedNetPol, netPol)
|
||||||
}
|
if len(errs) != 0 {
|
||||||
// And let's enable the FG again, add another from and check if the EndPort field is still present
|
t.Errorf("Unexpected error from validation for updated Network Policy: %v", errs)
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NetworkPolicyEndPort, true)()
|
|
||||||
_, err = testUpdateEndPort(updateNetPol)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Update with enabled FG failed. %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNetworkPolicyStatusStrategy(t *testing.T) {
|
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
|
// 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.
|
// is not defined or if the port field is defined as a named (string) port.
|
||||||
// The endPort must be equal or greater than 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
|
// +optional
|
||||||
EndPort *int32 `json:"endPort,omitempty" protobuf:"bytes,3,opt,name=endPort"`
|
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
|
// 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.
|
// is not defined or if the port field is defined as a named (string) port.
|
||||||
// The endPort must be equal or greater than 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
|
// +optional
|
||||||
EndPort *int32 `json:"endPort,omitempty" protobuf:"bytes,3,opt,name=endPort"`
|
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 cannot be defined if the Port field is defined as a named (string) port.
|
||||||
- EndPort field must be equal or greater than 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
|
ns := f.Namespace.Name
|
||||||
npClient := f.ClientSet.NetworkingV1().NetworkPolicies(ns)
|
npClient := f.ClientSet.NetworkingV1().NetworkPolicies(ns)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user