@@ -121,6 +121,13 @@ type PortRange struct {
121
121
}
122
122
123
123
// AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from.
124
+ //
125
+ // Note that presence of a Service object with this policy subject as its backend
126
+ // has no impact on the behavior of the policy applied to the peer
127
+ // trying to talk to the Service. It will work in the same way as if the
128
+ // Service didn't exist since policy is applied after ServiceVIP (clusterIP,
129
+ // externalIP, loadBalancerIngressVIP) is rewritten to the backendIPs.
130
+ //
124
131
// Exactly one of the selector pointers must be set for a given peer. If a
125
132
// consumer observes none of its fields are set, they must assume an unknown
126
133
// option has been specified and fail closed.
@@ -145,6 +152,13 @@ type AdminNetworkPolicyIngressPeer struct {
145
152
}
146
153
147
154
// AdminNetworkPolicyEgressPeer defines a peer to allow traffic to.
155
+ //
156
+ // Note that presence of a Service object with this peer as its backend
157
+ // has no impact on the behavior of the policy applied to the subject
158
+ // trying to talk to the Service. It will work in the same way as if the
159
+ // Service didn't exist since policy is applied after ServiceVIP (clusterIP,
160
+ // externalIP, loadBalancerIngressVIP) is rewritten to the backendIPs.
161
+ //
148
162
// Exactly one of the selector pointers must be set for a given peer. If a
149
163
// consumer observes none of its fields are set, they must assume an unknown
150
164
// option has been specified and fail closed.
@@ -175,6 +189,33 @@ type AdminNetworkPolicyEgressPeer struct {
175
189
// <network-policy-api:experimental>
176
190
// +optional
177
191
Nodes * metav1.LabelSelector `json:"nodes,omitempty"`
192
+ // Networks defines a way to select peers via CIDR blocks (both v4 & v6).
193
+ // This is intended for representing entities that live outside the cluster,
194
+ // which can't be selected by pods, namespaces and nodes peers, but note
195
+ // that cluster-internal traffic will be checked against the rule as
196
+ // well. So if you Allow or Deny traffic to `"0.0.0.0/0"`, that will allow
197
+ // or deny all IPv4 pod-to-pod traffic as well. If you don't want that,
198
+ // add a rule that Passes all pod traffic before the Networks rule.
199
+ //
200
+ // Do not provide serviceCIDR range in `networks` peer. This is NOT supported.
201
+ // While 0.0.0.0/0 will match on the serviceVIP as well, it does not make much sense
202
+ // anyways in that case because policies are expected to be applied after the serviceVIP
203
+ // (clusterIP, externalIP, loadbalancer.Ingress.VIP) is rewritten to the actual backend IPs.
204
+ // So policy match finally gets applied on the endpointIPs not serviceVIPs.
205
+ //
206
+ // Each item in Networks should be provided in the CIDR format and should be
207
+ // IPv4 or IPv6, for example "10.0.0.0/8" or "fd00::/8". IPv4 address embedded
208
+ // in IPv6 addresses are not supported.
209
+ //
210
+ // Networks can have upto 25 CIDRs specified.
211
+ //
212
+ // Support: Extended
213
+ //
214
+ // <network-policy-api:experimental>
215
+ // +optional
216
+ // +kubebuilder:validation:MinItems=1
217
+ // +kubebuilder:validation:MaxItems=25
218
+ Networks []CIDR `json:"networks,omitempty"`
178
219
}
179
220
180
221
// NamespacedPeer defines a flexible way to select Namespaces in a cluster.
@@ -237,3 +278,13 @@ type NamespacedPodPeer struct {
237
278
//
238
279
PodSelector metav1.LabelSelector `json:"podSelector"`
239
280
}
281
+
282
+ // CIDR is an IP address range in CIDR notation (for example, "10.0.0.0/8" or "fd00::/8").
283
+ // The regex for the IPv4 and IPv6 CIDR range was taken from
284
+ // https://blog.markhatton.co.uk/2011/03/15/regular-expressions-for-ip-addresses-cidr-ranges-and-hostnames/
285
+ // The resulting regex is an OR of both regexes. IPv4 address embedded in IPv6 addresses are not supported.
286
+ // TODO: Change the CIDR's validation regex to use CEL isCIDR() in Kube 1.31 when it is available.
287
+ // +kubebuilder:validation:Pattern=`(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$)|(^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))$)`
288
+ // +kubebuilder:validation:XValidation:rule="self.contains(':') != self.contains('.')",message="CIDR must be either an IPv4 or IPv6 address. IPv4 address embedded in IPv6 addresses are not supported"
289
+ // +kubebuilder:validation:MaxLength=43
290
+ type CIDR string
0 commit comments