Repository: spidernet-io/spiderpool (go)

Issue:
add annotation for AutoPool
At the current SpiderPool version, for a auto-created IPPool we can acquire its background whether its IP number is flexible or fixed. We need to check it with the pod annotation `ipam.spidernet.io/ippool-ip-number`. 

So, I suggest to add this annotation to AutoPool annotation. And with this, it's convenient for us to troubleshoot whether the AutoPool still heathy. For example, we set the one deployment with '+1' and all good. And later we set it to '+5', but the corresponding SpiderSubnet lacks of available IPs and lead to the AutoPool failed to scale up. In this situation, we can notice the AutoPool annotation `ipam.spidernet.io/ippool-ip-number: +1` is different with the pod annotation.  

Pull request:
supplement annotation for Auto-Pool 
supplement annotation for auto-created IPPool to explain whether its IP number is flexible or fixed.

Signed-off-by: Icarus9913 [icaruswu66@qq.com](mailto:icaruswu66@qq.com)


**What this PR does / why we need it**:
new feature

**Which issue(s) this PR fixes**:
close #1769 




Patch:
diff --git a/pkg/applicationcontroller/app_controller.go b/pkg/applicationcontroller/app_controller.go
index 78b7fd702..30514457e 100644
--- a/pkg/applicationcontroller/app_controller.go
+++ b/pkg/applicationcontroller/app_controller.go
@@ -8,6 +8,7 @@ import (
 	"errors"
 	"fmt"
 	"reflect"
+	"strconv"
 	"sync"
 	"time"
 
@@ -784,19 +785,23 @@ func (sac *SubnetAppController) applyAutoIPPool(ctx context.Context, podSubnetCo
 		}
 
 		var desiredIPNumber int
+		var annoPoolIPNumberVal string
 		if podSubnetConfig.FlexibleIPNum != nil {
 			desiredIPNumber = appReplicas + *(podSubnetConfig.FlexibleIPNum)
+			annoPoolIPNumberVal = fmt.Sprintf("+%d", *podSubnetConfig.FlexibleIPNum)
 		} else {
 			desiredIPNumber = podSubnetConfig.AssignIPNum
+			annoPoolIPNumberVal = strconv.Itoa(podSubnetConfig.AssignIPNum)
 		}
 
 		log.Sugar().Infof("try to reconcile auto-created IPv%d IPPool for Interface %s by SpiderSubnet %s with application controller %v",
 			ipVersion, ifName, subnetName, podController.AppNamespacedName)
 		_, err = sac.subnetMgr.ReconcileAutoIPPool(ctx, tmpPool, subnetName, podController, types.AutoPoolProperty{
-			DesiredIPNumber: desiredIPNumber,
-			IPVersion:       ipVersion,
-			IsReclaimIPPool: podSubnetConfig.ReclaimIPPool,
-			IfName:          ifName,
+			DesiredIPNumber:     desiredIPNumber,
+			IPVersion:           ipVersion,
+			IsReclaimIPPool:     podSubnetConfig.ReclaimIPPool,
+			IfName:              ifName,
+			AnnoPoolIPNumberVal: annoPoolIPNumberVal,
 		})
 		if nil != err {
 			return err
diff --git a/pkg/ipam/pool_selections.go b/pkg/ipam/pool_selections.go
index d4535e1d7..0cd25ecca 100644
--- a/pkg/ipam/pool_selections.go
+++ b/pkg/ipam/pool_selections.go
@@ -136,10 +136,11 @@ func (i *ipam) getPoolFromSubnetAnno(ctx context.Context, pod *corev1.Pod, nic s
 
 			if !slices.Contains(constant.K8sAPIVersions, podController.APIVersion) || !slices.Contains(constant.K8sKinds, podController.Kind) {
 				v4PoolCandidate, errV4 = i.applyThirdControllerAutoPool(ctx, subnetItem.IPv4[0], podController, types.AutoPoolProperty{
-					DesiredIPNumber: poolIPNum,
-					IPVersion:       constant.IPv4,
-					IsReclaimIPPool: subnetAnnoConfig.ReclaimIPPool,
-					IfName:          nic,
+					DesiredIPNumber:     poolIPNum,
+					IPVersion:           constant.IPv4,
+					IsReclaimIPPool:     subnetAnnoConfig.ReclaimIPPool,
+					IfName:              nic,
+					AnnoPoolIPNumberVal: strconv.Itoa(poolIPNum),
 				})
 			} else {
 				v4PoolCandidate, errV4 = i.findAppAutoPool(ctx, subnetItem.IPv4[0], nic, constant.LabelValueIPVersionV4, poolIPNum, podController)
@@ -159,10 +160,11 @@ func (i *ipam) getPoolFromSubnetAnno(ctx context.Context, pod *corev1.Pod, nic s
 
 			if !slices.Contains(constant.K8sAPIVersions, podController.APIVersion) || !slices.Contains(constant.K8sKinds, podController.Kind) {
 				v6PoolCandidate, errV6 = i.applyThirdControllerAutoPool(ctx, subnetItem.IPv6[0], podController, types.AutoPoolProperty{
-					DesiredIPNumber: poolIPNum,
-					IPVersion:       constant.IPv6,
-					IsReclaimIPPool: subnetAnnoConfig.ReclaimIPPool,
-					IfName:          nic,
+					DesiredIPNumber:     poolIPNum,
+					IPVersion:           constant.IPv6,
+					IsReclaimIPPool:     subnetAnnoConfig.ReclaimIPPool,
+					IfName:              nic,
+					AnnoPoolIPNumberVal: strconv.Itoa(poolIPNum),
 				})
 			} else {
 				v6PoolCandidate, errV6 = i.findAppAutoPool(ctx, subnetItem.IPv6[0], nic, constant.LabelValueIPVersionV6, poolIPNum, podController)
@@ -285,12 +287,7 @@ func (i *ipam) applyThirdControllerAutoPool(ctx context.Context, subnetName stri
 			}
 		}
 
-		pool, err = i.subnetManager.ReconcileAutoIPPool(ctx, pool, subnetName, podController, types.AutoPoolProperty{
-			DesiredIPNumber: autoPoolProperty.DesiredIPNumber,
-			IPVersion:       autoPoolProperty.IPVersion,
-			IsReclaimIPPool: autoPoolProperty.IsReclaimIPPool,
-			IfName:          autoPoolProperty.IfName,
-		})
+		pool, err = i.subnetManager.ReconcileAutoIPPool(ctx, pool, subnetName, podController, autoPoolProperty)
 		if nil != err {
 			if apierrors.IsConflict(err) || apierrors.IsAlreadyExists(err) {
 				log.Sugar().Warnf("fetch SubnetIPPool %d times: apply auto-created IPPool conflict: %v", j, err)
diff --git a/pkg/subnetmanager/subnet_manager.go b/pkg/subnetmanager/subnet_manager.go
index 4dda53672..431699be2 100644
--- a/pkg/subnetmanager/subnet_manager.go
+++ b/pkg/subnetmanager/subnet_manager.go
@@ -190,6 +190,12 @@ func (sm *subnetManager) ReconcileAutoIPPool(ctx context.Context, pool *spiderpo
 	}
 	pool.Spec.IPs = ips
 
+	// give the auto-created IPPool a symbol to explain whether it is IP number flexible or fixed.
+	poolAnno := map[string]string{
+		constant.AnnoSpiderSubnetPoolIPNumber: autoPoolProperty.AnnoPoolIPNumberVal,
+	}
+	pool.SetAnnotations(poolAnno)
+
 	if operationCreate {
 		log.Sugar().Infof("try to create IPPool '%v'", pool)
 		err = sm.client.Create(ctx, pool)
diff --git a/pkg/types/k8s.go b/pkg/types/k8s.go
index 737ae51d6..a9a94b5a3 100644
--- a/pkg/types/k8s.go
+++ b/pkg/types/k8s.go
@@ -104,4 +104,6 @@ type AutoPoolProperty struct {
 	IPVersion       IPVersion
 	IsReclaimIPPool bool
 	IfName          string
+	// AnnoPoolIPNumberVal serves for AutoPool annotation to explain whether it is IP number flexible or fixed.
+	AnnoPoolIPNumberVal string
 }


Test patch:
diff --git a/pkg/subnetmanager/subnet_manager_test.go b/pkg/subnetmanager/subnet_manager_test.go
index 3ab3027f9..b783b8b03 100644
--- a/pkg/subnetmanager/subnet_manager_test.go
+++ b/pkg/subnetmanager/subnet_manager_test.go
@@ -249,10 +249,11 @@ var _ = Describe("SubnetManager", Label("subnet_manager_test"), func() {
 					APP: nil,
 				}
 				autoPoolProperty := types.AutoPoolProperty{
-					DesiredIPNumber: 1,
-					IPVersion:       constant.IPv4,
-					IsReclaimIPPool: true,
-					IfName:          "eth0",
+					DesiredIPNumber:     1,
+					IPVersion:           constant.IPv4,
+					IsReclaimIPPool:     true,
+					IfName:              "eth0",
+					AnnoPoolIPNumberVal: "1",
 				}
 
 				autoPool, err := subnetManager.ReconcileAutoIPPool(ctx, nil, subnet.Name, podController, autoPoolProperty)