Allow including both podSelector and namespaceSelector in a NetworkPolicyPeer

This commit is contained in:
Dan Winship
2018-02-26 14:59:56 -05:00
parent 50b2b30526
commit 329639e9f6
5 changed files with 85 additions and 36 deletions

View File

@@ -159,22 +159,28 @@ type IPBlock struct {
Except []string Except []string
} }
// NetworkPolicyPeer describes a peer to allow traffic from. Exactly one of its fields // NetworkPolicyPeer describes a peer to allow traffic from.
// must be specified.
type NetworkPolicyPeer struct { type NetworkPolicyPeer struct {
// This is a label selector which selects Pods in this namespace. This field // This is a label selector which selects Pods. This field follows standard label
// follows standard label selector semantics. If present but empty, this selector // selector semantics; if present but empty, it selects all pods.
// selects all pods in this namespace. //
// If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.
// +optional // +optional
PodSelector *metav1.LabelSelector PodSelector *metav1.LabelSelector
// Selects Namespaces using cluster scoped-labels. This matches all pods in all // Selects Namespaces using cluster-scoped labels. This field follows standard label
// namespaces selected by this label selector. This field follows standard label // selector semantics; if present but empty, it selects all namespaces.
// selector semantics. If present but empty, this selector selects all namespaces. //
// If PodSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.
// +optional // +optional
NamespaceSelector *metav1.LabelSelector NamespaceSelector *metav1.LabelSelector
// IPBlock defines policy on a particular IPBlock // IPBlock defines policy on a particular IPBlock. If this field is set then
// neither of the other fields can be.
// +optional // +optional
IPBlock *IPBlock IPBlock *IPBlock
} }

View File

@@ -75,8 +75,8 @@ func ValidateNetworkPolicyPeer(peer *networking.NetworkPolicyPeer, peerPath *fie
if numPeers == 0 { if numPeers == 0 {
allErrs = append(allErrs, field.Required(peerPath, "must specify a peer")) allErrs = append(allErrs, field.Required(peerPath, "must specify a peer"))
} else if numPeers > 1 { } else if numPeers > 1 && peer.IPBlock != nil {
allErrs = append(allErrs, field.Forbidden(peerPath, "may not specify more than 1 peer")) allErrs = append(allErrs, field.Forbidden(peerPath, "may not specify both ipBlock and another peer"))
} }
return allErrs return allErrs

View File

@@ -122,6 +122,28 @@ 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{
{
NamespaceSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{"c": "d"},
},
PodSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{"e": "f"},
},
},
},
},
},
},
},
{ {
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
Spec: networking.NetworkPolicySpec{ Spec: networking.NetworkPolicySpec{
@@ -256,7 +278,7 @@ func TestValidateNetworkPolicy(t *testing.T) {
invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
errorCases := map[string]networking.NetworkPolicy{ errorCases := map[string]networking.NetworkPolicy{
"namespaceSelector and podSelector": { "namespaceSelector and ipBlock": {
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
Spec: networking.NetworkPolicySpec{ Spec: networking.NetworkPolicySpec{
PodSelector: metav1.LabelSelector{ PodSelector: metav1.LabelSelector{
@@ -266,16 +288,25 @@ func TestValidateNetworkPolicy(t *testing.T) {
{ {
From: []networking.NetworkPolicyPeer{ From: []networking.NetworkPolicyPeer{
{ {
PodSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{"c": "d"},
},
NamespaceSelector: &metav1.LabelSelector{ NamespaceSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{"c": "d"}, MatchLabels: map[string]string{"c": "d"},
}, },
IPBlock: &networking.IPBlock{
CIDR: "192.168.0.0/16",
Except: []string{"192.168.3.0/24", "192.168.4.0/24"},
},
}, },
}, },
}, },
}, },
},
},
"podSelector and ipBlock": {
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
Spec: networking.NetworkPolicySpec{
PodSelector: metav1.LabelSelector{
MatchLabels: map[string]string{"a": "b"},
},
Egress: []networking.NetworkPolicyEgressRule{ Egress: []networking.NetworkPolicyEgressRule{
{ {
To: []networking.NetworkPolicyPeer{ To: []networking.NetworkPolicyPeer{
@@ -283,8 +314,9 @@ func TestValidateNetworkPolicy(t *testing.T) {
PodSelector: &metav1.LabelSelector{ PodSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{"c": "d"}, MatchLabels: map[string]string{"c": "d"},
}, },
NamespaceSelector: &metav1.LabelSelector{ IPBlock: &networking.IPBlock{
MatchLabels: map[string]string{"c": "d"}, CIDR: "192.168.0.0/16",
Except: []string{"192.168.3.0/24", "192.168.4.0/24"},
}, },
}, },
}, },

View File

@@ -1256,22 +1256,26 @@ type IPBlock struct {
// DEPRECATED 1.9 - This group version of NetworkPolicyPeer is deprecated by networking/v1/NetworkPolicyPeer. // DEPRECATED 1.9 - This group version of NetworkPolicyPeer is deprecated by networking/v1/NetworkPolicyPeer.
type NetworkPolicyPeer struct { type NetworkPolicyPeer struct {
// Exactly one of the following must be specified. // This is a label selector which selects Pods. This field follows standard label
// selector semantics; if present but empty, it selects all pods.
// This is a label selector which selects Pods in this namespace. //
// This field follows standard label selector semantics. // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects
// If present but empty, this selector selects all pods in this namespace. // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.
// +optional // +optional
PodSelector *metav1.LabelSelector `json:"podSelector,omitempty" protobuf:"bytes,1,opt,name=podSelector"` PodSelector *metav1.LabelSelector `json:"podSelector,omitempty" protobuf:"bytes,1,opt,name=podSelector"`
// Selects Namespaces using cluster scoped-labels. This // Selects Namespaces using cluster-scoped labels. This field follows standard label
// matches all pods in all namespaces selected by this label selector. // selector semantics; if present but empty, it selects all namespaces.
// This field follows standard label selector semantics. //
// If present but empty, this selector selects all namespaces. // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.
// +optional // +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"` NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"`
// IPBlock defines policy on a particular IPBlock // IPBlock defines policy on a particular IPBlock. If this field is set then
// neither of the other fields can be.
// +optional // +optional
IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"` IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"`
} }

View File

@@ -161,22 +161,29 @@ type IPBlock struct {
Except []string `json:"except,omitempty" protobuf:"bytes,2,rep,name=except"` Except []string `json:"except,omitempty" protobuf:"bytes,2,rep,name=except"`
} }
// NetworkPolicyPeer describes a peer to allow traffic from. Exactly one of its fields // NetworkPolicyPeer describes a peer to allow traffic from. Only certain combinations of
// must be specified. // fields are allowed
type NetworkPolicyPeer struct { type NetworkPolicyPeer struct {
// This is a label selector which selects Pods in this namespace. This field // This is a label selector which selects Pods. This field follows standard label
// follows standard label selector semantics. If present but empty, this selector // selector semantics; if present but empty, it selects all pods.
// selects all pods in this namespace. //
// If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.
// +optional // +optional
PodSelector *metav1.LabelSelector `json:"podSelector,omitempty" protobuf:"bytes,1,opt,name=podSelector"` PodSelector *metav1.LabelSelector `json:"podSelector,omitempty" protobuf:"bytes,1,opt,name=podSelector"`
// Selects Namespaces using cluster scoped-labels. This matches all pods in all // Selects Namespaces using cluster-scoped labels. This field follows standard label
// namespaces selected by this label selector. This field follows standard label // selector semantics; if present but empty, it selects all namespaces.
// selector semantics. If present but empty, this selector selects all namespaces. //
// If PodSelector is also set, then the NetworkPolicyPeer as a whole selects
// the Pods matching PodSelector in the Namespaces selected by NamespaceSelector.
// Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.
// +optional // +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"` NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"`
// IPBlock defines policy on a particular IPBlock // IPBlock defines policy on a particular IPBlock. If this field is set then
// neither of the other fields can be.
// +optional // +optional
IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"` IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"`
} }