Repository: spidernet-io/spiderpool
Pull request #1611 (2023-04-04 10:03:39)

forbidden modifying auto-created IPPool by hand
For the auto-created IPPool with SpiderSubnet feature, it's allow to change the Spec.IPs by yourself in the previous version. But it's a little strange to do that, because the spiderpool-controller will turn it back with the auto desired IP number later.

So, I think we should forbidden modifying auto-created IPPool by hand.

Signed-off-by: Icarus9913 [icaruswu66@qq.com](mailto:icaruswu66@qq.com)

**What this PR does / why we need it**:
fix bug

**Which issue(s) this PR fixes**:
https://github.com/spidernet-io/spiderpool/issues/1609



sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1611)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT) [5 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611) No Coverage information  
[![3.9%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '3.9%')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611&metric=new_duplicated_lines_density&view=list) [3.9% Duplication](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1611)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT) [5 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611) No Coverage information  
[![3.9%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '3.9%')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611&metric=new_duplicated_lines_density&view=list) [3.9% Duplication](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611&metric=new_duplicated_lines_density&view=list)


codecov[bot]: ## [Codecov](https://codecov.io/gh/spidernet-io/spiderpool/pull/1611?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) Report
> Merging [#1611](https://codecov.io/gh/spidernet-io/spiderpool/pull/1611?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) (f90cce1) into [main](https://codecov.io/gh/spidernet-io/spiderpool/commit/88e9141b4877680b033c5843660f1b7fb2af1020?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) (88e9141) will **decrease** coverage by `0.46%`.
> The diff coverage is `2.94%`.

[![Impacted file tree graph](https://codecov.io/gh/spidernet-io/spiderpool/pull/1611/graphs/tree.svg?width=650&height=150&src=pr&token=YKXY2E4Q8G&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io)](https://codecov.io/gh/spidernet-io/spiderpool/pull/1611?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io)

```diff
@@            Coverage Diff             @@
##             main    #1611      +/-   ##
==========================================
- Coverage   75.67%   75.22%   -0.46%     
==========================================
  Files          45       45              
  Lines        4564     4598      +34     
==========================================
+ Hits         3454     3459       +5     
- Misses       1007     1035      +28     
- Partials      103      104       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `75.22% <2.94%> (-0.46%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/spidernet-io/spiderpool/pull/1611?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) | Coverage Δ | |
|---|---|---|
| [pkg/ippoolmanager/ippool\_subnet\_validate.go](https://codecov.io/gh/spidernet-io/spiderpool/pull/1611?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io#diff-cGtnL2lwcG9vbG1hbmFnZXIvaXBwb29sX3N1Ym5ldF92YWxpZGF0ZS5nbw==) | `52.38% <2.94%> (-35.62%)` | :arrow_down: |

... and [1 file with indirect coverage changes](https://codecov.io/gh/spidernet-io/spiderpool/pull/1611/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io)

sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1611)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT) [5 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1611&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611) No Coverage information  
[![3.9%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '3.9%')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611&metric=new_duplicated_lines_density&view=list) [3.9% Duplication](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1611&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/.github/workflows/lint-markdown.yaml b/.github/workflows/lint-markdown.yaml
index 7e1d3dc89..565ab7f71 100644
--- a/.github/workflows/lint-markdown.yaml
+++ b/.github/workflows/lint-markdown.yaml
@@ -39,7 +39,7 @@ jobs:
         uses: actions/checkout@v3
 
       - name: markdownlint-cli
-        uses: nosborn/github-action-markdown-cli@v3.3.0
+        uses: nosborn/github-action-markdown-cli@v3.2.0
         with:
           files: .
           config_file: '.github/markdownlint.yaml'
diff --git a/go.mod b/go.mod
index 321657047..a38ee8193 100644
--- a/go.mod
+++ b/go.mod
@@ -3,13 +3,13 @@ module github.com/spidernet-io/spiderpool
 go 1.20
 
 require (
-	github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
+	github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
 	github.com/containernetworking/cni v1.1.2
 	github.com/go-openapi/errors v0.20.3
 	github.com/go-openapi/loads v0.21.2
 	github.com/go-openapi/runtime v0.25.0
 	github.com/go-openapi/spec v0.20.7
-	github.com/go-openapi/strfmt v0.21.7
+	github.com/go-openapi/strfmt v0.21.3
 	github.com/go-openapi/swag v0.22.3
 	github.com/go-openapi/validate v0.22.1
 	github.com/go-swagger/go-swagger v0.30.3
@@ -17,7 +17,7 @@ require (
 	github.com/google/gops v0.3.27
 	github.com/jessevdk/go-flags v1.5.0
 	github.com/onsi/ginkgo/v2 v2.9.2
-	github.com/onsi/gomega v1.27.6
+	github.com/onsi/gomega v1.27.4
 	github.com/pyroscope-io/client v0.6.0
 	github.com/sasha-s/go-deadlock v0.3.1
 	github.com/spf13/cobra v1.6.1
@@ -124,7 +124,7 @@ require (
 	github.com/spf13/viper v1.12.0 // indirect
 	github.com/subosito/gotenv v1.3.0 // indirect
 	github.com/toqueteos/webbrowser v1.2.0 // indirect
-	go.mongodb.org/mongo-driver v1.11.3 // indirect
+	go.mongodb.org/mongo-driver v1.10.1 // indirect
 	golang.org/x/crypto v0.1.0 // indirect
 	golang.org/x/mod v0.9.0 // indirect
 	golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 // indirect
diff --git a/go.sum b/go.sum
index d753a4638..f931bce8f 100644
--- a/go.sum
+++ b/go.sum
@@ -54,8 +54,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
-github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
+github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
+github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -152,9 +152,8 @@ github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SK
 github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
 github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
 github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
+github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o=
 github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg=
-github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k=
-github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
 github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
@@ -391,8 +390,8 @@ github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxe
 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.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
-github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
+github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
+github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
 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=
@@ -489,7 +488,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
 github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
@@ -510,8 +509,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
 go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
 go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
 go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
-go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y=
-go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
+go.mongodb.org/mongo-driver v1.10.1 h1:NujsPveKwHaWuKUer/ceo9DzEe7HIj1SlJ6uvXZG0S4=
+go.mongodb.org/mongo-driver v1.10.1/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
diff --git a/pkg/ippoolmanager/ippool_subnet_validate.go b/pkg/ippoolmanager/ippool_subnet_validate.go
index b87cf50f1..00ba61772 100644
--- a/pkg/ippoolmanager/ippool_subnet_validate.go
+++ b/pkg/ippoolmanager/ippool_subnet_validate.go
@@ -4,8 +4,12 @@
 package ippoolmanager
 
 import (
+	"bytes"
 	"context"
 	"fmt"
+	"net"
+	"reflect"
+	"sort"
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	apitypes "k8s.io/apimachinery/pkg/types"
@@ -13,6 +17,7 @@ import (
 
 	spiderpoolip "github.com/spidernet-io/spiderpool/pkg/ip"
 	spiderpoolv2beta1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1"
+	"github.com/spidernet-io/spiderpool/pkg/utils/convert"
 )
 
 func (iw *IPPoolWebhook) validateCreateIPPoolWhileEnableSpiderSubnet(ctx context.Context, ipPool *spiderpoolv2beta1.SpiderIPPool) field.ErrorList {
@@ -79,5 +84,47 @@ func (iw *IPPoolWebhook) validateSubnetTotalIPsContainsIPPoolTotalIPs(ctx contex
 		)
 	}
 
+	if IsAutoCreatedIPPool(ipPool) {
+		return validateNewAutoPoolTotalIPsWithinSubnet(ipPool, &subnet)
+	}
+
+	return nil
+}
+
+func validateNewAutoPoolTotalIPsWithinSubnet(pool *spiderpoolv2beta1.SpiderIPPool, subnet *spiderpoolv2beta1.SpiderSubnet) *field.Error {
+	var subnetPreAllocateIPs []net.IP
+
+	poolTotalIPs, err := spiderpoolip.AssembleTotalIPs(*pool.Spec.IPVersion, pool.Spec.IPs, pool.Spec.ExcludeIPs)
+	if nil != err {
+		return field.InternalError(ipsField, fmt.Errorf("failed to assemble the total IP addresses of the Subnet %s: %v", subnet.Name, err))
+	}
+	sort.Slice(poolTotalIPs, func(i, j int) bool {
+		return bytes.Compare(poolTotalIPs[i].To16(), poolTotalIPs[j].To16()) < 0
+	})
+
+	subnetAllocatedIPPools, err := convert.UnmarshalSubnetAllocatedIPPools(subnet.Status.ControlledIPPools)
+	if nil != err {
+		return field.InternalError(subnetField, fmt.Errorf("failed unsharmal SpiderSubnet %s Status.ControlledIPPools: %v", subnet.Name, err))
+	}
+	if subnetAllocatedIPPools != nil {
+		subnetPoolAllocation, ok := subnetAllocatedIPPools[pool.Name]
+		if ok {
+			subnetPoolIPs, err := spiderpoolip.ParseIPRanges(*subnet.Spec.IPVersion, subnetPoolAllocation.IPs)
+			if nil != err {
+				return field.InternalError(subnetField, fmt.Errorf("failed to parse SpiderSubnet %s controlledIPPool %s IPs: %v ", subnet.Name, pool.Name, err))
+			}
+			sort.Slice(subnetPoolIPs, func(i, j int) bool {
+				return bytes.Compare(subnetPoolIPs[i].To16(), subnetPoolIPs[j].To16()) < 0
+			})
+			subnetPreAllocateIPs = subnetPoolIPs
+		}
+	}
+
+	isEqual := reflect.DeepEqual(subnetPreAllocateIPs, poolTotalIPs)
+	if !isEqual {
+		return field.Forbidden(ipsField,
+			"it's illegal to update AutoPool.Spec.IPs that are different from corresponding SpiderSubnet.Status.ControlledIPPools")
+	}
+
 	return nil
 }
diff --git a/vendor/github.com/asaskevich/govalidator/validator.go b/vendor/github.com/asaskevich/govalidator/validator.go
index c9c4fac06..46ecfc84a 100644
--- a/vendor/github.com/asaskevich/govalidator/validator.go
+++ b/vendor/github.com/asaskevich/govalidator/validator.go
@@ -454,26 +454,27 @@ func IsCreditCard(str string) bool {
 	if !rxCreditCard.MatchString(sanitized) {
 		return false
 	}
-	
-	number, _ := ToInt(sanitized)
-	number, lastDigit := number / 10, number % 10	
-
 	var sum int64
-	for i:=0; number > 0; i++ {
-		digit := number % 10
-		
-		if i % 2 == 0 {
-			digit *= 2
-			if digit > 9 {
-				digit -= 9
+	var digit string
+	var tmpNum int64
+	var shouldDouble bool
+	for i := len(sanitized) - 1; i >= 0; i-- {
+		digit = sanitized[i:(i + 1)]
+		tmpNum, _ = ToInt(digit)
+		if shouldDouble {
+			tmpNum *= 2
+			if tmpNum >= 10 {
+				sum += (tmpNum % 10) + 1
+			} else {
+				sum += tmpNum
 			}
+		} else {
+			sum += tmpNum
 		}
-		
-		sum += digit
-		number = number / 10
+		shouldDouble = !shouldDouble
 	}
-	
-	return (sum + lastDigit) % 10 == 0
+
+	return sum%10 == 0
 }
 
 // IsISBN10 checks if the string is an ISBN version 10.
diff --git a/vendor/github.com/go-openapi/strfmt/.golangci.yml b/vendor/github.com/go-openapi/strfmt/.golangci.yml
index be4899cb1..d36b25665 100644
--- a/vendor/github.com/go-openapi/strfmt/.golangci.yml
+++ b/vendor/github.com/go-openapi/strfmt/.golangci.yml
@@ -14,40 +14,31 @@ linters-settings:
     min-occurrences: 4
 
 linters:
-  enable:
-    - revive
-    - goimports
-    - gosec
-    - unparam
-    - unconvert
-    - predeclared
-    - prealloc
-    - misspell
-
-  # disable:
-  #   - maligned
-  #   - lll
-  #   - gochecknoinits
-  #   - gochecknoglobals
-  #   - godox
-  #   - gocognit
-  #   - whitespace
-  #   - wsl
-  #   - funlen
-  #   - wrapcheck
-  #   - testpackage
-  #   - nlreturn
-  #   - gofumpt
-  #   - goerr113
-  #   - gci
-  #   - gomnd
-  #   - godot
-  #   - exhaustivestruct
-  #   - paralleltest
-  #   - varnamelen
-  #   - ireturn
-  #   - exhaustruct
-  #   #- thelper
+  enable-all: true
+  disable:
+    - maligned
+    - lll
+    - gochecknoinits
+    - gochecknoglobals
+    - godox
+    - gocognit
+    - whitespace
+    - wsl
+    - funlen
+    - wrapcheck
+    - testpackage
+    - nlreturn
+    - gofumpt
+    - goerr113
+    - gci
+    - gomnd
+    - godot
+    - exhaustivestruct
+    - paralleltest
+    - varnamelen
+    - ireturn
+    - exhaustruct
+    #- thelper
 
 issues:
   exclude-rules:
diff --git a/vendor/github.com/go-openapi/strfmt/bson.go b/vendor/github.com/go-openapi/strfmt/bson.go
index a8a3604a2..8740b1505 100644
--- a/vendor/github.com/go-openapi/strfmt/bson.go
+++ b/vendor/github.com/go-openapi/strfmt/bson.go
@@ -142,7 +142,7 @@ func (id ObjectId) MarshalBSONValue() (bsontype.Type, []byte, error) {
 // BSON value representation of themselves. The BSON bytes and type can be
 // assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it
 // wishes to retain the data after returning.
-func (id *ObjectId) UnmarshalBSONValue(_ bsontype.Type, data []byte) error {
+func (id *ObjectId) UnmarshalBSONValue(tpe bsontype.Type, data []byte) error {
 	var oid bsonprim.ObjectID
 	copy(oid[:], data)
 	*id = ObjectId(oid)
diff --git a/vendor/github.com/go-openapi/strfmt/date.go b/vendor/github.com/go-openapi/strfmt/date.go
index 3c93381c7..f0b310964 100644
--- a/vendor/github.com/go-openapi/strfmt/date.go
+++ b/vendor/github.com/go-openapi/strfmt/date.go
@@ -57,7 +57,7 @@ func (d *Date) UnmarshalText(text []byte) error {
 	if len(text) == 0 {
 		return nil
 	}
-	dd, err := time.ParseInLocation(RFC3339FullDate, string(text), DefaultTimeLocation)
+	dd, err := time.Parse(RFC3339FullDate, string(text))
 	if err != nil {
 		return err
 	}
@@ -107,7 +107,7 @@ func (d *Date) UnmarshalJSON(data []byte) error {
 	if err := json.Unmarshal(data, &strdate); err != nil {
 		return err
 	}
-	tt, err := time.ParseInLocation(RFC3339FullDate, strdate, DefaultTimeLocation)
+	tt, err := time.Parse(RFC3339FullDate, strdate)
 	if err != nil {
 		return err
 	}
@@ -126,7 +126,7 @@ func (d *Date) UnmarshalBSON(data []byte) error {
 	}
 
 	if data, ok := m["data"].(string); ok {
-		rd, err := time.ParseInLocation(RFC3339FullDate, data, DefaultTimeLocation)
+		rd, err := time.Parse(RFC3339FullDate, data)
 		if err != nil {
 			return err
 		}
diff --git a/vendor/github.com/go-openapi/strfmt/format.go b/vendor/github.com/go-openapi/strfmt/format.go
index ad3b3c355..172055d22 100644
--- a/vendor/github.com/go-openapi/strfmt/format.go
+++ b/vendor/github.com/go-openapi/strfmt/format.go
@@ -109,7 +109,7 @@ func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc { //
 			if to == tpe {
 				switch v.Name {
 				case "date":
-					d, err := time.ParseInLocation(RFC3339FullDate, data, DefaultTimeLocation)
+					d, err := time.Parse(RFC3339FullDate, data)
 					if err != nil {
 						return nil, err
 					}
diff --git a/vendor/github.com/go-openapi/strfmt/time.go b/vendor/github.com/go-openapi/strfmt/time.go
index 9bef4c3b3..023676e6c 100644
--- a/vendor/github.com/go-openapi/strfmt/time.go
+++ b/vendor/github.com/go-openapi/strfmt/time.go
@@ -29,12 +29,6 @@ import (
 	"go.mongodb.org/mongo-driver/bson/bsontype"
 )
 
-var (
-	// UnixZero sets the zero unix timestamp we want to compare against.
-	// Unix 0 for an EST timezone is not equivalent to a UTC timezone.
-	UnixZero = time.Unix(0, 0).UTC()
-)
-
 func init() {
 	dt := DateTime{}
 	Default.Add("datetime", &dt, IsDateTime)
@@ -92,9 +86,6 @@ var (
 	// NormalizeTimeForMarshal provides a normalization function on time befeore marshalling (e.g. time.UTC).
 	// By default, the time value is not changed.
 	NormalizeTimeForMarshal = func(t time.Time) time.Time { return t }
-
-	// DefaultTimeLocation provides a location for a time when the time zone is not encoded in the string (ex: ISO8601 Local variants).
-	DefaultTimeLocation = time.UTC
 )
 
 // ParseDateTime parses a string that represents an ISO8601 time or a unix epoch
@@ -104,7 +95,7 @@ func ParseDateTime(data string) (DateTime, error) {
 	}
 	var lastError error
 	for _, layout := range DateTimeFormats {
-		dd, err := time.ParseInLocation(layout, data, DefaultTimeLocation)
+		dd, err := time.Parse(layout, data)
 		if err != nil {
 			lastError = err
 			continue
@@ -132,22 +123,6 @@ func (t DateTime) String() string {
 	return NormalizeTimeForMarshal(time.Time(t)).Format(MarshalFormat)
 }
 
-// IsZero returns whether the date time is a zero value
-func (t *DateTime) IsZero() bool {
-	if t == nil {
-		return true
-	}
-	return time.Time(*t).IsZero()
-}
-
-// IsUnixZerom returns whether the date time is equivalent to time.Unix(0, 0).UTC().
-func (t *DateTime) IsUnixZero() bool {
-	if t == nil {
-		return true
-	}
-	return time.Time(*t).Equal(UnixZero)
-}
-
 // MarshalText implements the text marshaller interface
 func (t DateTime) MarshalText() ([]byte, error) {
 	return []byte(t.String()), nil
diff --git a/vendor/github.com/go-openapi/strfmt/ulid.go b/vendor/github.com/go-openapi/strfmt/ulid.go
index e71aff7c3..4bd2ccd8f 100644
--- a/vendor/github.com/go-openapi/strfmt/ulid.go
+++ b/vendor/github.com/go-openapi/strfmt/ulid.go
@@ -15,12 +15,9 @@ import (
 
 // ULID represents a ulid string format
 // ref:
-//
-//	https://github.com/ulid/spec
-//
+//   https://github.com/ulid/spec
 // impl:
-//
-//	https://github.com/oklog/ulid
+//   https://github.com/oklog/ulid
 //
 // swagger:strfmt ulid
 type ULID struct {
@@ -92,9 +89,7 @@ func NewULIDZero() ULID {
 }
 
 // NewULID generates new unique ULID value and a error if any
-func NewULID() (ULID, error) {
-	var u ULID
-
+func NewULID() (u ULID, err error) {
 	obj := ulidEntropyPool.Get()
 	entropy, ok := obj.(io.Reader)
 	if !ok {
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index ef428f6f6..e702e3c99 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,17 +1,3 @@
-## 1.27.6
-
-### Fixes
-- Allow collections matchers to work correctly when expected has nil elements [60e7cf3]
-
-### Maintenance
-- updates MatchError godoc comment to also accept a Gomega matcher (#654) [67b869d]
-
-## 1.27.5
-
-### Maintenance
-- Bump github.com/onsi/ginkgo/v2 from 2.9.1 to 2.9.2 (#653) [a215021]
-- Bump github.com/go-task/slim-sprig (#652) [a26fed8]
-
 ## 1.27.4
 
 ### Fixes
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index 872592bfb..e37251d89 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.27.6"
+const GOMEGA_VERSION = "1.27.4"
 
 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/matchers.go b/vendor/github.com/onsi/gomega/matchers.go
index b832f3dba..44056ad64 100644
--- a/vendor/github.com/onsi/gomega/matchers.go
+++ b/vendor/github.com/onsi/gomega/matchers.go
@@ -87,17 +87,14 @@ func Succeed() types.GomegaMatcher {
 	return &matchers.SucceedMatcher{}
 }
 
-// MatchError succeeds if actual is a non-nil error that matches the passed in
-// string, error, or matcher.
+// MatchError succeeds if actual is a non-nil error that matches the passed in string/error.
 //
 // These are valid use-cases:
 //
-//  Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error"
-//  Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual)
-//  Expect(err).Should(MatchError(ContainsSubstring("sprocket not found"))) // asserts that edrr.Error() contains substring "sprocket not found"
+//	Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error"
+//	Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual)
 //
-// It is an error for err to be nil or an object that does not implement the
-// Error interface
+// It is an error for err to be nil or an object that does not implement the Error interface
 func MatchError(expected interface{}) types.GomegaMatcher {
 	return &matchers.MatchErrorMatcher{
 		Expected: expected,
diff --git a/vendor/github.com/onsi/gomega/matchers/consist_of.go b/vendor/github.com/onsi/gomega/matchers/consist_of.go
index f69037a4f..e8ef0dee1 100644
--- a/vendor/github.com/onsi/gomega/matchers/consist_of.go
+++ b/vendor/github.com/onsi/gomega/matchers/consist_of.go
@@ -48,13 +48,11 @@ func neighbours(value, matcher interface{}) (bool, error) {
 
 func equalMatchersToElements(matchers []interface{}) (elements []interface{}) {
 	for _, matcher := range matchers {
-		if equalMatcher, ok := matcher.(*EqualMatcher); ok {
-			elements = append(elements, equalMatcher.Expected)
-		} else if _, ok := matcher.(*BeNilMatcher); ok {
-			elements = append(elements, nil)
-		} else {
-			elements = append(elements, matcher)
+		equalMatcher, ok := matcher.(*EqualMatcher)
+		if ok {
+			matcher = equalMatcher.Expected
 		}
+		elements = append(elements, matcher)
 	}
 	return
 }
@@ -74,13 +72,11 @@ func flatten(elems []interface{}) []interface{} {
 
 func matchers(expectedElems []interface{}) (matchers []interface{}) {
 	for _, e := range flatten(expectedElems) {
-		if e == nil {
-			matchers = append(matchers, &BeNilMatcher{})
-		} else if matcher, isMatcher := e.(omegaMatcher); isMatcher {
-			matchers = append(matchers, matcher)
-		} else {
-			matchers = append(matchers, &EqualMatcher{Expected: e})
+		matcher, isMatcher := e.(omegaMatcher)
+		if !isMatcher {
+			matcher = &EqualMatcher{Expected: e}
 		}
+		matchers = append(matchers, matcher)
 	}
 	return
 }
@@ -93,14 +89,9 @@ func presentable(elems []interface{}) interface{} {
 	}
 
 	sv := reflect.ValueOf(elems)
-	firstEl := sv.Index(0)
-	if firstEl.IsNil() {
-		return elems
-	}
-	tt := firstEl.Elem().Type()
+	tt := sv.Index(0).Elem().Type()
 	for i := 1; i < sv.Len(); i++ {
-		el := sv.Index(i)
-		if el.IsNil() || (sv.Index(i).Elem().Type() != tt) {
+		if sv.Index(i).Elem().Type() != tt {
 			return elems
 		}
 	}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bson.go b/vendor/go.mongodb.org/mongo-driver/bson/bson.go
index a0d818582..95ffc1078 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bson.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bson.go
@@ -27,7 +27,7 @@ type Zeroer interface {
 //
 // Example usage:
 //
-//	bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
+// 		bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
 type D = primitive.D
 
 // E represents a BSON element for a D. It is usually used inside a D.
@@ -39,12 +39,12 @@ type E = primitive.E
 //
 // Example usage:
 //
-//	bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
+// 		bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
 type M = primitive.M
 
 // An A is an ordered representation of a BSON array.
 //
 // Example usage:
 //
-//	bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}}
+// 		bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}}
 type A = primitive.A
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
index 5f903ebea..b0ae0e23f 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
@@ -17,7 +17,7 @@
 // 2) A Registry that holds these ValueEncoders and ValueDecoders and provides methods for
 // retrieving them.
 //
-// # ValueEncoders and ValueDecoders
+// ValueEncoders and ValueDecoders
 //
 // The ValueEncoder interface is implemented by types that can encode a provided Go type to BSON.
 // The value to encode is provided as a reflect.Value and a bsonrw.ValueWriter is used within the
@@ -31,7 +31,7 @@
 // allow the use of a function with the correct signature as a ValueDecoder. A DecodeContext
 // instance is provided and serves similar functionality to the EncodeContext.
 //
-// # Registry and RegistryBuilder
+// Registry and RegistryBuilder
 //
 // A Registry is an immutable store for ValueEncoders, ValueDecoders, and a type map. See the Registry type
 // documentation for examples of registering various custom encoders and decoders. A Registry can be constructed using a
@@ -53,15 +53,15 @@
 // values decode as Go int32 and int64 instances, respectively, when decoding into a bson.D. The following code would
 // change the behavior so these values decode as Go int instances instead:
 //
-//	intType := reflect.TypeOf(int(0))
-//	registryBuilder.RegisterTypeMapEntry(bsontype.Int32, intType).RegisterTypeMapEntry(bsontype.Int64, intType)
+//		intType := reflect.TypeOf(int(0))
+//		registryBuilder.RegisterTypeMapEntry(bsontype.Int32, intType).RegisterTypeMapEntry(bsontype.Int64, intType)
 //
 // 4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and RegisterDefaultDecoder
 // methods. The registered codec will be invoked when encoding or decoding values whose reflect.Kind matches the
 // registered reflect.Kind as long as the value's type doesn't match a registered type or hook encoder/decoder first.
 // These methods should be used to change the behavior for all values for a specific kind.
 //
-// # Registry Lookup Procedure
+// Registry Lookup Procedure
 //
 // When looking up an encoder in a Registry, the precedence rules are as follows:
 //
@@ -79,7 +79,7 @@
 // rules apply for decoders, with the exception that an error of type ErrNoDecoder will be returned if no decoder is
 // found.
 //
-// # DefaultValueEncoders and DefaultValueDecoders
+// DefaultValueEncoders and DefaultValueDecoders
 //
 // The DefaultValueEncoders and DefaultValueDecoders types provide a full set of ValueEncoders and
 // ValueDecoders for handling a wide range of Go types, including all of the types within the
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
index 80644023c..f6f3800d4 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
@@ -254,7 +254,6 @@ func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDe
 // By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON
 // documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents
 // to decode to bson.Raw, use the following code:
-//
 //	rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{}))
 func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder {
 	rb.typeMap[bt] = rt
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
index 62708c5c7..6f406c162 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
@@ -34,21 +34,21 @@ func (stpf StructTagParserFunc) ParseStructTags(sf reflect.StructField) (StructT
 //
 // The properties are defined below:
 //
-//	OmitEmpty  Only include the field if it's not set to the zero value for the type or to
-//	           empty slices or maps.
+//     OmitEmpty  Only include the field if it's not set to the zero value for the type or to
+//                empty slices or maps.
 //
-//	MinSize    Marshal an integer of a type larger than 32 bits value as an int32, if that's
-//	           feasible while preserving the numeric value.
+//     MinSize    Marshal an integer of a type larger than 32 bits value as an int32, if that's
+//                feasible while preserving the numeric value.
 //
-//	Truncate   When unmarshaling a BSON double, it is permitted to lose precision to fit within
-//	           a float32.
+//     Truncate   When unmarshaling a BSON double, it is permitted to lose precision to fit within
+//                a float32.
 //
-//	Inline     Inline the field, which must be a struct or a map, causing all of its fields
-//	           or keys to be processed as if they were part of the outer struct. For maps,
-//	           keys must not conflict with the bson keys of other struct fields.
+//     Inline     Inline the field, which must be a struct or a map, causing all of its fields
+//                or keys to be processed as if they were part of the outer struct. For maps,
+//                keys must not conflict with the bson keys of other struct fields.
 //
-//	Skip       This struct field should be skipped. This is usually denoted by parsing a "-"
-//	           for the name.
+//     Skip       This struct field should be skipped. This is usually denoted by parsing a "-"
+//                for the name.
 //
 // TODO(skriptble): Add tags for undefined as nil and for null as nil.
 type StructTags struct {
@@ -67,20 +67,20 @@ type StructTags struct {
 // If there is no name in the struct tag fields, the struct field name is lowercased.
 // The tag formats accepted are:
 //
-//	"[<key>][,<flag1>[,<flag2>]]"
+//     "[<key>][,<flag1>[,<flag2>]]"
 //
-//	`(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)`
+//     `(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)`
 //
 // An example:
 //
-//	type T struct {
-//	    A bool
-//	    B int    "myb"
-//	    C string "myc,omitempty"
-//	    D string `bson:",omitempty" json:"jsonkey"`
-//	    E int64  ",minsize"
-//	    F int64  "myf,omitempty,minsize"
-//	}
+//     type T struct {
+//         A bool
+//         B int    "myb"
+//         C string "myc,omitempty"
+//         D string `bson:",omitempty" json:"jsonkey"`
+//         E int64  ",minsize"
+//         F int64  "myf,omitempty,minsize"
+//     }
 //
 // A struct tag either consisting entirely of '-' or with a bson key with a
 // value consisting entirely of '-' will return a StructTags with Skip true and
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/doc.go
deleted file mode 100644
index c40973c8d..000000000
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/doc.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2022-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-// Package bsonoptions defines the optional configurations for the BSON codecs.
-package bsonoptions
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/doc.go
index 0134006d8..5e3825a23 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/doc.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/doc.go
@@ -9,22 +9,21 @@
 // The BSON library handles marshalling and unmarshalling of values through a configurable codec system. For a description
 // of the codec system and examples of registering custom codecs, see the bsoncodec package.
 //
-// # Raw BSON
+// Raw BSON
 //
 // The Raw family of types is used to validate and retrieve elements from a slice of bytes. This
 // type is most useful when you want do lookups on BSON bytes without unmarshaling it into another
 // type.
 //
 // Example:
+// 		var raw bson.Raw = ... // bytes from somewhere
+// 		err := raw.Validate()
+// 		if err != nil { return err }
+// 		val := raw.Lookup("foo")
+// 		i32, ok := val.Int32OK()
+// 		// do something with i32...
 //
-//	var raw bson.Raw = ... // bytes from somewhere
-//	err := raw.Validate()
-//	if err != nil { return err }
-//	val := raw.Lookup("foo")
-//	i32, ok := val.Int32OK()
-//	// do something with i32...
-//
-// # Native Go Types
+// Native Go Types
 //
 // The D and M types defined in this package can be used to build representations of BSON using native Go types. D is a
 // slice and M is a map. For more information about the use cases for these types, see the documentation on the type
@@ -33,64 +32,63 @@
 // Note that a D should not be constructed with duplicate key names, as that can cause undefined server behavior.
 //
 // Example:
-//
-//	bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
-//	bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
+// 		bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
+//		bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
 //
 // When decoding BSON to a D or M, the following type mappings apply when unmarshalling:
 //
-//  1. BSON int32 unmarshals to an int32.
-//  2. BSON int64 unmarshals to an int64.
-//  3. BSON double unmarshals to a float64.
-//  4. BSON string unmarshals to a string.
-//  5. BSON boolean unmarshals to a bool.
-//  6. BSON embedded document unmarshals to the parent type (i.e. D for a D, M for an M).
-//  7. BSON array unmarshals to a bson.A.
-//  8. BSON ObjectId unmarshals to a primitive.ObjectID.
-//  9. BSON datetime unmarshals to a primitive.DateTime.
-//  10. BSON binary unmarshals to a primitive.Binary.
-//  11. BSON regular expression unmarshals to a primitive.Regex.
-//  12. BSON JavaScript unmarshals to a primitive.JavaScript.
-//  13. BSON code with scope unmarshals to a primitive.CodeWithScope.
-//  14. BSON timestamp unmarshals to an primitive.Timestamp.
-//  15. BSON 128-bit decimal unmarshals to an primitive.Decimal128.
-//  16. BSON min key unmarshals to an primitive.MinKey.
-//  17. BSON max key unmarshals to an primitive.MaxKey.
-//  18. BSON undefined unmarshals to a primitive.Undefined.
-//  19. BSON null unmarshals to nil.
-//  20. BSON DBPointer unmarshals to a primitive.DBPointer.
-//  21. BSON symbol unmarshals to a primitive.Symbol.
+// 		1. BSON int32 unmarshals to an int32.
+// 		2. BSON int64 unmarshals to an int64.
+// 		3. BSON double unmarshals to a float64.
+// 		4. BSON string unmarshals to a string.
+// 		5. BSON boolean unmarshals to a bool.
+// 		6. BSON embedded document unmarshals to the parent type (i.e. D for a D, M for an M).
+// 		7. BSON array unmarshals to a bson.A.
+// 		8. BSON ObjectId unmarshals to a primitive.ObjectID.
+// 		9. BSON datetime unmarshals to a primitive.DateTime.
+// 		10. BSON binary unmarshals to a primitive.Binary.
+// 		11. BSON regular expression unmarshals to a primitive.Regex.
+// 		12. BSON JavaScript unmarshals to a primitive.JavaScript.
+// 		13. BSON code with scope unmarshals to a primitive.CodeWithScope.
+// 		14. BSON timestamp unmarshals to an primitive.Timestamp.
+// 		15. BSON 128-bit decimal unmarshals to an primitive.Decimal128.
+// 		16. BSON min key unmarshals to an primitive.MinKey.
+// 		17. BSON max key unmarshals to an primitive.MaxKey.
+// 		18. BSON undefined unmarshals to a primitive.Undefined.
+// 		19. BSON null unmarshals to nil.
+// 		20. BSON DBPointer unmarshals to a primitive.DBPointer.
+// 		21. BSON symbol unmarshals to a primitive.Symbol.
 //
 // The above mappings also apply when marshalling a D or M to BSON. Some other useful marshalling mappings are:
 //
-//  1. time.Time marshals to a BSON datetime.
-//  2. int8, int16, and int32 marshal to a BSON int32.
-//  3. int marshals to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32, inclusive, and a BSON int64
-//     otherwise.
-//  4. int64 marshals to BSON int64.
-//  5. uint8 and uint16 marshal to a BSON int32.
-//  6. uint, uint32, and uint64 marshal to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32,
-//     inclusive, and BSON int64 otherwise.
-//  7. BSON null and undefined values will unmarshal into the zero value of a field (e.g. unmarshalling a BSON null or
-//     undefined value into a string will yield the empty string.).
+//       1. time.Time marshals to a BSON datetime.
+//       2. int8, int16, and int32 marshal to a BSON int32.
+//       3. int marshals to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32, inclusive, and a BSON int64
+//       otherwise.
+//       4. int64 marshals to BSON int64.
+//       5. uint8 and uint16 marshal to a BSON int32.
+//       6. uint, uint32, and uint64 marshal to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32,
+//       inclusive, and BSON int64 otherwise.
+//       7. BSON null and undefined values will unmarshal into the zero value of a field (e.g. unmarshalling a BSON null or
+//       undefined value into a string will yield the empty string.).
 //
-// # Structs
+// Structs
 //
 // Structs can be marshalled/unmarshalled to/from BSON or Extended JSON. When transforming structs to/from BSON or Extended
 // JSON, the following rules apply:
 //
-//  1. Only exported fields in structs will be marshalled or unmarshalled.
+//     1. Only exported fields in structs will be marshalled or unmarshalled.
 //
-//  2. When marshalling a struct, each field will be lowercased to generate the key for the corresponding BSON element.
+//     2. When marshalling a struct, each field will be lowercased to generate the key for the corresponding BSON element.
 //     For example, a struct field named "Foo" will generate key "foo". This can be overridden via a struct tag (e.g.
 //     `bson:"fooField"` to generate key "fooField" instead).
 //
-//  3. An embedded struct field is marshalled as a subdocument. The key will be the lowercased name of the field's type.
+//     3. An embedded struct field is marshalled as a subdocument. The key will be the lowercased name of the field's type.
 //
-//  4. A pointer field is marshalled as the underlying type if the pointer is non-nil. If the pointer is nil, it is
+//     4. A pointer field is marshalled as the underlying type if the pointer is non-nil. If the pointer is nil, it is
 //     marshalled as a BSON null value.
 //
-//  5. When unmarshalling, a field of type interface{} will follow the D/M type mappings listed above. BSON documents
+//     5. When unmarshalling, a field of type interface{} will follow the D/M type mappings listed above. BSON documents
 //     unmarshalled into an interface{} field will be unmarshalled as a D.
 //
 // The encoding of each struct field can be customized by the "bson" struct tag.
@@ -100,14 +98,13 @@
 // are not honored, but that can be enabled by creating a StructCodec with JSONFallbackStructTagParser, like below:
 //
 // Example:
-//
-//	structcodec, _ := bsoncodec.NewStructCodec(bsoncodec.JSONFallbackStructTagParser)
+//      structcodec, _ := bsoncodec.NewStructCodec(bsoncodec.JSONFallbackStructTagParser)
 //
 // The bson tag gives the name of the field, possibly followed by a comma-separated list of options.
 // The name may be empty in order to specify options without overriding the default field name. The following options can be used
 // to configure behavior:
 //
-//  1. omitempty: If the omitempty struct tag is specified on a field, the field will not be marshalled if it is set to
+//     1. omitempty: If the omitempty struct tag is specified on a field, the field will not be marshalled if it is set to
 //     the zero value. Fields with language primitive types such as integers, booleans, and strings are considered empty if
 //     their value is equal to the zero value for the type (i.e. 0 for integers, false for booleans, and "" for strings).
 //     Slices, maps, and arrays are considered empty if they are of length zero. Interfaces and pointers are considered
@@ -116,16 +113,16 @@
 //     never considered empty and will be marshalled as embedded documents.
 //     NOTE: It is recommended that this tag be used for all slice and map fields.
 //
-//  2. minsize: If the minsize struct tag is specified on a field of type int64, uint, uint32, or uint64 and the value of
+//     2. minsize: If the minsize struct tag is specified on a field of type int64, uint, uint32, or uint64 and the value of
 //     the field can fit in a signed int32, the field will be serialized as a BSON int32 rather than a BSON int64. For other
 //     types, this tag is ignored.
 //
-//  3. truncate: If the truncate struct tag is specified on a field with a non-float numeric type, BSON doubles unmarshalled
+//     3. truncate: If the truncate struct tag is specified on a field with a non-float numeric type, BSON doubles unmarshalled
 //     into that field will be truncated at the decimal point. For example, if 3.14 is unmarshalled into a field of type int,
 //     it will be unmarshalled as 3. If this tag is not specified, the decoder will throw an error if the value cannot be
 //     decoded without losing precision. For float64 or non-numeric types, this tag is ignored.
 //
-//  4. inline: If the inline struct tag is specified for a struct or map field, the field will be "flattened" when
+//     4. inline: If the inline struct tag is specified for a struct or map field, the field will be "flattened" when
 //     marshalling and "un-flattened" when unmarshalling. This means that all of the fields in that struct/map will be
 //     pulled up one level and will become top-level fields rather than being fields in a nested document. For example, if a
 //     map field named "Map" with value map[string]interface{}{"foo": "bar"} is inlined, the resulting document will be
@@ -135,7 +132,7 @@
 //     This tag can be used with fields that are pointers to structs. If an inlined pointer field is nil, it will not be
 //     marshalled. For fields that are not maps or structs, this tag is ignored.
 //
-// # Marshalling and Unmarshalling
+// Marshalling and Unmarshalling
 //
 // Manually marshalling and unmarshalling can be done with the Marshal and Unmarshal family of functions.
 package bson
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go
index ba7c9112e..ffe4eed07 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go
@@ -191,9 +191,10 @@ func (d Decimal128) IsNaN() bool {
 
 // IsInf returns:
 //
-//	+1 d == Infinity
-//	 0 other case
-//	-1 d == -Infinity
+//   +1 d == Infinity
+//    0 other case
+//   -1 d == -Infinity
+//
 func (d Decimal128) IsInf() int {
 	if d.h>>58&(1<<5-1) != 0x1E {
 		return 0
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go
index ded367316..652898fea 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go
@@ -61,9 +61,7 @@ func (id ObjectID) Timestamp() time.Time {
 
 // Hex returns the hex encoding of the ObjectID as a string.
 func (id ObjectID) Hex() string {
-	var buf [24]byte
-	hex.Encode(buf[:], id[:])
-	return string(buf[:])
+	return hex.EncodeToString(id[:])
 }
 
 func (id ObjectID) String() string {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go
index c72ccc1c4..b3cba1bf9 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go
@@ -182,7 +182,7 @@ type MaxKey struct{}
 //
 // Example usage:
 //
-//	bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
+// 		bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
 type D []E
 
 // Map creates a map from the elements of the D.
@@ -206,12 +206,12 @@ type E struct {
 //
 // Example usage:
 //
-//	bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
+// 		bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
 type M map[string]interface{}
 
 // An A is an ordered representation of a BSON array.
 //
 // Example usage:
 //
-//	bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}}
+// 		bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}}
 type A []interface{}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document_sequence.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document_sequence.go
index e35bd0cd9..6c858a010 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document_sequence.go
+++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document_sequence.go
@@ -96,8 +96,8 @@ func (ds *DocumentSequence) Empty() bool {
 	}
 }
 
-// ResetIterator resets the iteration point for the Next method to the beginning of the document
-// sequence.
+//ResetIterator resets the iteration point for the Next method to the beginning of the document
+//sequence.
 func (ds *DocumentSequence) ResetIterator() {
 	if ds == nil {
 		return
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
index 789d2b982..54aa617cf 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
+++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
@@ -323,7 +323,7 @@ func (v Value) String() string {
 		if !ok {
 			return ""
 		}
-		return fmt.Sprintf(`{"$timestamp":{"t":%v,"i":%v}}`, t, i)
+		return fmt.Sprintf(`{"$timestamp":{"t":"%s","i":"%s"}}`, strconv.FormatUint(uint64(t), 10), strconv.FormatUint(uint64(i), 10))
 	case bsontype.Int64:
 		i64, ok := v.Int64OK()
 		if !ok {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index cd406152a..d415e904d 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -11,7 +11,7 @@ github.com/Masterminds/sprig/v3
 ## explicit; go 1.14
 github.com/agiledragon/gomonkey/v2
 github.com/agiledragon/gomonkey/v2/creflect
-# github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
+# github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
 ## explicit; go 1.13
 github.com/asaskevich/govalidator
 # github.com/beorn7/perks v1.0.1
@@ -107,8 +107,8 @@ github.com/go-openapi/runtime/yamlpc
 # github.com/go-openapi/spec v0.20.7
 ## explicit; go 1.13
 github.com/go-openapi/spec
-# github.com/go-openapi/strfmt v0.21.7
-## explicit; go 1.19
+# github.com/go-openapi/strfmt v0.21.3
+## explicit; go 1.13
 github.com/go-openapi/strfmt
 # github.com/go-openapi/swag v0.22.3
 ## explicit; go 1.18
@@ -285,7 +285,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.27.6
+# github.com/onsi/gomega v1.27.4
 ## explicit; go 1.18
 github.com/onsi/gomega
 github.com/onsi/gomega/format
@@ -409,8 +409,8 @@ github.com/subosito/gotenv
 # github.com/toqueteos/webbrowser v1.2.0
 ## explicit; go 1.12
 github.com/toqueteos/webbrowser
-# go.mongodb.org/mongo-driver v1.11.3
-## explicit; go 1.13
+# go.mongodb.org/mongo-driver v1.10.1
+## explicit; go 1.10
 go.mongodb.org/mongo-driver/bson
 go.mongodb.org/mongo-driver/bson/bsoncodec
 go.mongodb.org/mongo-driver/bson/bsonoptions


Test patch:
diff --git a/pkg/ippoolmanager/ippool_webhook_test.go b/pkg/ippoolmanager/ippool_webhook_test.go
index 28cbed1cb..513caecf1 100644
--- a/pkg/ippoolmanager/ippool_webhook_test.go
+++ b/pkg/ippoolmanager/ippool_webhook_test.go
@@ -11,6 +11,7 @@ import (
 	"github.com/agiledragon/gomonkey/v2"
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
+	appsv1 "k8s.io/api/apps/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime/schema"
@@ -22,11 +23,13 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 
+	"github.com/spidernet-io/spiderpool/pkg/applicationcontroller/applicationinformers"
 	"github.com/spidernet-io/spiderpool/pkg/constant"
 	spiderpoolip "github.com/spidernet-io/spiderpool/pkg/ip"
 	"github.com/spidernet-io/spiderpool/pkg/ippoolmanager"
 	spiderpoolv2beta1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1"
 	"github.com/spidernet-io/spiderpool/pkg/logutils"
+	"github.com/spidernet-io/spiderpool/pkg/types"
 	"github.com/spidernet-io/spiderpool/pkg/utils/convert"
 )
 
@@ -1593,6 +1596,82 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					err = ipPoolWebhook.ValidateUpdate(ctx, ipPoolT, newIPPoolT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
+
+				It("update auto-created IPPool by hand", func() {
+					subnetT.SetUID(uuid.NewUUID())
+					subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
+					subnetT.Spec.Subnet = "172.18.40.0/24"
+					subnetT.Spec.IPs = append(subnetT.Spec.IPs, "172.18.40.1-172.18.40.2")
+
+					autoPool := ipPoolT.DeepCopy()
+					autoPool.Annotations = map[string]string{constant.AnnoSpiderSubnetPoolApp: applicationinformers.ApplicationNamespacedName(types.AppNamespacedName{
+						APIVersion: appsv1.SchemeGroupVersion.String(),
+						Kind:       constant.KindDeployment,
+						Namespace:  autoPool.Namespace,
+						Name:       autoPool.Name,
+					})}
+					autoPool.Spec.IPVersion = pointer.Int64(constant.IPv4)
+					autoPool.Spec.Subnet = "172.18.40.0/24"
+					autoPool.Spec.IPs = append(autoPool.Spec.IPs, "172.18.40.1")
+
+					err := controllerutil.SetControllerReference(subnetT, autoPool, scheme)
+					Expect(err).NotTo(HaveOccurred())
+					poolIPPreAllocations := spiderpoolv2beta1.PoolIPPreAllocations{autoPool.Name: spiderpoolv2beta1.PoolIPPreAllocation{
+						IPs:         []string{"172.18.40.1"},
+						Application: pointer.String(autoPool.Annotations[constant.AnnoSpiderSubnetPoolApp]),
+					}}
+					subnetAllocatedIPPools, err := convert.MarshalSubnetAllocatedIPPools(poolIPPreAllocations)
+					Expect(err).NotTo(HaveOccurred())
+					subnetT.Status.ControlledIPPools = subnetAllocatedIPPools
+
+					err = tracker.Add(subnetT)
+					Expect(err).NotTo(HaveOccurred())
+
+					newAutoPool := autoPool.DeepCopy()
+					newAutoPool.Spec.IPs = append(newAutoPool.Spec.IPs, "172.18.40.2")
+
+					err = ipPoolWebhook.ValidateUpdate(ctx, autoPool, newAutoPool)
+					Expect(apierrors.IsInvalid(err)).To(BeTrue())
+				})
+
+				It("update auto-created IPPool annotation", func() {
+					subnetT.SetUID(uuid.NewUUID())
+					subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
+					subnetT.Spec.Subnet = "172.18.40.0/24"
+					subnetT.Spec.IPs = append(subnetT.Spec.IPs, "172.18.40.1-172.18.40.2")
+
+					autoPool := ipPoolT.DeepCopy()
+					autoPool.Annotations = map[string]string{constant.AnnoSpiderSubnetPoolApp: applicationinformers.ApplicationNamespacedName(types.AppNamespacedName{
+						APIVersion: appsv1.SchemeGroupVersion.String(),
+						Kind:       constant.KindDeployment,
+						Namespace:  autoPool.Namespace,
+						Name:       autoPool.Name,
+					})}
+					autoPool.Spec.IPVersion = pointer.Int64(constant.IPv4)
+					autoPool.Spec.Subnet = "172.18.40.0/24"
+					autoPool.Spec.IPs = append(autoPool.Spec.IPs, "172.18.40.1")
+
+					err := controllerutil.SetControllerReference(subnetT, autoPool, scheme)
+					Expect(err).NotTo(HaveOccurred())
+					poolIPPreAllocations := spiderpoolv2beta1.PoolIPPreAllocations{autoPool.Name: spiderpoolv2beta1.PoolIPPreAllocation{
+						IPs:         []string{"172.18.40.1"},
+						Application: pointer.String(autoPool.Annotations[constant.AnnoSpiderSubnetPoolApp]),
+					}}
+					subnetAllocatedIPPools, err := convert.MarshalSubnetAllocatedIPPools(poolIPPreAllocations)
+					Expect(err).NotTo(HaveOccurred())
+					subnetT.Status.ControlledIPPools = subnetAllocatedIPPools
+
+					err = tracker.Add(subnetT)
+					Expect(err).NotTo(HaveOccurred())
+
+					newAutoPool := autoPool.DeepCopy()
+					anno := newAutoPool.GetAnnotations()
+					anno["aaa"] = "test"
+					newAutoPool.Annotations = anno
+
+					err = ipPoolWebhook.ValidateUpdate(ctx, autoPool, newAutoPool)
+					Expect(err).NotTo(HaveOccurred())
+				})
 			})
 
 			It("deletes IPPool", func() {