mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Add EgressRule to NetworkPolicy
Signed-off-by: Christopher M. Luciano <cmluciano@us.ibm.com>
This commit is contained in:
		@@ -62,6 +62,8 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
 | 
			
		||||
		Convert_extensions_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySpec,
 | 
			
		||||
		Convert_v1beta1_IPBlock_To_networking_IPBlock,
 | 
			
		||||
		Convert_networking_IPBlock_To_v1beta1_IPBlock,
 | 
			
		||||
		Convert_networking_NetworkPolicyEgressRule_To_v1beta1_NetworkPolicyEgressRule,
 | 
			
		||||
		Convert_v1beta1_NetworkPolicyEgressRule_To_networking_NetworkPolicyEgressRule,
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@@ -283,6 +285,12 @@ func Convert_v1beta1_NetworkPolicySpec_To_networking_NetworkPolicySpec(in *exten
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	out.Egress = make([]networking.NetworkPolicyEgressRule, len(in.Egress))
 | 
			
		||||
	for i := range in.Egress {
 | 
			
		||||
		if err := Convert_v1beta1_NetworkPolicyEgressRule_To_networking_NetworkPolicyEgressRule(&in.Egress[i], &out.Egress[i], s); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -296,6 +304,12 @@ func Convert_networking_NetworkPolicySpec_To_v1beta1_NetworkPolicySpec(in *netwo
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	out.Egress = make([]extensionsv1beta1.NetworkPolicyEgressRule, len(in.Egress))
 | 
			
		||||
	for i := range in.Egress {
 | 
			
		||||
		if err := Convert_networking_NetworkPolicyEgressRule_To_v1beta1_NetworkPolicyEgressRule(&in.Egress[i], &out.Egress[i], s); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -331,6 +345,38 @@ func Convert_networking_NetworkPolicyIngressRule_To_v1beta1_NetworkPolicyIngress
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Convert_v1beta1_NetworkPolicyEgressRule_To_networking_NetworkPolicyEgressRule(in *extensionsv1beta1.NetworkPolicyEgressRule, out *networking.NetworkPolicyEgressRule, s conversion.Scope) error {
 | 
			
		||||
	out.Ports = make([]networking.NetworkPolicyPort, len(in.Ports))
 | 
			
		||||
	for i := range in.Ports {
 | 
			
		||||
		if err := Convert_v1beta1_NetworkPolicyPort_To_networking_NetworkPolicyPort(&in.Ports[i], &out.Ports[i], s); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	out.To = make([]networking.NetworkPolicyPeer, len(in.To))
 | 
			
		||||
	for i := range in.To {
 | 
			
		||||
		if err := Convert_v1beta1_NetworkPolicyPeer_To_networking_NetworkPolicyPeer(&in.To[i], &out.To[i], s); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Convert_networking_NetworkPolicyEgressRule_To_v1beta1_NetworkPolicyEgressRule(in *networking.NetworkPolicyEgressRule, out *extensionsv1beta1.NetworkPolicyEgressRule, s conversion.Scope) error {
 | 
			
		||||
	out.Ports = make([]extensionsv1beta1.NetworkPolicyPort, len(in.Ports))
 | 
			
		||||
	for i := range in.Ports {
 | 
			
		||||
		if err := Convert_networking_NetworkPolicyPort_To_v1beta1_NetworkPolicyPort(&in.Ports[i], &out.Ports[i], s); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	out.To = make([]extensionsv1beta1.NetworkPolicyPeer, len(in.To))
 | 
			
		||||
	for i := range in.To {
 | 
			
		||||
		if err := Convert_networking_NetworkPolicyPeer_To_v1beta1_NetworkPolicyPeer(&in.To[i], &out.To[i], s); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Convert_v1beta1_NetworkPolicyPeer_To_networking_NetworkPolicyPeer(in *extensionsv1beta1.NetworkPolicyPeer, out *networking.NetworkPolicyPeer, s conversion.Scope) error {
 | 
			
		||||
	if in.PodSelector != nil {
 | 
			
		||||
		out.PodSelector = new(metav1.LabelSelector)
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,15 @@ type NetworkPolicySpec struct {
 | 
			
		||||
	// solely to ensure that the pods it selects are isolated by default)
 | 
			
		||||
	// +optional
 | 
			
		||||
	Ingress []NetworkPolicyIngressRule
 | 
			
		||||
 | 
			
		||||
	// List of egress rules to be applied to the selected pods. Outgoing traffic is
 | 
			
		||||
	// allowed if there are no NetworkPolicies selecting the pod (and cluster policy
 | 
			
		||||
	// otherwise allows the traffic), OR if the traffic matches at least one egress rule
 | 
			
		||||
	// across all of the NetworkPolicy objects whose podSelector matches the pod. If
 | 
			
		||||
	// this field is empty then this NetworkPolicy does not limit any outgoing traffic
 | 
			
		||||
	// (and serves solely to ensure that the pods it selects does not allow any outgoing traffic.)
 | 
			
		||||
	// +optional
 | 
			
		||||
	Egress []NetworkPolicyEgressRule
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods
 | 
			
		||||
@@ -77,6 +86,26 @@ type NetworkPolicyIngressRule struct {
 | 
			
		||||
	From []NetworkPolicyPeer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods
 | 
			
		||||
// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.
 | 
			
		||||
type NetworkPolicyEgressRule struct {
 | 
			
		||||
	// List of destination ports for outgoing traffic.
 | 
			
		||||
	// Each item in this list is combined using a logical OR. If this field is
 | 
			
		||||
	// empty or missing, this rule matches all ports (traffic not restricted by port).
 | 
			
		||||
	// If this field is present and contains at least one item, then this rule allows
 | 
			
		||||
	// traffic only if the traffic matches at least one port in the list.
 | 
			
		||||
	// +optional
 | 
			
		||||
	Ports []NetworkPolicyPort
 | 
			
		||||
 | 
			
		||||
	// List of destinations for outgoing traffic of pods selected for this rule.
 | 
			
		||||
	// Items in this list are combined using a logical OR operation. If this field is
 | 
			
		||||
	// empty or missing, this rule matches all destinations (traffic not restricted by
 | 
			
		||||
	// destination). If this field is present and contains at least one item, this rule
 | 
			
		||||
	// allows traffic only if the traffic matches at least one item in the to list.
 | 
			
		||||
	// +optional
 | 
			
		||||
	To []NetworkPolicyPeer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkPolicyPort describes a port to allow traffic on
 | 
			
		||||
type NetworkPolicyPort struct {
 | 
			
		||||
	// The protocol (TCP or UDP) which traffic must match. If not specified, this
 | 
			
		||||
 
 | 
			
		||||
@@ -81,6 +81,48 @@ func ValidateNetworkPolicySpec(spec *networking.NetworkPolicySpec, fldPath *fiel
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Validate egress rules
 | 
			
		||||
	for i, egress := range spec.Egress {
 | 
			
		||||
		egressPath := fldPath.Child("egress").Index(i)
 | 
			
		||||
		for i, port := range egress.Ports {
 | 
			
		||||
			portPath := egressPath.Child("ports").Index(i)
 | 
			
		||||
			if port.Protocol != nil && *port.Protocol != api.ProtocolTCP && *port.Protocol != api.ProtocolUDP {
 | 
			
		||||
				allErrs = append(allErrs, field.NotSupported(portPath.Child("protocol"), *port.Protocol, []string{string(api.ProtocolTCP), string(api.ProtocolUDP)}))
 | 
			
		||||
			}
 | 
			
		||||
			if port.Port != nil {
 | 
			
		||||
				if port.Port.Type == intstr.Int {
 | 
			
		||||
					for _, msg := range validation.IsValidPortNum(int(port.Port.IntVal)) {
 | 
			
		||||
						allErrs = append(allErrs, field.Invalid(portPath.Child("port"), port.Port.IntVal, msg))
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					for _, msg := range validation.IsValidPortName(port.Port.StrVal) {
 | 
			
		||||
						allErrs = append(allErrs, field.Invalid(portPath.Child("port"), port.Port.StrVal, msg))
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		for i, to := range egress.To {
 | 
			
		||||
			toPath := egressPath.Child("to").Index(i)
 | 
			
		||||
			numTo := 0
 | 
			
		||||
			if to.PodSelector != nil {
 | 
			
		||||
				numTo++
 | 
			
		||||
				allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(to.PodSelector, toPath.Child("podSelector"))...)
 | 
			
		||||
			}
 | 
			
		||||
			if to.NamespaceSelector != nil {
 | 
			
		||||
				numTo++
 | 
			
		||||
				allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(to.NamespaceSelector, toPath.Child("namespaceSelector"))...)
 | 
			
		||||
			}
 | 
			
		||||
			if to.IPBlock != nil {
 | 
			
		||||
				numTo++
 | 
			
		||||
				allErrs = append(allErrs, ValidateIPBlock(to.IPBlock, toPath.Child("ipBlock"))...)
 | 
			
		||||
			}
 | 
			
		||||
			if numTo == 0 {
 | 
			
		||||
				allErrs = append(allErrs, field.Required(toPath, "must specify a to type"))
 | 
			
		||||
			} else if numTo > 1 {
 | 
			
		||||
				allErrs = append(allErrs, field.Forbidden(toPath, "may not specify more than 1 to type"))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return allErrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -128,6 +128,17 @@ func TestValidateNetworkPolicy(t *testing.T) {
 | 
			
		||||
				PodSelector: metav1.LabelSelector{
 | 
			
		||||
					MatchLabels: map[string]string{"a": "b"},
 | 
			
		||||
				},
 | 
			
		||||
				Egress: []networking.NetworkPolicyEgressRule{
 | 
			
		||||
					{
 | 
			
		||||
						To: []networking.NetworkPolicyPeer{
 | 
			
		||||
							{
 | 
			
		||||
								NamespaceSelector: &metav1.LabelSelector{
 | 
			
		||||
									MatchLabels: map[string]string{"c": "d"},
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				Ingress: []networking.NetworkPolicyIngressRule{
 | 
			
		||||
					{
 | 
			
		||||
						From: []networking.NetworkPolicyPeer{
 | 
			
		||||
@@ -142,6 +153,46 @@ func TestValidateNetworkPolicy(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
 | 
			
		||||
			Spec: networking.NetworkPolicySpec{
 | 
			
		||||
				PodSelector: metav1.LabelSelector{
 | 
			
		||||
					MatchLabels: map[string]string{"a": "b"},
 | 
			
		||||
				},
 | 
			
		||||
				Ingress: []networking.NetworkPolicyIngressRule{
 | 
			
		||||
					{
 | 
			
		||||
						From: []networking.NetworkPolicyPeer{
 | 
			
		||||
							{
 | 
			
		||||
								IPBlock: &networking.IPBlock{
 | 
			
		||||
									CIDR:   "192.168.0.0/16",
 | 
			
		||||
									Except: []string{"192.168.3.0/24", "192.168.4.0/24"},
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
 | 
			
		||||
			Spec: networking.NetworkPolicySpec{
 | 
			
		||||
				PodSelector: metav1.LabelSelector{
 | 
			
		||||
					MatchLabels: map[string]string{"a": "b"},
 | 
			
		||||
				},
 | 
			
		||||
				Egress: []networking.NetworkPolicyEgressRule{
 | 
			
		||||
					{
 | 
			
		||||
						To: []networking.NetworkPolicyPeer{
 | 
			
		||||
							{
 | 
			
		||||
								IPBlock: &networking.IPBlock{
 | 
			
		||||
									CIDR:   "192.168.0.0/16",
 | 
			
		||||
									Except: []string{"192.168.3.0/24", "192.168.4.0/24"},
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Success cases are expected to pass validation.
 | 
			
		||||
@@ -259,6 +310,23 @@ func TestValidateNetworkPolicy(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		"invalid egress.to.podSelector": {
 | 
			
		||||
			ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
 | 
			
		||||
			Spec: networking.NetworkPolicySpec{
 | 
			
		||||
				PodSelector: metav1.LabelSelector{},
 | 
			
		||||
				Egress: []networking.NetworkPolicyEgressRule{
 | 
			
		||||
					{
 | 
			
		||||
						To: []networking.NetworkPolicyPeer{
 | 
			
		||||
							{
 | 
			
		||||
								PodSelector: &metav1.LabelSelector{
 | 
			
		||||
									MatchLabels: invalidSelector,
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		"invalid ingress.from.namespaceSelector": {
 | 
			
		||||
			ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
 | 
			
		||||
			Spec: networking.NetworkPolicySpec{
 | 
			
		||||
 
 | 
			
		||||
@@ -1174,6 +1174,15 @@ type NetworkPolicySpec struct {
 | 
			
		||||
	// (and serves solely to ensure that the pods it selects are isolated by default).
 | 
			
		||||
	// +optional
 | 
			
		||||
	Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,2,rep,name=ingress"`
 | 
			
		||||
 | 
			
		||||
	// List of egress rules to be applied to the selected pods. Outgoing traffic is
 | 
			
		||||
	// allowed if there are no NetworkPolicies selecting the pod (and cluster policy
 | 
			
		||||
	// otherwise allows the traffic), OR if the traffic matches at least one egress rule
 | 
			
		||||
	// across all of the NetworkPolicy objects whose podSelector matches the pod. If
 | 
			
		||||
	// this field is empty then this NetworkPolicy does not limit any outgoing traffic
 | 
			
		||||
	// (and serves solely to ensure that the pods it selects does not allow any outgoing traffic.)
 | 
			
		||||
	// +optional
 | 
			
		||||
	Egress []NetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,3,rep,name=egress"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This NetworkPolicyIngressRule matches traffic if and only if the traffic matches both ports AND from.
 | 
			
		||||
@@ -1195,6 +1204,26 @@ type NetworkPolicyIngressRule struct {
 | 
			
		||||
	From []NetworkPolicyPeer `json:"from,omitempty" protobuf:"bytes,2,rep,name=from"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods
 | 
			
		||||
// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.
 | 
			
		||||
type NetworkPolicyEgressRule struct {
 | 
			
		||||
	// List of destination ports for outgoing traffic.
 | 
			
		||||
	// Each item in this list is combined using a logical OR. If this field is
 | 
			
		||||
	// empty or missing, this rule matches all ports (traffic not restricted by port).
 | 
			
		||||
	// If this field is present and contains at least one item, then this rule allows
 | 
			
		||||
	// traffic only if the traffic matches at least one port in the list.
 | 
			
		||||
	// +optional
 | 
			
		||||
	Ports []NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"`
 | 
			
		||||
 | 
			
		||||
	// List of destinations for outgoing traffic of pods selected for this rule.
 | 
			
		||||
	// Items in this list are combined using a logical OR operation. If this field is
 | 
			
		||||
	// empty or missing, this rule matches all destinations (traffic not restricted by
 | 
			
		||||
	// destination). If this field is present and contains at least one item, this rule
 | 
			
		||||
	// allows traffic only if the traffic matches at least one item in the to list.
 | 
			
		||||
	// +optional
 | 
			
		||||
	To []NetworkPolicyPeer `json:"to,omitempty" protobuf:"bytes,2,rep,name=to"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type NetworkPolicyPort struct {
 | 
			
		||||
	// Optional.  The protocol (TCP or UDP) which traffic must match.
 | 
			
		||||
	// If not specified, this field defaults to TCP.
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,15 @@ type NetworkPolicySpec struct {
 | 
			
		||||
	// solely to ensure that the pods it selects are isolated by default)
 | 
			
		||||
	// +optional
 | 
			
		||||
	Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,2,rep,name=ingress"`
 | 
			
		||||
 | 
			
		||||
	// List of egress rules to be applied to the selected pods. Outgoing traffic is
 | 
			
		||||
	// allowed if there are no NetworkPolicies selecting the pod (and cluster policy
 | 
			
		||||
	// otherwise allows the traffic), OR if the traffic matches at least one egress rule
 | 
			
		||||
	// across all of the NetworkPolicy objects whose podSelector matches the pod. If
 | 
			
		||||
	// this field is empty then this NetworkPolicy does not limit any outgoing traffic
 | 
			
		||||
	// (and serves solely to ensure that the pods it selects does not allow any outgoing traffic.)
 | 
			
		||||
	// +optional
 | 
			
		||||
	Egress []NetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,3,rep,name=egress"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods
 | 
			
		||||
@@ -79,6 +88,26 @@ type NetworkPolicyIngressRule struct {
 | 
			
		||||
	From []NetworkPolicyPeer `json:"from,omitempty" protobuf:"bytes,2,rep,name=from"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods
 | 
			
		||||
// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.
 | 
			
		||||
type NetworkPolicyEgressRule struct {
 | 
			
		||||
	// List of destination ports for outgoing traffic.
 | 
			
		||||
	// Each item in this list is combined using a logical OR. If this field is
 | 
			
		||||
	// empty or missing, this rule matches all ports (traffic not restricted by port).
 | 
			
		||||
	// If this field is present and contains at least one item, then this rule allows
 | 
			
		||||
	// traffic only if the traffic matches at least one port in the list.
 | 
			
		||||
	// +optional
 | 
			
		||||
	Ports []NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"`
 | 
			
		||||
 | 
			
		||||
	// List of destinations for outgoing traffic of pods selected for this rule.
 | 
			
		||||
	// Items in this list are combined using a logical OR operation. If this field is
 | 
			
		||||
	// empty or missing, this rule matches all destinations (traffic not restricted by
 | 
			
		||||
	// destination). If this field is present and contains at least one item, this rule
 | 
			
		||||
	// allows traffic only if the traffic matches at least one item in the to list.
 | 
			
		||||
	// +optional
 | 
			
		||||
	To []NetworkPolicyPeer `json:"to,omitempty" protobuf:"bytes,2,rep,name=to"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkPolicyPort describes a port to allow traffic on
 | 
			
		||||
type NetworkPolicyPort struct {
 | 
			
		||||
	// The protocol (TCP or UDP) which traffic must match. If not specified, this
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user