Repository: spidernet-io/spiderpool
Pull request #1345 (2023-02-20 10:05:18)

build(deps): bump github.com/onsi/ginkgo/v2 from 2.8.0 to 2.8.3
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.8.0 to 2.8.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/onsi/ginkgo/releases">github.com/onsi/ginkgo/v2's releases</a>.</em></p>
<blockquote>
<h2>v2.8.3</h2>
<h2>2.8.3</h2>
<p>Released to fix security issue in golang.org/x/net dependency</p>
<h3>Maintenance</h3>
<ul>
<li>Bump golang.org/x/net from 0.6.0 to 0.7.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1141">#1141</a>) [fc1a02e]</li>
<li>remove tools.go hack from documentation [0718693]</li>
</ul>
<h2>v2.8.2</h2>
<h2>2.8.2</h2>
<p>Ginkgo now includes a <code>tools.go</code> file in the root directory of the <code>ginkgo</code> package.  This should allow modules that simply <code>go get github.com/onsi/ginkgo/v2</code> to also pull in the CLI dependencies.  This obviates the need for consumers of Ginkgo to have their own <code>tools.go</code> file and makes it simpler to ensure that the version of the <code>ginkgo</code> CLI being used matches the version of the library.  You can simply run <code>go run github.com/onsi/ginkgo/v2/ginkgo</code> to run the version of the cli associated with your package go.mod.</p>
<h3>Maintenance</h3>
<ul>
<li>Bump github.com/onsi/gomega from 1.26.0 to 1.27.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1139">#1139</a>) [5767b0a]</li>
<li>Fix minor typos (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1138">#1138</a>) [e1e9723]</li>
<li>Fix link in V2 Migration Guide (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1137">#1137</a>) [a588f60]</li>
</ul>
<h2>v2.8.1</h2>
<h2>2.8.1</h2>
<h3>Fixes</h3>
<ul>
<li>lock around default report output to avoid triggering the race detector when calling By from goroutines [2d5075a]</li>
<li>don't run ReportEntries through sprintf [febbe38]</li>
</ul>
<h3>Maintenance</h3>
<ul>
<li>Bump golang.org/x/tools from 0.5.0 to 0.6.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1135">#1135</a>) [11a4860]</li>
<li>test: update matrix for Go 1.20 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1130">#1130</a>) [4890a62]</li>
<li>Bump golang.org/x/sys from 0.4.0 to 0.5.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1133">#1133</a>) [a774638]</li>
<li>Bump github.com/onsi/gomega from 1.25.0 to 1.26.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1120">#1120</a>) [3f233bd]</li>
<li>Bump github-pages from 227 to 228 in /docs (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1131">#1131</a>) [f9b8649]</li>
<li>Bump activesupport from 6.0.6 to 6.0.6.1 in /docs (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1127">#1127</a>) [6f8c042]</li>
<li>Update index.md with instructions on how to upgrade Ginkgo [833a75e]</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md">github.com/onsi/ginkgo/v2's changelog</a>.</em></p>
<blockquote>
<h2>2.8.3</h2>
<p>Released to fix security issue in golang.org/x/net dependency</p>
<h3>Maintenance</h3>
<ul>
<li>Bump golang.org/x/net from 0.6.0 to 0.7.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1141">#1141</a>) [fc1a02e]</li>
<li>remove tools.go hack from documentation [0718693]</li>
</ul>
<h2>2.8.2</h2>
<p>Ginkgo now includes a <code>tools.go</code> file in the root directory of the <code>ginkgo</code> package.  This should allow modules that simply <code>go get github.com/onsi/ginkgo/v2</code> to also pull in the CLI dependencies.  This obviates the need for consumers of Ginkgo to have their own <code>tools.go</code> file and makes it simpler to ensure that the version of the <code>ginkgo</code> CLI being used matches the version of the library.  You can simply run <code>go run github.com/onsi/ginkgo/v2/ginkgo</code> to run the version of the cli associated with your package go.mod.</p>
<h3>Maintenance</h3>
<ul>
<li>Bump github.com/onsi/gomega from 1.26.0 to 1.27.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1139">#1139</a>) [5767b0a]</li>
<li>Fix minor typos (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1138">#1138</a>) [e1e9723]</li>
<li>Fix link in V2 Migration Guide (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1137">#1137</a>) [a588f60]</li>
</ul>
<h2>2.8.1</h2>
<h3>Fixes</h3>
<ul>
<li>lock around default report output to avoid triggering the race detector when calling By from goroutines [2d5075a]</li>
<li>don't run ReportEntries through sprintf [febbe38]</li>
</ul>
<h3>Maintenance</h3>
<ul>
<li>Bump golang.org/x/tools from 0.5.0 to 0.6.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1135">#1135</a>) [11a4860]</li>
<li>test: update matrix for Go 1.20 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1130">#1130</a>) [4890a62]</li>
<li>Bump golang.org/x/sys from 0.4.0 to 0.5.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1133">#1133</a>) [a774638]</li>
<li>Bump github.com/onsi/gomega from 1.25.0 to 1.26.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1120">#1120</a>) [3f233bd]</li>
<li>Bump github-pages from 227 to 228 in /docs (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1131">#1131</a>) [f9b8649]</li>
<li>Bump activesupport from 6.0.6 to 6.0.6.1 in /docs (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1127">#1127</a>) [6f8c042]</li>
<li>Update index.md with instructions on how to upgrade Ginkgo [833a75e]</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/onsi/ginkgo/commit/02875615161399a309839fbf3ae019c6f87dd33d"><code>0287561</code></a> v2.8.3</li>
<li><a href="https://github.com/onsi/ginkgo/commit/fc1a02e17d0e0e41c84cfab91bd4d2bd5615370e"><code>fc1a02e</code></a> Bump golang.org/x/net from 0.6.0 to 0.7.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1141">#1141</a>)</li>
<li><a href="https://github.com/onsi/ginkgo/commit/0718693ff7f084ae4eccb8a1c7f15c906cc82162"><code>0718693</code></a> remove tools.go hack from documentation</li>
<li><a href="https://github.com/onsi/ginkgo/commit/cca66a86b668bda0ddab325c10f07de29678e0b1"><code>cca66a8</code></a> v2.8.2</li>
<li><a href="https://github.com/onsi/ginkgo/commit/f05681c5ec1269d679d2e736dbd78e25ca015187"><code>f05681c</code></a> exploring to see whether adding a tools.go to ginkgo proper will cause consum...</li>
<li><a href="https://github.com/onsi/ginkgo/commit/5767b0a4257c8ba58fe6ed9606c72d49f50dee39"><code>5767b0a</code></a> Bump github.com/onsi/gomega from 1.26.0 to 1.27.0 (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1139">#1139</a>)</li>
<li><a href="https://github.com/onsi/ginkgo/commit/e1e9723e3a3c51dd7e24459046f49ce14c0600fc"><code>e1e9723</code></a> Fix minor typos (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1138">#1138</a>)</li>
<li><a href="https://github.com/onsi/ginkgo/commit/a588f6064512ed4ba26a8821fb5f2b37df55aa78"><code>a588f60</code></a> Fix link in V2 Migration Guide (<a href="https://github-redirect.dependabot.com/onsi/ginkgo/issues/1137">#1137</a>)</li>
<li><a href="https://github.com/onsi/ginkgo/commit/c7e3ebe32b1aca0fc3b32d385c828fb11cbeafbf"><code>c7e3ebe</code></a> v2.8.1</li>
<li><a href="https://github.com/onsi/ginkgo/commit/2d5075afb8bbe53a62060d2c2028c15b653aae38"><code>2d5075a</code></a> lock around default report output to avoid triggering the race detector when ...</li>
<li>Additional commits viewable in <a href="https://github.com/onsi/ginkgo/compare/v2.8.0...v2.8.3">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/onsi/ginkgo/v2&package-manager=go_modules&previous-version=2.8.0&new-version=2.8.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/go.mod b/go.mod
index 2ec6ce726..367672ce6 100644
--- a/go.mod
+++ b/go.mod
@@ -17,8 +17,8 @@ require (
 	github.com/gogo/protobuf v1.3.2
 	github.com/google/gops v0.3.26
 	github.com/jessevdk/go-flags v1.5.0
-	github.com/onsi/ginkgo/v2 v2.8.0
-	github.com/onsi/gomega v1.25.0
+	github.com/onsi/ginkgo/v2 v2.8.3
+	github.com/onsi/gomega v1.27.0
 	github.com/pyroscope-io/client v0.6.0
 	github.com/sasha-s/go-deadlock v0.3.1
 	github.com/spf13/cobra v1.6.1
diff --git a/go.sum b/go.sum
index 100d816f5..c646ff82f 100644
--- a/go.sum
+++ b/go.sum
@@ -464,13 +464,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
-github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI=
-github.com/onsi/ginkgo/v2 v2.8.0/go.mod h1:6JsQiECmxCa3V5st74AL/AmsV482EDdVrGaVW6z3oYU=
+github.com/onsi/ginkgo/v2 v2.8.3 h1:RpbK1G8nWPNaCVFBWsOGnEQQGgASi6b8fxcWBvDYjxQ=
+github.com/onsi/ginkgo/v2 v2.8.3/go.mod h1:6OaUA8BCi0aZfmzYT/q9AacwTzDpNbxILUT+TlBq6MY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
-github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y=
-github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
+github.com/onsi/gomega v1.27.0 h1:QLidEla4bXUuZVFa4KX6JHCsuGgbi85LC/pCHrt/O08=
+github.com/onsi/gomega v1.27.0/go.mod h1:i189pavgK95OSIipFBa74gC2V4qrQuvjuyGEr3GmbXA=
 github.com/openkruise/kruise-api v1.3.0 h1:yfEy64uXgSuX/5RwePLbwUK/uX8RRM8fHJkccel5ZIQ=
 github.com/openkruise/kruise-api v1.3.0/go.mod h1:9ZX+ycdHKNzcA5ezAf35xOa2Mwfa2BYagWr0lKgi5dU=
 github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
diff --git a/pkg/ip/ip.go b/pkg/ip/ip.go
index 7278be1ef..1d576c227 100644
--- a/pkg/ip/ip.go
+++ b/pkg/ip/ip.go
@@ -80,9 +80,7 @@ func IsIP(version types.IPVersion, s string) error {
 // IPsDiffSet calculates the difference set of two IP address slices.
 // For example, the difference set between [172.18.40.1 172.18.40.2] and
 // [172.18.40.2 172.18.40.3] is [172.18.40.1].
-//
-// If sorted is true, the result set of IP addresses will be sorted.
-func IPsDiffSet(ips1, ips2 []net.IP, sorted bool) []net.IP {
+func IPsDiffSet(ips1, ips2 []net.IP) []net.IP {
 	var ips []net.IP
 	marks := make(map[string]bool)
 	for _, ip := range ips1 {
@@ -101,11 +99,9 @@ func IPsDiffSet(ips1, ips2 []net.IP, sorted bool) []net.IP {
 		ips = append(ips, net.ParseIP(k))
 	}
 
-	if sorted {
-		sort.Slice(ips, func(i, j int) bool {
-			return bytes.Compare(ips[i].To16(), ips[j].To16()) < 0
-		})
-	}
+	sort.Slice(ips, func(i, j int) bool {
+		return bytes.Compare(ips[i].To16(), ips[j].To16()) < 0
+	})
 
 	return ips
 }
@@ -113,9 +109,7 @@ func IPsDiffSet(ips1, ips2 []net.IP, sorted bool) []net.IP {
 // IPsUnionSet calculates the union set of two IP address slices.
 // For example, the union set between [172.18.40.1 172.18.40.2] and
 // [172.18.40.2 172.18.40.3] is [172.18.40.1 172.18.40.2 172.18.40.3].
-//
-// If sorted is true, the result set of IP addresses will be sorted.
-func IPsUnionSet(ips1, ips2 []net.IP, sorted bool) []net.IP {
+func IPsUnionSet(ips1, ips2 []net.IP) []net.IP {
 	var ips []net.IP
 	marks := make(map[string]bool)
 	ips1 = append(ips1, ips2...)
@@ -129,11 +123,9 @@ func IPsUnionSet(ips1, ips2 []net.IP, sorted bool) []net.IP {
 		ips = append(ips, net.ParseIP(k))
 	}
 
-	if sorted {
-		sort.Slice(ips, func(i, j int) bool {
-			return bytes.Compare(ips[i].To16(), ips[j].To16()) < 0
-		})
-	}
+	sort.Slice(ips, func(i, j int) bool {
+		return bytes.Compare(ips[i].To16(), ips[j].To16()) < 0
+	})
 
 	return ips
 }
@@ -141,9 +133,7 @@ func IPsUnionSet(ips1, ips2 []net.IP, sorted bool) []net.IP {
 // IPsIntersectionSet calculates the intersection set of two IP address
 // slices. For example, the intersection set between [172.18.40.1 172.18.40.2]
 // and [172.18.40.2 172.18.40.3] is [172.18.40.2].
-//
-// If sorted is true, the result set of IP addresses will be sorted.
-func IPsIntersectionSet(ips1, ips2 []net.IP, sorted bool) []net.IP {
+func IPsIntersectionSet(ips1, ips2 []net.IP) []net.IP {
 	var ips []net.IP
 	set := make(map[string]bool)
 	for _, ip := range ips1 {
@@ -163,11 +153,9 @@ func IPsIntersectionSet(ips1, ips2 []net.IP, sorted bool) []net.IP {
 		ips = append(ips, net.ParseIP(k))
 	}
 
-	if sorted {
-		sort.Slice(ips, func(i, j int) bool {
-			return bytes.Compare(ips[i].To16(), ips[j].To16()) < 0
-		})
-	}
+	sort.Slice(ips, func(i, j int) bool {
+		return bytes.Compare(ips[i].To16(), ips[j].To16()) < 0
+	})
 
 	return ips
 }
diff --git a/pkg/ip/iprange.go b/pkg/ip/iprange.go
index 2f0d5aed8..905717889 100644
--- a/pkg/ip/iprange.go
+++ b/pkg/ip/iprange.go
@@ -158,7 +158,7 @@ func IsIPRangeOverlap(version types.IPVersion, ipRange1, ipRange2 string) (bool,
 	// verified in IsIPRange above.
 	ips1, _ := ParseIPRange(version, ipRange1)
 	ips2, _ := ParseIPRange(version, ipRange2)
-	if len(ips1) > len(IPsDiffSet(ips1, ips2, false)) {
+	if len(ips1) > len(IPsDiffSet(ips1, ips2)) {
 		return true, nil
 	}
 
diff --git a/pkg/ip/utils.go b/pkg/ip/utils.go
index 7178bfc87..773d1a30a 100644
--- a/pkg/ip/utils.go
+++ b/pkg/ip/utils.go
@@ -19,7 +19,7 @@ func AssembleTotalIPs(ipVersion types.IPVersion, ipRanges, excludedIPRanges []st
 	if nil != err {
 		return nil, err
 	}
-	totalIPs := IPsDiffSet(ips, excludeIPs, false)
+	totalIPs := IPsDiffSet(ips, excludeIPs)
 
 	return totalIPs, nil
 }
diff --git a/pkg/ippoolmanager/ippool_informer.go b/pkg/ippoolmanager/ippool_informer.go
index 97f6cdb22..7c4e4f001 100644
--- a/pkg/ippoolmanager/ippool_informer.go
+++ b/pkg/ippoolmanager/ippool_informer.go
@@ -497,7 +497,7 @@ func (ic *IPPoolController) scaleIPPoolIfNeeded(ctx context.Context, pool *spide
 			if nil != err {
 				return fmt.Errorf("%w: failed to parse IP ranges '%v', error: %v", constant.ErrWrongInput, allocatedIPRanges, err)
 			}
-			freeIPs := spiderpoolip.IPsDiffSet(totalIPs, allocatedIPs, true)
+			freeIPs := spiderpoolip.IPsDiffSet(totalIPs, allocatedIPs)
 			discardedIPs := freeIPs[:totalIPCount-desiredIPNum]
 			discardedIPRanges, err := spiderpoolip.ConvertIPsToIPRanges(*pool.Spec.IPVersion, discardedIPs)
 			if nil != err {
@@ -756,7 +756,7 @@ func (ic *IPPoolController) scaleIPPoolWithIPs(ctx context.Context, pool *spider
 			return fmt.Errorf("failed to parse IP ranges '%v', error: %v", pool.Spec.IPs, err)
 		}
 
-		sortedIPRanges, err := spiderpoolip.ConvertIPsToIPRanges(*pool.Spec.IPVersion, spiderpoolip.IPsDiffSet(totalIPs, discardedIPs, false))
+		sortedIPRanges, err := spiderpoolip.ConvertIPsToIPRanges(*pool.Spec.IPVersion, spiderpoolip.IPsDiffSet(totalIPs, discardedIPs))
 		if nil != err {
 			return fmt.Errorf("failed to convert IPs '%v' to IP ranges, error: %v", ipRanges, err)
 		}
@@ -822,7 +822,7 @@ func (ic *IPPoolController) generateIPsFromSubnetWhenScaleUpIP(ctx context.Conte
 		// the subnetPoolAllocatedIPs is greater than pool total IP counts indicates that
 		// the SpiderSubnet updated successfully but the IPPool failed to update in the last procession
 		if len(subnetPoolAllocatedIPs) > len(poolTotalIPs) {
-			lastAllocatedIPs := spiderpoolip.IPsDiffSet(subnetPoolAllocatedIPs, poolTotalIPs, false)
+			lastAllocatedIPs := spiderpoolip.IPsDiffSet(subnetPoolAllocatedIPs, poolTotalIPs)
 			log.Sugar().Warnf("SpiderSubnet '%s' Status ControlledIPPool '%s' has the allocated IPs '%v', try to re-use it!", subnetName, pool.Name, lastAllocatedIPs)
 			if len(lastAllocatedIPs) == desiredIPNum-len(poolTotalIPs) {
 				// last allocated IPs is same with the current allocation request
@@ -853,7 +853,7 @@ func (ic *IPPoolController) generateIPsFromSubnetWhenScaleUpIP(ctx context.Conte
 	}
 
 	if len(reservedIPs) != 0 {
-		freeIPs = spiderpoolip.IPsDiffSet(freeIPs, reservedIPs, true)
+		freeIPs = spiderpoolip.IPsDiffSet(freeIPs, reservedIPs)
 	}
 
 	if len(pool.Spec.ExcludeIPs) != 0 {
@@ -861,7 +861,7 @@ func (ic *IPPoolController) generateIPsFromSubnetWhenScaleUpIP(ctx context.Conte
 		if nil != err {
 			return nil, fmt.Errorf("failed to parse exclude IP ranges '%v', error: %v", pool.Spec.ExcludeIPs, err)
 		}
-		freeIPs = spiderpoolip.IPsDiffSet(freeIPs, excludeIPs, true)
+		freeIPs = spiderpoolip.IPsDiffSet(freeIPs, excludeIPs)
 	}
 
 	// check the filtered subnet free IP number is enough or not
diff --git a/pkg/ippoolmanager/ippool_manager.go b/pkg/ippoolmanager/ippool_manager.go
index 3c515ab4e..04d778f02 100644
--- a/pkg/ippoolmanager/ippool_manager.go
+++ b/pkg/ippoolmanager/ippool_manager.go
@@ -163,7 +163,7 @@ func (im *ipPoolManager) genRandomIP(ctx context.Context, ipPool *spiderpoolv1.S
 		return nil, err
 	}
 
-	availableIPs := spiderpoolip.IPsDiffSet(totalIPs, append(reservedIPs, usedIPs...), false)
+	availableIPs := spiderpoolip.IPsDiffSet(totalIPs, append(reservedIPs, usedIPs...))
 	if len(availableIPs) == 0 {
 		return nil, constant.ErrIPUsedOut
 	}
diff --git a/pkg/ippoolmanager/ippool_subnet_validate.go b/pkg/ippoolmanager/ippool_subnet_validate.go
index 4d08921ac..5c661d0e4 100644
--- a/pkg/ippoolmanager/ippool_subnet_validate.go
+++ b/pkg/ippoolmanager/ippool_subnet_validate.go
@@ -86,7 +86,7 @@ func validateSubnetTotalIPsContainsIPPoolTotalIPs(subnet *spiderpoolv1.SpiderSub
 		return field.InternalError(ipsField, fmt.Errorf("failed to assemble the total IP addresses of the Subnet %s: %v", subnet.Name, err))
 	}
 
-	outIPs := spiderpoolip.IPsDiffSet(poolTotalIPs, subnetTotalIPs, false)
+	outIPs := spiderpoolip.IPsDiffSet(poolTotalIPs, subnetTotalIPs)
 	if len(outIPs) > 0 {
 		ranges, _ := spiderpoolip.ConvertIPsToIPRanges(*ipPool.Spec.IPVersion, outIPs)
 		return field.Forbidden(
diff --git a/pkg/ippoolmanager/ippool_validate.go b/pkg/ippoolmanager/ippool_validate.go
index f8adac9d3..084322efa 100644
--- a/pkg/ippoolmanager/ippool_validate.go
+++ b/pkg/ippoolmanager/ippool_validate.go
@@ -243,7 +243,7 @@ func (iw *IPPoolWebhook) validateIPPoolAvailableIPs(ctx context.Context, ipPool
 				return field.InternalError(ipsField, fmt.Errorf("failed to assemble the total IP addresses of the existing IPPool %s: %v", pool.Name, err))
 			}
 
-			overlapIPs := spiderpoolip.IPsIntersectionSet(newIPs, existIPs, false)
+			overlapIPs := spiderpoolip.IPsIntersectionSet(newIPs, existIPs)
 			if len(overlapIPs) > 0 {
 				overlapRanges, _ := spiderpoolip.ConvertIPsToIPRanges(*pool.Spec.IPVersion, overlapIPs)
 				return field.Forbidden(
diff --git a/pkg/subnetmanager/controllers/utils.go b/pkg/subnetmanager/controllers/utils.go
index 07716f53e..048f8b1af 100644
--- a/pkg/subnetmanager/controllers/utils.go
+++ b/pkg/subnetmanager/controllers/utils.go
@@ -80,7 +80,7 @@ func GenSubnetFreeIPs(subnet *spiderpoolv1.SpiderSubnet) ([]net.IP, error) {
 	if err != nil {
 		return nil, err
 	}
-	freeIPs := spiderpoolip.IPsDiffSet(totalIPs, usedIPs, true)
+	freeIPs := spiderpoolip.IPsDiffSet(totalIPs, usedIPs)
 
 	return freeIPs, nil
 }
diff --git a/pkg/subnetmanager/subnet_informer.go b/pkg/subnetmanager/subnet_informer.go
index 9e147e9a7..a1e64b548 100644
--- a/pkg/subnetmanager/subnet_informer.go
+++ b/pkg/subnetmanager/subnet_informer.go
@@ -338,7 +338,7 @@ func (sc *SubnetController) syncControlledIPPoolIPs(ctx context.Context, subnet
 			return err
 		}
 
-		validIPs := spiderpoolip.IPsIntersectionSet(subnetTotalIPs, poolTotalIPs, false)
+		validIPs := spiderpoolip.IPsIntersectionSet(subnetTotalIPs, poolTotalIPs)
 		tmpCount += len(validIPs)
 
 		ranges, err := spiderpoolip.ConvertIPsToIPRanges(*pool.Spec.IPVersion, validIPs)
diff --git a/pkg/subnetmanager/subnet_validate.go b/pkg/subnetmanager/subnet_validate.go
index f41534adc..be4894ab3 100644
--- a/pkg/subnetmanager/subnet_validate.go
+++ b/pkg/subnetmanager/subnet_validate.go
@@ -117,7 +117,7 @@ func validateSubnetIPInUse(subnet *spiderpoolv1.SpiderSubnet) *field.Error {
 		if err != nil {
 			return field.InternalError(controlledIPPoolsField, fmt.Errorf("failed to parse the pre-allocation of the IPPool %s: %v", poolName, err))
 		}
-		invalidIPs := spiderpoolip.IPsDiffSet(poolTotalIPs, totalIPs, false)
+		invalidIPs := spiderpoolip.IPsDiffSet(poolTotalIPs, totalIPs)
 		if len(invalidIPs) > 0 {
 			ranges, _ := spiderpoolip.ConvertIPsToIPRanges(*subnet.Spec.IPVersion, invalidIPs)
 			return field.Forbidden(
diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
index 5eb133228..a77e95e25 100644
--- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
+++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
@@ -1,3 +1,37 @@
+## 2.8.3
+
+Released to fix security issue in golang.org/x/net dependency
+
+### Maintenance
+
+- Bump golang.org/x/net from 0.6.0 to 0.7.0 (#1141) [fc1a02e]
+- remove tools.go hack from documentation [0718693]
+
+## 2.8.2
+
+Ginkgo now includes a `tools.go` file in the root directory of the `ginkgo` package.  This should allow modules that simply `go get github.com/onsi/ginkgo/v2` to also pull in the CLI dependencies.  This obviates the need for consumers of Ginkgo to have their own `tools.go` file and makes it simpler to ensure that the version of the `ginkgo` CLI being used matches the version of the library.  You can simply run `go run github.com/onsi/ginkgo/v2/ginkgo` to run the version of the cli associated with your package go.mod.
+
+### Maintenance
+
+- Bump github.com/onsi/gomega from 1.26.0 to 1.27.0 (#1139) [5767b0a]
+- Fix minor typos (#1138) [e1e9723]
+- Fix link in V2 Migration Guide (#1137) [a588f60]
+
+## 2.8.1
+
+### Fixes
+- lock around default report output to avoid triggering the race detector when calling By from goroutines [2d5075a]
+- don't run ReportEntries through sprintf [febbe38]
+
+### Maintenance
+- Bump golang.org/x/tools from 0.5.0 to 0.6.0 (#1135) [11a4860]
+- test: update matrix for Go 1.20 (#1130) [4890a62]
+- Bump golang.org/x/sys from 0.4.0 to 0.5.0 (#1133) [a774638]
+- Bump github.com/onsi/gomega from 1.25.0 to 1.26.0 (#1120) [3f233bd]
+- Bump github-pages from 227 to 228 in /docs (#1131) [f9b8649]
+- Bump activesupport from 6.0.6 to 6.0.6.1 in /docs (#1127) [6f8c042]
+- Update index.md with instructions on how to upgrade Ginkgo [833a75e]
+
 ## 2.8.0
 
 ### Features
@@ -149,7 +183,7 @@ to build tooling on top of as it has stronger guarantees to be stable from versi
 
 ### Fixes
 - correcting some typos (#1064) [1403d3c]
-- fix flaky internal_integration interupt specs [2105ba3]
+- fix flaky internal_integration interrupt specs [2105ba3]
 - Correct busted link in README [be6b5b9]
 
 ### Maintenance
diff --git a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
index 5e78a92f3..0b13b0d22 100644
--- a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
@@ -92,11 +92,11 @@ type GinkgoWriterInterface interface {
 }
 
 /*
-SpecContext is the context object passed into nodes that are subject to a timeout or need to be notified of an interrupt.  It implements the standard context.Context interface but also contains additional helpers to provide an extensibility point for Ginkgo.  (As an example, Gomega's Eventually can use the methods defined on SpecContext to provide deeper integratoin with Ginkgo).
+SpecContext is the context object passed into nodes that are subject to a timeout or need to be notified of an interrupt.  It implements the standard context.Context interface but also contains additional helpers to provide an extensibility point for Ginkgo.  (As an example, Gomega's Eventually can use the methods defined on SpecContext to provide deeper integration with Ginkgo).
 
 You can do anything with SpecContext that you do with a typical context.Context including wrapping it with any of the context.With* methods.
 
-Ginkgo will cancel the SpecContext when a node is interrupted (e.g. by the user sending an interupt signal) or when a node has exceeded it's allowed run-time.  Note, however, that even in cases where a node has a deadline, SpecContext will not return a deadline via .Deadline().  This is because Ginkgo does not use a WithDeadline() context to model node deadlines as Ginkgo needs control over the precise timing of the context cancellation to ensure it can provide an accurate progress report at the moment of cancellation.
+Ginkgo will cancel the SpecContext when a node is interrupted (e.g. by the user sending an interrupt signal) or when a node has exceeded its allowed run-time.  Note, however, that even in cases where a node has a deadline, SpecContext will not return a deadline via .Deadline().  This is because Ginkgo does not use a WithDeadline() context to model node deadlines as Ginkgo needs control over the precise timing of the context cancellation to ensure it can provide an accurate progress report at the moment of cancellation.
 */
 type SpecContext = internal.SpecContext
 
@@ -743,7 +743,7 @@ For example:
 	    os.SetEnv("FOO", "BAR")
 	})
 
-will register a cleanup handler that will set the environment variable "FOO" to it's current value (obtained by os.GetEnv("FOO")) after the spec runs and then sets the environment variable "FOO" to "BAR" for the current spec.
+will register a cleanup handler that will set the environment variable "FOO" to its current value (obtained by os.GetEnv("FOO")) after the spec runs and then sets the environment variable "FOO" to "BAR" for the current spec.
 
 Similarly:
 
diff --git a/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go b/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
index ece35d17b..743555dde 100644
--- a/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
@@ -120,7 +120,10 @@ func (f Formatter) Fi(indentation uint, format string, args ...interface{}) stri
 }
 
 func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
-	out := fmt.Sprintf(f.style(format), args...)
+	out := f.style(format)
+	if len(args) > 0 {
+		out = fmt.Sprintf(out, args...)
+	}
 
 	if indentation == 0 && maxWidth == 0 {
 		return out
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
index 7a27220ca..56b7be758 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
@@ -12,6 +12,7 @@ import (
 	"io"
 	"runtime"
 	"strings"
+	"sync"
 	"time"
 
 	"github.com/onsi/ginkgo/v2/formatter"
@@ -23,7 +24,7 @@ type DefaultReporter struct {
 	writer io.Writer
 
 	// managing the emission stream
-	lastChar                 string
+	lastCharWasNewline       bool
 	lastEmissionWasDelimiter bool
 
 	// rendering
@@ -32,6 +33,7 @@ type DefaultReporter struct {
 	formatter    formatter.Formatter
 
 	runningInParallel bool
+	lock              *sync.Mutex
 }
 
 func NewDefaultReporterUnderTest(conf types.ReporterConfig, writer io.Writer) *DefaultReporter {
@@ -46,12 +48,13 @@ func NewDefaultReporter(conf types.ReporterConfig, writer io.Writer) *DefaultRep
 		conf:   conf,
 		writer: writer,
 
-		lastChar:                 "\n",
+		lastCharWasNewline:       true,
 		lastEmissionWasDelimiter: false,
 
 		specDenoter:  "•",
 		retryDenoter: "↺",
 		formatter:    formatter.NewWithNoColorBool(conf.NoColor),
+		lock:         &sync.Mutex{},
 	}
 	if runtime.GOOS == "windows" {
 		reporter.specDenoter = "+"
@@ -528,7 +531,7 @@ func (r *DefaultReporter) EmitReportEntry(entry types.ReportEntry) {
 }
 
 func (r *DefaultReporter) emitReportEntry(indent uint, entry types.ReportEntry) {
-	r.emitBlock(r.fi(indent, "{{bold}}"+entry.Name+"{{gray}} - %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT)))
+	r.emitBlock(r.fi(indent, "{{bold}}"+entry.Name+"{{gray}} "+fmt.Sprintf("- %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT))))
 	if representation := entry.StringRepresentation(); representation != "" {
 		r.emitBlock(r.fi(indent+1, representation))
 	}
@@ -619,31 +622,37 @@ func (r *DefaultReporter) emitSource(indent uint, fc types.FunctionCall) {
 
 /* Emitting to the writer */
 func (r *DefaultReporter) emit(s string) {
-	if len(s) > 0 {
-		r.lastChar = s[len(s)-1:]
-		r.lastEmissionWasDelimiter = false
-		r.writer.Write([]byte(s))
-	}
+	r._emit(s, false, false)
 }
 
 func (r *DefaultReporter) emitBlock(s string) {
-	if len(s) > 0 {
-		if r.lastChar != "\n" {
-			r.emit("\n")
-		}
-		r.emit(s)
-		if r.lastChar != "\n" {
-			r.emit("\n")
-		}
-	}
+	r._emit(s, true, false)
 }
 
 func (r *DefaultReporter) emitDelimiter(indent uint) {
-	if r.lastEmissionWasDelimiter {
+	r._emit(r.fi(indent, "{{gray}}%s{{/}}", strings.Repeat("-", 30)), true, true)
+}
+
+// a bit ugly - but we're trying to minimize locking on this hot codepath
+func (r *DefaultReporter) _emit(s string, block bool, isDelimiter bool) {
+	if len(s) == 0 {
+		return
+	}
+	r.lock.Lock()
+	defer r.lock.Unlock()
+	if isDelimiter && r.lastEmissionWasDelimiter {
 		return
 	}
-	r.emitBlock(r.fi(indent, "{{gray}}%s{{/}}", strings.Repeat("-", 30)))
-	r.lastEmissionWasDelimiter = true
+	if block && !r.lastCharWasNewline {
+		r.writer.Write([]byte("\n"))
+	}
+	r.lastCharWasNewline = (s[len(s)-1:] == "\n")
+	r.writer.Write([]byte(s))
+	if block && !r.lastCharWasNewline {
+		r.writer.Write([]byte("\n"))
+		r.lastCharWasNewline = true
+	}
+	r.lastEmissionWasDelimiter = isDelimiter
 }
 
 /* Rendering text */
diff --git a/vendor/github.com/onsi/ginkgo/v2/tools.go b/vendor/github.com/onsi/ginkgo/v2/tools.go
new file mode 100644
index 000000000..974294467
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/tools.go
@@ -0,0 +1,8 @@
+//go:build tools
+// +build tools
+
+package ginkgo
+
+import (
+	_ "github.com/onsi/ginkgo/v2/ginkgo"
+)
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go
index c59837b4c..185317c63 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/version.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go
@@ -1,3 +1,3 @@
 package types
 
-const VERSION = "2.8.0"
+const VERSION = "2.8.3"
diff --git a/vendor/github.com/onsi/gomega/.gitignore b/vendor/github.com/onsi/gomega/.gitignore
index 5f12ff053..52266eae1 100644
--- a/vendor/github.com/onsi/gomega/.gitignore
+++ b/vendor/github.com/onsi/gomega/.gitignore
@@ -3,4 +3,5 @@
 .
 .idea
 gomega.iml
-TODO.md
\ No newline at end of file
+TODO.md
+.vscode
\ No newline at end of file
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index 2757441e8..aaa51dfff 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,29 @@
+## 1.27.0
+
+### Features
+- Add HaveExactElements matcher (#634) [9d50783]
+- update Gomega docs to discuss GinkgoHelper() [be32774]
+
+### Maintenance
+- Bump github.com/onsi/ginkgo/v2 from 2.8.0 to 2.8.1 (#639) [296a68b]
+- Bump golang.org/x/net from 0.5.0 to 0.6.0 (#638) [c2b098b]
+- Bump github-pages from 227 to 228 in /docs (#636) [a9069ab]
+- test: update matrix for Go 1.20 (#635) [6bd25c8]
+- Bump github.com/onsi/ginkgo/v2 from 2.7.0 to 2.8.0 (#631) [5445f8b]
+- Bump webrick from 1.7.0 to 1.8.1 in /docs (#630) [03e93bb]
+- codeql: add ruby language (#626) [63c7d21]
+- dependabot: add bundler package-ecosystem for docs (#625) [d92f963]
+
+## 1.26.0
+
+### Features
+- When a polled function returns an error, keep track of the actual and report on the matcher state of the last non-errored actual [21f3090]
+- improve eventually failure message output [c530fb3]
+
+### Fixes
+- fix several documentation spelling issues [e2eff1f]
+
+
 ## 1.25.0
 
 ### Features
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index 3076b277b..d56a892bb 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -22,7 +22,7 @@ import (
 	"github.com/onsi/gomega/types"
 )
 
-const GOMEGA_VERSION = "1.25.0"
+const GOMEGA_VERSION = "1.27.0"
 
 const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
 If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/onsi/gomega/internal/async_assertion.go b/vendor/github.com/onsi/gomega/internal/async_assertion.go
index 1f6fc13b0..7f6226968 100644
--- a/vendor/github.com/onsi/gomega/internal/async_assertion.go
+++ b/vendor/github.com/onsi/gomega/internal/async_assertion.go
@@ -2,6 +2,7 @@ package internal
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"reflect"
 	"runtime"
@@ -16,6 +17,22 @@ var errInterface = reflect.TypeOf((*error)(nil)).Elem()
 var gomegaType = reflect.TypeOf((*types.Gomega)(nil)).Elem()
 var contextType = reflect.TypeOf(new(context.Context)).Elem()
 
+type formattedGomegaError interface {
+	FormattedGomegaError() string
+}
+
+type asyncPolledActualError struct {
+	message string
+}
+
+func (err *asyncPolledActualError) Error() string {
+	return err.message
+}
+
+func (err *asyncPolledActualError) FormattedGomegaError() string {
+	return err.message
+}
+
 type contextWithAttachProgressReporter interface {
 	AttachProgressReporter(func() string) func()
 }
@@ -148,7 +165,9 @@ func (assertion *AsyncAssertion) buildDescription(optionalDescription ...interfa
 
 func (assertion *AsyncAssertion) processReturnValues(values []reflect.Value) (interface{}, error) {
 	if len(values) == 0 {
-		return nil, fmt.Errorf("No values were returned by the function passed to Gomega")
+		return nil, &asyncPolledActualError{
+			message: fmt.Sprintf("The function passed to %s did not return any values", assertion.asyncType),
+		}
 	}
 
 	actual := values[0].Interface()
@@ -171,10 +190,12 @@ func (assertion *AsyncAssertion) processReturnValues(values []reflect.Value) (in
 			continue
 		}
 		if i == len(values)-2 && extraType.Implements(errInterface) {
-			err = fmt.Errorf("function returned error: %w", extra.(error))
+			err = extra.(error)
 		}
 		if err == nil {
-			err = fmt.Errorf("Unexpected non-nil/non-zero return value at index %d:\n\t<%T>: %#v", i+1, extra, extra)
+			err = &asyncPolledActualError{
+				message: fmt.Sprintf("The function passed to %s had an unexpected non-nil/non-zero return value at index %d:\n%s", assertion.asyncType, i+1, format.Object(extra, 1)),
+			}
 		}
 	}
 
@@ -253,7 +274,9 @@ func (assertion *AsyncAssertion) buildActualPoller() (func() (interface{}, error
 				skip = callerSkip[0]
 			}
 			_, file, line, _ := runtime.Caller(skip + 1)
-			assertionFailure = fmt.Errorf("Assertion in callback at %s:%d failed:\n%s", file, line, message)
+			assertionFailure = &asyncPolledActualError{
+				message: fmt.Sprintf("The function passed to %s failed at %s:%d with:\n%s", assertion.asyncType, file, line, message),
+			}
 			// we throw an asyncGomegaHaltExecutionError so that defer GinkgoRecover() can catch this error if the user makes an assertion in a goroutine
 			panic(asyncGomegaHaltExecutionError{})
 		})))
@@ -359,22 +382,39 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
 	timeout := assertion.afterTimeout()
 	lock := sync.Mutex{}
 
-	var matches bool
-	var err error
+	var matches, hasLastValidActual bool
+	var actual, lastValidActual interface{}
+	var actualErr, matcherErr error
 	var oracleMatcherSaysStop bool
 
 	assertion.g.THelper()
 
-	pollActual, err := assertion.buildActualPoller()
-	if err != nil {
-		assertion.g.Fail(err.Error(), 2+assertion.offset)
+	pollActual, buildActualPollerErr := assertion.buildActualPoller()
+	if buildActualPollerErr != nil {
+		assertion.g.Fail(buildActualPollerErr.Error(), 2+assertion.offset)
 		return false
 	}
 
-	value, err := pollActual()
-	if err == nil {
-		oracleMatcherSaysStop = assertion.matcherSaysStopTrying(matcher, value)
-		matches, err = assertion.pollMatcher(matcher, value)
+	actual, actualErr = pollActual()
+	if actualErr == nil {
+		lastValidActual = actual
+		hasLastValidActual = true
+		oracleMatcherSaysStop = assertion.matcherSaysStopTrying(matcher, actual)
+		matches, matcherErr = assertion.pollMatcher(matcher, actual)
+	}
+
+	renderError := func(preamble string, err error) string {
+		message := ""
+		if pollingSignalErr, ok := AsPollingSignalError(err); ok {
+			message = err.Error()
+			for _, attachment := range pollingSignalErr.Attachments {
+				message += fmt.Sprintf("\n%s:\n", attachment.Description)
+				message += format.Object(attachment.Object, 1)
+			}
+		} else {
+			message = preamble + "\n" + err.Error() + "\n" + format.Object(err, 1)
+		}
+		return message
 	}
 
 	messageGenerator := func() string {
@@ -382,23 +422,45 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
 		lock.Lock()
 		defer lock.Unlock()
 		message := ""
-		if err != nil {
-			if pollingSignalErr, ok := AsPollingSignalError(err); ok && pollingSignalErr.IsStopTrying() {
-				message = err.Error()
-				for _, attachment := range pollingSignalErr.Attachments {
-					message += fmt.Sprintf("\n%s:\n", attachment.Description)
-					message += format.Object(attachment.Object, 1)
+
+		if actualErr == nil {
+			if matcherErr == nil {
+				if desiredMatch {
+					message += matcher.FailureMessage(actual)
+				} else {
+					message += matcher.NegatedFailureMessage(actual)
 				}
 			} else {
-				message = "Error: " + err.Error() + "\n" + format.Object(err, 1)
+				var fgErr formattedGomegaError
+				if errors.As(actualErr, &fgErr) {
+					message += fgErr.FormattedGomegaError() + "\n"
+				} else {
+					message += renderError(fmt.Sprintf("The matcher passed to %s returned the following error:", assertion.asyncType), matcherErr)
+				}
 			}
 		} else {
-			if desiredMatch {
-				message = matcher.FailureMessage(value)
+			var fgErr formattedGomegaError
+			if errors.As(actualErr, &fgErr) {
+				message += fgErr.FormattedGomegaError() + "\n"
 			} else {
-				message = matcher.NegatedFailureMessage(value)
+				message += renderError(fmt.Sprintf("The function passed to %s returned the following error:", assertion.asyncType), actualErr)
+			}
+			if hasLastValidActual {
+				message += fmt.Sprintf("\nAt one point, however, the function did return successfully.\nYet, %s failed because", assertion.asyncType)
+				_, e := matcher.Match(lastValidActual)
+				if e != nil {
+					message += renderError(" the matcher returned the following error:", e)
+				} else {
+					message += " the matcher was not satisfied:\n"
+					if desiredMatch {
+						message += matcher.FailureMessage(lastValidActual)
+					} else {
+						message += matcher.NegatedFailureMessage(lastValidActual)
+					}
+				}
 			}
 		}
+
 		description := assertion.buildDescription(optionalDescription...)
 		return fmt.Sprintf("%s%s", description, message)
 	}
@@ -423,18 +485,20 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
 		var nextPoll <-chan time.Time = nil
 		var isTryAgainAfterError = false
 
-		if pollingSignalErr, ok := AsPollingSignalError(err); ok {
-			if pollingSignalErr.IsStopTrying() {
-				fail("Told to stop trying")
-				return false
-			}
-			if pollingSignalErr.IsTryAgainAfter() {
-				nextPoll = time.After(pollingSignalErr.TryAgainDuration())
-				isTryAgainAfterError = true
+		for _, err := range []error{actualErr, matcherErr} {
+			if pollingSignalErr, ok := AsPollingSignalError(err); ok {
+				if pollingSignalErr.IsStopTrying() {
+					fail("Told to stop trying")
+					return false
+				}
+				if pollingSignalErr.IsTryAgainAfter() {
+					nextPoll = time.After(pollingSignalErr.TryAgainDuration())
+					isTryAgainAfterError = true
+				}
 			}
 		}
 
-		if err == nil && matches == desiredMatch {
+		if actualErr == nil && matcherErr == nil && matches == desiredMatch {
 			if assertion.asyncType == AsyncAssertionTypeEventually {
 				passedRepeatedlyCount += 1
 				if passedRepeatedlyCount == assertion.mustPassRepeatedly {
@@ -465,15 +529,19 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
 
 		select {
 		case <-nextPoll:
-			v, e := pollActual()
+			a, e := pollActual()
 			lock.Lock()
-			value, err = v, e
+			actual, actualErr = a, e
 			lock.Unlock()
-			if err == nil {
-				oracleMatcherSaysStop = assertion.matcherSaysStopTrying(matcher, value)
-				m, e := assertion.pollMatcher(matcher, value)
+			if actualErr == nil {
+				lock.Lock()
+				lastValidActual = actual
+				hasLastValidActual = true
+				lock.Unlock()
+				oracleMatcherSaysStop = assertion.matcherSaysStopTrying(matcher, actual)
+				m, e := assertion.pollMatcher(matcher, actual)
 				lock.Lock()
-				matches, err = m, e
+				matches, matcherErr = m, e
 				lock.Unlock()
 			}
 		case <-contextDone:
diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go
index 857586a91..44056ad64 100644
--- a/vendor/github.com/onsi/gomega/matchers.go
+++ b/vendor/github.com/onsi/gomega/matchers.go
@@ -349,6 +349,20 @@ func ConsistOf(elements ...interface{}) types.GomegaMatcher {
 	}
 }
 
+// HaveExactElemets succeeds if actual contains elements that precisely match the elemets passed into the matcher. The ordering of the elements does matter.
+// By default HaveExactElements() uses Equal() to match the elements, however custom matchers can be passed in instead.  Here are some examples:
+//
+//	Expect([]string{"Foo", "FooBar"}).Should(HaveExactElements("Foo", "FooBar"))
+//	Expect([]string{"Foo", "FooBar"}).Should(HaveExactElements("Foo", ContainSubstring("Bar")))
+//	Expect([]string{"Foo", "FooBar"}).Should(HaveExactElements(ContainSubstring("Foo"), ContainSubstring("Foo")))
+//
+// Actual must be an array or slice.
+func HaveExactElements(elements ...interface{}) types.GomegaMatcher {
+	return &matchers.HaveExactElementsMatcher{
+		Elements: elements,
+	}
+}
+
 // ContainElements succeeds if actual contains the passed in elements. The ordering of the elements does not matter.
 // By default ContainElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples:
 //
diff --git a/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go b/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go
new file mode 100644
index 000000000..19d8f3d1d
--- /dev/null
+++ b/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go
@@ -0,0 +1,75 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type mismatchFailure struct {
+	failure string
+	index   int
+}
+
+type HaveExactElementsMatcher struct {
+	Elements         []interface{}
+	mismatchFailures []mismatchFailure
+	missingIndex     int
+	extraIndex       int
+}
+
+func (matcher *HaveExactElementsMatcher) Match(actual interface{}) (success bool, err error) {
+	if isMap(actual) {
+		return false, fmt.Errorf("error")
+	}
+
+	matchers := matchers(matcher.Elements)
+	values := valuesOf(actual)
+
+	lenMatchers := len(matchers)
+	lenValues := len(values)
+
+	for i := 0; i < lenMatchers || i < lenValues; i++ {
+		if i >= lenMatchers {
+			matcher.extraIndex = i
+			continue
+		}
+
+		if i >= lenValues {
+			matcher.missingIndex = i
+			return
+		}
+
+		elemMatcher := matchers[i].(omegaMatcher)
+		match, err := elemMatcher.Match(values[i])
+		if err != nil || !match {
+			matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{
+				index:   i,
+				failure: elemMatcher.FailureMessage(values[i]),
+			})
+		}
+	}
+
+	return matcher.missingIndex+matcher.extraIndex+len(matcher.mismatchFailures) == 0, nil
+}
+
+func (matcher *HaveExactElementsMatcher) FailureMessage(actual interface{}) (message string) {
+	message = format.Message(actual, "to have exact elements with", presentable(matcher.Elements))
+	if matcher.missingIndex > 0 {
+		message = fmt.Sprintf("%s\nthe missing elements start from index %d", message, matcher.missingIndex)
+	}
+	if matcher.extraIndex > 0 {
+		message = fmt.Sprintf("%s\nthe extra elements start from index %d", message, matcher.extraIndex)
+	}
+	if len(matcher.mismatchFailures) != 0 {
+		message = fmt.Sprintf("%s\nthe mismatch indexes were:", message)
+	}
+	for _, mismatch := range matcher.mismatchFailures {
+		message = fmt.Sprintf("%s\n%d: %s", message, mismatch.index, mismatch.failure)
+	}
+	return
+}
+
+func (matcher *HaveExactElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to contain elements", presentable(matcher.Elements))
+}
diff --git a/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go b/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go
index 721ed5529..da5a39594 100644
--- a/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go
+++ b/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go
@@ -1,11 +1,16 @@
 package matchers
 
 import (
+	"errors"
 	"fmt"
 
 	"github.com/onsi/gomega/format"
 )
 
+type formattedGomegaError interface {
+	FormattedGomegaError() string
+}
+
 type SucceedMatcher struct {
 }
 
@@ -25,6 +30,10 @@ func (matcher *SucceedMatcher) Match(actual interface{}) (success bool, err erro
 }
 
 func (matcher *SucceedMatcher) FailureMessage(actual interface{}) (message string) {
+	var fgErr formattedGomegaError
+	if errors.As(actual.(error), &fgErr) {
+		return fgErr.FormattedGomegaError()
+	}
 	return fmt.Sprintf("Expected success, but got an error:\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1))
 }
 
diff --git a/vendor/modules.txt b/vendor/modules.txt
index cde1bbf66..94323f293 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -292,7 +292,7 @@ github.com/munnerz/goautoneg
 # github.com/oklog/ulid v1.3.1
 ## explicit
 github.com/oklog/ulid
-# github.com/onsi/ginkgo/v2 v2.8.0
+# github.com/onsi/ginkgo/v2 v2.8.3
 ## explicit; go 1.18
 github.com/onsi/ginkgo/v2
 github.com/onsi/ginkgo/v2/config
@@ -314,7 +314,7 @@ github.com/onsi/ginkgo/v2/internal/parallel_support
 github.com/onsi/ginkgo/v2/internal/testingtproxy
 github.com/onsi/ginkgo/v2/reporters
 github.com/onsi/ginkgo/v2/types
-# github.com/onsi/gomega v1.25.0
+# github.com/onsi/gomega v1.27.0
 ## explicit; go 1.18
 github.com/onsi/gomega
 github.com/onsi/gomega/format


Test patch:
diff --git a/pkg/ip/ip_test.go b/pkg/ip/ip_test.go
index b8e735885..49d13a408 100644
--- a/pkg/ip/ip_test.go
+++ b/pkg/ip/ip_test.go
@@ -190,7 +190,6 @@ var _ = Describe("IP", Label("ip_test"), func() {
 					net.IPv4(172, 18, 40, 2),
 					net.IPv4(172, 18, 40, 3),
 				},
-				true,
 			)
 			Expect(ips).To(Equal([]net.IP{net.IPv4(172, 18, 40, 1)}))
 		})
@@ -205,7 +204,6 @@ var _ = Describe("IP", Label("ip_test"), func() {
 					net.ParseIP("abcd:1234::2"),
 					net.ParseIP("abcd:1234::3"),
 				},
-				true,
 			)
 			Expect(ips).To(Equal([]net.IP{net.ParseIP("abcd:1234::1")}))
 		})
@@ -222,7 +220,6 @@ var _ = Describe("IP", Label("ip_test"), func() {
 					net.IPv4(172, 18, 40, 2),
 					net.IPv4(172, 18, 40, 3),
 				},
-				true,
 			)
 			Expect(ips).To(Equal(
 				[]net.IP{
@@ -243,7 +240,6 @@ var _ = Describe("IP", Label("ip_test"), func() {
 					net.ParseIP("abcd:1234::2"),
 					net.ParseIP("abcd:1234::3"),
 				},
-				true,
 			)
 			Expect(ips).To(Equal(
 				[]net.IP{
@@ -266,7 +262,6 @@ var _ = Describe("IP", Label("ip_test"), func() {
 					net.IPv4(172, 18, 40, 2),
 					net.IPv4(172, 18, 40, 3),
 				},
-				true,
 			)
 			Expect(ips).To(Equal([]net.IP{net.IPv4(172, 18, 40, 2)}))
 		})
@@ -281,7 +276,6 @@ var _ = Describe("IP", Label("ip_test"), func() {
 					net.ParseIP("abcd:1234::2"),
 					net.ParseIP("abcd:1234::3"),
 				},
-				true,
 			)
 			Expect(ips).To(Equal([]net.IP{net.ParseIP("abcd:1234::2")}))
 		})
diff --git a/test/e2e/common/spidersubnet.go b/test/e2e/common/spidersubnet.go
index 24a9b6708..d97e716cd 100644
--- a/test/e2e/common/spidersubnet.go
+++ b/test/e2e/common/spidersubnet.go
@@ -310,7 +310,7 @@ func GetAvailableIpsInSubnet(f *frame.Framework, subnetName string) ([]net.IP, e
 		return nil, err
 	}
 
-	ips := ip.IPsDiffSet(ips1, ips2, false)
+	ips := ip.IPsDiffSet(ips1, ips2)
 	return ips, nil
 }
 
@@ -358,7 +358,7 @@ LOOP:
 							return err
 						}
 
-						diffIps := ip.IPsDiffSet(ips1, ips2, false)
+						diffIps := ip.IPsDiffSet(ips1, ips2)
 						if diffIps != nil {
 							GinkgoWriter.Printf("inconsistent ip records in subnet %v/%v and pool %v/%v \n", subnetName, ips2, pool.Name, ips1)
 							continue LOOP