Repository: spidernet-io/spiderpool
Pull request #2314 (2023-09-07 06:40:04)

spidercoordinator: allow set ip addr to hijackCIDR
---
name: Pull request
about: Tell us about your contribution
labels: ["pr/release/none-required"]
---

---
## Thanks for contributing !

Before submitting a pull request, make sure you read about our Contribution notice here: <https://spidernet-io.github.io/spiderpool/contributing/development/pullrequest/#need-review>

**What this PR does / why we need it**:

This PR allows set IP address to hijackCIDR, you can set it as a netip or a cidr

**Which issue(s) this PR fixes**:

https://github.com/spidernet-io/spiderpool/issues/2223

**Special notes for your reviewer**:

**make sure your commit is signed off**


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/spidernet-io/spiderpool/pull/2314?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) Report
> Merging [#2314](https://app.codecov.io/gh/spidernet-io/spiderpool/pull/2314?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) (d3dc050) into [main](https://app.codecov.io/gh/spidernet-io/spiderpool/commit/933a8cd1d1a5e9cb486233a2d9cc156b9c2de31d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) (933a8cd) will **decrease** coverage by `0.25%`.
> The diff coverage is `0.00%`.

> :exclamation: Current head d3dc050 differs from pull request most recent head 05d10df. Consider uploading reports for the commit 05d10df to get more accurate results

[![Impacted file tree graph](https://app.codecov.io/gh/spidernet-io/spiderpool/pull/2314/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://app.codecov.io/gh/spidernet-io/spiderpool/pull/2314?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    #2314      +/-   ##
==========================================
- Coverage   81.14%   80.89%   -0.25%     
==========================================
  Files          49       49              
  Lines        5277     5293      +16     
==========================================
  Hits         4282     4282              
- Misses        832      848      +16     
  Partials      163      163              
```

| [Flag](https://app.codecov.io/gh/spidernet-io/spiderpool/pull/2314/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/spidernet-io/spiderpool/pull/2314/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) | `80.89% <0.00%> (-0.25%)` | :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.

| [Files Changed](https://app.codecov.io/gh/spidernet-io/spiderpool/pull/2314?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io) | Coverage Δ | |
|---|---|---|
| [pkg/ip/ip.go](https://app.codecov.io/gh/spidernet-io/spiderpool/pull/2314?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=spidernet-io#diff-cGtnL2lwL2lwLmdv) | `82.67% <0.00%> (-11.92%)` | :arrow_down: |

cyclinder: /cc @weizhoublue 

Patch:
diff --git a/cmd/spiderpool-init/cmd/config.go b/cmd/spiderpool-init/cmd/config.go
index 8f965d8ba..aa6bde343 100644
--- a/cmd/spiderpool-init/cmd/config.go
+++ b/cmd/spiderpool-init/cmd/config.go
@@ -6,7 +6,6 @@ package cmd
 import (
 	"fmt"
 	"k8s.io/utils/pointer"
-	"net/netip"
 	"os"
 	"sort"
 	"strconv"
@@ -145,13 +144,16 @@ func parseENVAsDefault() InitDefaultConfig {
 			v = strings.ReplaceAll(v, ",", " ")
 			subnets := strings.Fields(v)
 
-			for _, r := range subnets {
-				_, err := netip.ParsePrefix(r)
+			for idx, r := range subnets {
+				nPrefix, err := spiderpoolip.ParseIPOrCIDR(r)
 				if err != nil {
 					logger.Sugar().Fatalf("ENV %s invalid: %v", ENVDefaultCoordiantorHijackCIDR, err)
 				}
+				subnets[idx] = nPrefix.String()
 			}
 			config.CoordinatorHijackCIDR = subnets
+		} else {
+			config.CoordinatorHijackCIDR = []string{}
 		}
 	} else {
 		logger.Info("Ignore creating default Coordinator")
diff --git a/pkg/coordinatormanager/coordinator_mutate.go b/pkg/coordinatormanager/coordinator_mutate.go
index 4ef410738..702bb4bcd 100644
--- a/pkg/coordinatormanager/coordinator_mutate.go
+++ b/pkg/coordinatormanager/coordinator_mutate.go
@@ -7,6 +7,8 @@ import (
 	"context"
 	"fmt"
 	"k8s.io/utils/pointer"
+	"net/netip"
+	"strings"
 
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
@@ -47,6 +49,21 @@ func mutateCoordinator(ctx context.Context, coord *spiderpoolv2beta1.SpiderCoord
 		return fmt.Errorf("PodCIDRType is not allowed to be empty")
 	}
 
+	for idx, cidr := range coord.Spec.HijackCIDR {
+		if !strings.Contains(cidr, "/") {
+			nAddr, err := netip.ParseAddr(cidr)
+			if err != nil {
+				return fmt.Errorf("invalid IP address: %v", cidr)
+			}
+
+			if nAddr.Is4() {
+				coord.Spec.HijackCIDR[idx] = fmt.Sprintf("%s/%d", cidr, 32)
+			} else if nAddr.Is6() {
+				coord.Spec.HijackCIDR[idx] = fmt.Sprintf("%s/%d", cidr, 128)
+			}
+		}
+	}
+
 	if !controllerutil.ContainsFinalizer(coord, constant.SpiderFinalizer) {
 		controllerutil.AddFinalizer(coord, constant.SpiderFinalizer)
 		logger.Sugar().Infof("Add finalizer %s", constant.SpiderFinalizer)
diff --git a/pkg/coordinatormanager/coordinator_validate.go b/pkg/coordinatormanager/coordinator_validate.go
index 229105574..6dff89b3f 100644
--- a/pkg/coordinatormanager/coordinator_validate.go
+++ b/pkg/coordinatormanager/coordinator_validate.go
@@ -5,13 +5,13 @@ package coordinatormanager
 
 import (
 	"fmt"
-	"net"
 	"strconv"
 	"strings"
 
 	"k8s.io/apimachinery/pkg/util/validation/field"
 	"k8s.io/utils/strings/slices"
 
+	"github.com/spidernet-io/spiderpool/pkg/ip"
 	spiderpoolv2beta1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1"
 )
 
@@ -104,7 +104,7 @@ func validateCoordinatorExtraCIDR(cidrs []string) *field.Error {
 	}
 
 	for i, cidr := range cidrs {
-		_, _, err := net.ParseCIDR(cidr)
+		nPrefix, err := ip.ParseIPOrCIDR(cidr)
 		if err != nil {
 			return field.Invalid(
 				extraCIDRField.Index(i),
@@ -112,8 +112,8 @@ func validateCoordinatorExtraCIDR(cidrs []string) *field.Error {
 				err.Error(),
 			)
 		}
+		cidrs[i] = nPrefix.String()
 	}
-
 	return nil
 }
 
diff --git a/pkg/ip/ip.go b/pkg/ip/ip.go
index 20d21ac9d..f6a83175a 100644
--- a/pkg/ip/ip.go
+++ b/pkg/ip/ip.go
@@ -8,7 +8,9 @@ import (
 	"fmt"
 	"math/big"
 	"net"
+	"net/netip"
 	"sort"
+	"strings"
 
 	"github.com/asaskevich/govalidator"
 
@@ -206,3 +208,24 @@ func ipToInt(ip net.IP) *big.Int {
 func intToIP(i *big.Int) net.IP {
 	return net.IP(i.Bytes()).To16()
 }
+
+func ParseIPOrCIDR(s string) (netip.Prefix, error) {
+	if !strings.Contains(s, "/") {
+		nAddr, err := netip.ParseAddr(s)
+		if err != nil {
+			return netip.Prefix{}, err
+		}
+
+		prefix := 32
+		if nAddr.Is6() {
+			prefix = 128
+		}
+		return netip.PrefixFrom(nAddr, prefix), nil
+	}
+
+	nPrefix, err := netip.ParsePrefix(s)
+	if err != nil {
+		return netip.Prefix{}, err
+	}
+	return nPrefix, nil
+}


Test patch:
diff --git a/pkg/ip/ip_test.go b/pkg/ip/ip_test.go
index b8e735885..8caf3a6ba 100644
--- a/pkg/ip/ip_test.go
+++ b/pkg/ip/ip_test.go
@@ -346,4 +346,40 @@ var _ = Describe("IP", Label("ip_test"), func() {
 			)).To(BeNumerically(">", 0))
 		})
 	})
+
+	Describe("Test ParseIPOrCIDR", func() {
+		It("Parse an IPv4 address, expect 32 Bit Mask", func() {
+			nip := "1.1.1.1"
+			expect := "1.1.1.1/32"
+			nPrefix, err := spiderpoolip.ParseIPOrCIDR(nip)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(expect).To(Equal(nPrefix.String()))
+		})
+		It("Parse an IPv6 address, expect 128 Bit Mask", func() {
+			nip := "fd00::1"
+			expect := "fd00::1/128"
+			nPrefix, err := spiderpoolip.ParseIPOrCIDR(nip)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(expect).To(Equal(nPrefix.String()))
+		})
+		It("Parse an IPv4 CIDR", func() {
+			nip := "1.1.0.0/16"
+			expect := "1.1.0.0/16"
+			nPrefix, err := spiderpoolip.ParseIPOrCIDR(nip)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(expect).To(Equal(nPrefix.String()))
+		})
+		It("Parse an IPv6 CIDR", func() {
+			nip := "fd00::/64"
+			expect := "fd00::/64"
+			nPrefix, err := spiderpoolip.ParseIPOrCIDR(nip)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(expect).To(Equal(nPrefix.String()))
+		})
+		It("Parse an invalid string", func() {
+			str := "invalid cir"
+			_, err := spiderpoolip.ParseIPOrCIDR(str)
+			Expect(err).To(HaveOccurred())
+		})
+	})
 })
diff --git a/test/scripts/install-multus.sh b/test/scripts/install-multus.sh
index 628fabe93..abcc2c0d6 100755
--- a/test/scripts/install-multus.sh
+++ b/test/scripts/install-multus.sh
@@ -231,6 +231,7 @@ EOF
 Install::MultusCR
 Install::SpiderpoolCR
 
+kubectl get spidercoordinator default -o yaml --kubeconfig ${E2E_KUBECONFIG}
 kubectl get sp -o wide --kubeconfig ${E2E_KUBECONFIG}
 kubectl get network-attachment-definitions.k8s.cni.cncf.io --kubeconfig ${E2E_KUBECONFIG} -n kube-system -o yaml