Repository: kubernetes/kubernetes (language: go)

Issue:
CEL,CRD: Combining nested macros and CIDR containing another CIDR checks doesnt seem to work
### What happened?

Hi, I trying to use CEL validation on a CRD to verify a given subnet from one field is in range of subnets of another field, but it doesnt seem to work. Please see bellow details: 

The CRD has the following fields
```
subnets:
  description: ...
  items:
    maxLength: 43
    type: string
    x-kubernetes-validations:
    - message: CIDR is invalid
      rule: isCIDR(self)
  maxItems: 2
  minItems: 1
  type: array
  x-kubernetes-validations:
  - message: When 2 CIDRs are set, they must be from different
      IP families
    rule: size(self) != 2 || !isCIDR(self[0]) || !isCIDR(self[1])
      || cidr(self[0]).ip().family() != cidr(self[1]).ip().family()
excludeSubnets:
  description: ...
  items:
    maxLength: 43
    type: string
    x-kubernetes-validations:
    - message: CIDR is invalid
      rule: isCIDR(self)
  maxItems: 25
  minItems: 1
  type: array
```

Using the following rule, to verify each item in `excludeSubnets` is in range of at least one item in `subents`:
```
self.excludeSubnets.all(e, self.subnets.exists(s,cidr(s).containsCIDR(cidr(e))))
```
1. Given the following input the validation should block the request (return false): 
```
subnets: ["192.168.0.0/16"]
excludeSubnets: ["192.200.0.0/30", "192.300.0.1/32"]
```
2. Given the following input the validation should pass (return true): 
```
subnets: ["192.168.0.0/16"]
excludeSubnets: ["192.168.0.100/32", "192.168.0.1/32"]
```
The rule doesnt seem to work and result in blocking inputs (i.e.: return false in both cases).




### What did you expect to happen?

I expect the above CEL rule to work, it should return false for input (1), and return true for input (2).

### How can we reproduce it (as minimally and precisely as possible)?

Install the following CRD  [crd.md](https://github.com/user-attachments/files/18981991/crd.md)
Apply [cudn-should-fail.md](https://github.com/user-attachments/files/18985446/cudn-should-fail.md), expect failure.
Apply [cudn-should-pass.md](https://github.com/user-attachments/files/18981992/cudn-should-pass.md), expect success.

### Anything else we need to know?

It seem that nested macros work with more simple condition, please see this [CEL playground example](https://playcel.undistro.io/?content=H4sIAAAAAAAAA3WS22rCQBCGX2WaXqgQDy30RnojRWiLbaVSpJCbMRnjwmY37OxqpPTdOxsDYkECYTKH%2F%2FtnNz9JTjqZJuMxrEnntiLwFvyO4Gm%2BgKXGY%2BlsMMVNZqTlMgeKAQ0o48lh7tWeRGMzY6Zqo49Q2wM5KoDMXjlrKjI%2BalNTa%2BtIJosYk1Nt5aD87sS1VWUNzJvaEbOScIGmDFgS9IU%2FGEUnrZshrJ3yBEcbXGuNzjM7QXdNX0ytMDpCkFKMWRUEW%2BvEfB08FOgxlRi%2BZ28LkPTr6uM91iv0ncoyKkPvM5heu8UedcArcCxRGfYt6QzohObd%2FnEut1qTnJzM2K0oYFVr4s4Y18phrGXyUJPrUNAqbAx5HqHWfUqBu09qFHvucwoEj8AwGGQmSZNIfYl8ueBbeJYjiVd26erK1qMI7eSnmRnC3WTy30Wbf5icqvF9H3uEW9mCBBn%2FrN8%2FNsGsyWECAAA%3D) 

### Kubernetes version

<details>

```console
$ kubectl version
Client Version: v1.31.1
Kustomize Version: v5.4.2
Server Version: v1.31.1
```

</details>


### Cloud provider

<details>

</details>


### OS version

<details>

```console
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here
```

</details>


### Install tools

<details>

</details>


### Container runtime (CRI) and version (if applicable)

<details>

</details>


### Related plugins (CNI, CSI, ...) and versions (if applicable)

<details>

</details>



Discussion / hints:
/sig api-machinery

I've set up an example of this in the openshift API examples (we use this to test patterns), and as far as I can tell this does work, see the way I've implemented this here https://github.com/openshift/api/pull/2213

It's largely the same as your description but I had to change the `self.excludeSubnets.all(e, self.subnets.exists(s,cidr(s).containsCIDR(cidr(e))))` rule slightly to account for when `excludeSubnets` is not present

Fix patch:
diff --git a/staging/src/k8s.io/apiserver/pkg/cel/library/cidr.go b/staging/src/k8s.io/apiserver/pkg/cel/library/cidr.go
index 354c9c776ec54..a638fd4ac190a 100644
--- a/staging/src/k8s.io/apiserver/pkg/cel/library/cidr.go
+++ b/staging/src/k8s.io/apiserver/pkg/cel/library/cidr.go
@@ -229,8 +229,7 @@ func cidrContainsCIDR(arg ref.Val, other ref.Val) ref.Val {
 		return types.MaybeNoSuchOverloadErr(other)
 	}
 
-	equalMasked := cidr.Prefix.Masked() == netip.PrefixFrom(containsCIDR.Prefix.Addr(), cidr.Prefix.Bits())
-	return types.Bool(equalMasked && cidr.Prefix.Bits() <= containsCIDR.Prefix.Bits())
+	return types.Bool(cidr.Overlaps(containsCIDR.Prefix) && cidr.Prefix.Bits() <= containsCIDR.Prefix.Bits())
 }
 
 func prefixLength(arg ref.Val) ref.Val {


Test patch:
diff --git a/staging/src/k8s.io/apiserver/pkg/cel/library/cidr_test.go b/staging/src/k8s.io/apiserver/pkg/cel/library/cidr_test.go
index 938d5953b4df0..fc291551afa48 100644
--- a/staging/src/k8s.io/apiserver/pkg/cel/library/cidr_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/cel/library/cidr_test.go
@@ -151,11 +151,21 @@ func TestCIDR(t *testing.T) {
 			expr:         `cidr("192.168.0.0/24").containsCIDR(cidr("192.168.0.0/25"))`,
 			expectResult: trueVal,
 		},
+		{
+			name:         "contains CIDR ipv4 (CIDR) (/32)",
+			expr:         `cidr("192.168.0.0/24").containsCIDR(cidr("192.168.0.1/32"))`,
+			expectResult: trueVal,
+		},
 		{
 			name:         "does not contain IP ipv4 (CIDR)",
 			expr:         `cidr("192.168.0.0/24").containsCIDR(cidr("192.168.0.0/23"))`,
 			expectResult: falseVal,
 		},
+		{
+			name:         "does not contain IP ipv4 (CIDR) (/32)",
+			expr:         `cidr("192.168.0.0/24").containsCIDR(cidr("192.169.0.1/32"))`,
+			expectResult: falseVal,
+		},
 		{
 			name:         "contains CIDR ipv4 (string)",
 			expr:         `cidr("192.168.0.0/24").containsCIDR("192.168.0.0/25")`,