Repository: spidernet-io/spiderpool (go)

Issue:
failed to auto cherry pick PR 1749 to branch release-v0.5
commits 80fd32378d0174144d9cbb64d2e4c0525e1c858d  conflict when merging to branch release-v0.5, please manually cherry pick it by yourself. 
 PR <https://github.com/spidernet-io/spiderpool/pull/1749> ,  action <https://github.com/spidernet-io/spiderpool/actions/runs/4913882440>  

  ```
CONFLICT (modify/delete): pkg/ippoolmanager/ippool_informer_test.go deleted in HEAD and modified in 80fd3237 (change auto-created IPPool application NamespacedName label because of value max length limitation).  Version 80fd3237 (change auto-created IPPool application NamespacedName label because of value max length limitation) of pkg/ippoolmanager/ippool_informer_test.go left in tree.
error: could not apply 80fd3237... change auto-created IPPool application NamespacedName label because of value max length limitation
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
``` 


Pull request:
Cherrypick 1749&1757 to release v0.5
Signed-off-by: Icarus9913 [icaruswu66@qq.com](mailto:icaruswu66@qq.com)

**What this PR does / why we need it**:
cherry-pick

**Which issue(s) this PR fixes**:
close #1754 
close #1757 


Patch:
diff --git a/pkg/applicationcontroller/app_controller.go b/pkg/applicationcontroller/app_controller.go
index 1b446fdc2..78b7fd702 100644
--- a/pkg/applicationcontroller/app_controller.go
+++ b/pkg/applicationcontroller/app_controller.go
@@ -746,20 +746,16 @@ func (sac *SubnetAppController) applyAutoIPPool(ctx context.Context, podSubnetCo
 
 	// retrieve application pools
 	fn := func(subnetName string, ipVersion types.IPVersion, ifName string) error {
-		var ipVersionStr string
-		if ipVersion == constant.IPv4 {
-			ipVersionStr = constant.LabelValueIPVersionV4
-		} else {
-			ipVersionStr = constant.LabelValueIPVersionV6
-		}
-
 		var tmpPool *spiderpoolv2beta1.SpiderIPPool
 		tmpPoolList := &spiderpoolv2beta1.SpiderIPPoolList{}
 		matchLabels := client.MatchingLabels{
-			constant.LabelIPPoolOwnerSpiderSubnet: subnetName,
-			constant.LabelIPPoolOwnerApplication:  applicationinformers.ApplicationNamespacedName(podController.AppNamespacedName),
-			constant.LabelIPPoolIPVersion:         ipVersionStr,
-			constant.LabelIPPoolInterface:         ifName,
+			constant.LabelIPPoolOwnerSpiderSubnet:         subnetName,
+			constant.LabelIPPoolOwnerApplicationGV:        applicationinformers.ApplicationLabelGV(podController.APIVersion),
+			constant.LabelIPPoolOwnerApplicationKind:      podController.Kind,
+			constant.LabelIPPoolOwnerApplicationNamespace: podController.Namespace,
+			constant.LabelIPPoolOwnerApplicationName:      podController.Name,
+			constant.LabelIPPoolIPVersion:                 applicationinformers.AutoPoolIPVersionLabelValue(ipVersion),
+			constant.LabelIPPoolInterface:                 ifName,
 		}
 
 		err := sac.apiReader.List(ctx, tmpPoolList, matchLabels)
diff --git a/pkg/applicationcontroller/applicationinformers/utils.go b/pkg/applicationcontroller/applicationinformers/utils.go
index 8deac045a..c31cbed09 100644
--- a/pkg/applicationcontroller/applicationinformers/utils.go
+++ b/pkg/applicationcontroller/applicationinformers/utils.go
@@ -61,6 +61,37 @@ func AutoPoolName(controllerName string, ipVersion types.IPVersion, ifName strin
 	return fmt.Sprintf("auto%d-%s-%s-%s", ipVersion, strings.ToLower(controllerName), strings.ToLower(ifName), strings.ToLower(lastOne))
 }
 
+// ApplicationLabelGV switches the kubernetes APIVersion from "/" link format to "_" link format for kubernetes label value usage.
+func ApplicationLabelGV(apiVersion string) string {
+	// Kubernetes API Group might be empty, ref: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#api-versions
+	first, second, hasGroup := strings.Cut(apiVersion, "/")
+	if hasGroup {
+		return fmt.Sprintf("%s_%s", first, second)
+	}
+
+	return first
+}
+
+// ParseApplicationGVStr will parse a label value string back to apiVersion format string, its corresponding function is ApplicationLabelGV.
+func ParseApplicationGVStr(str string) (apiVersion string, isMatch bool) {
+	split := strings.Split(str, "_")
+
+	// no API Group
+	if len(split) == 1 {
+		return schema.GroupVersion{
+			Group:   "",
+			Version: split[0],
+		}.String(), true
+	} else if len(split) == 2 {
+		return schema.GroupVersion{
+			Group:   split[0],
+			Version: split[1],
+		}.String(), true
+	}
+
+	return
+}
+
 // ApplicationNamespacedName will joint the application apiVersion, application type, namespace and name as a string, then we need unpack it for tracing
 // [ns and object name constraint Ref]: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/
 // We set format is "{apiVersion}:{appKind}:{appNS}:{appName}"
@@ -468,3 +499,19 @@ func IsThirdController(appNamespacedName types.AppNamespacedName) bool {
 
 	return isThird
 }
+
+func IsReclaimAutoPoolLabelValue(isReclaim bool) string {
+	if isReclaim {
+		return constant.True
+	}
+
+	return constant.False
+}
+
+func AutoPoolIPVersionLabelValue(ipVersion types.IPVersion) string {
+	if ipVersion == constant.IPv4 {
+		return constant.LabelValueIPVersionV4
+	}
+
+	return constant.LabelValueIPVersionV6
+}
diff --git a/pkg/constant/k8s.go b/pkg/constant/k8s.go
index da9b9ae9a..5ec77758e 100644
--- a/pkg/constant/k8s.go
+++ b/pkg/constant/k8s.go
@@ -62,14 +62,17 @@ const (
 	AnnoSpiderSubnetPoolIPNumber  = AnnotationPre + "/ippool-ip-number"
 	AnnoSpiderSubnetReclaimIPPool = AnnotationPre + "/ippool-reclaim"
 
-	LabelIPPoolReclaimIPPool       = AnnoSpiderSubnetReclaimIPPool
-	LabelIPPoolOwnerSpiderSubnet   = AnnotationPre + "/owner-spider-subnet"
-	LabelIPPoolOwnerApplication    = AnnotationPre + "/owner-application"
-	LabelIPPoolOwnerApplicationUID = AnnotationPre + "/owner-application-uid"
-	LabelIPPoolInterface           = AnnotationPre + "/interface"
-	LabelIPPoolIPVersion           = AnnotationPre + "/ip-version"
-	LabelValueIPVersionV4          = "IPv4"
-	LabelValueIPVersionV6          = "IPv6"
+	LabelIPPoolReclaimIPPool             = AnnoSpiderSubnetReclaimIPPool
+	LabelIPPoolOwnerSpiderSubnet         = AnnotationPre + "/owner-spider-subnet"
+	LabelIPPoolOwnerApplicationGV        = AnnotationPre + "/owner-application-gv"
+	LabelIPPoolOwnerApplicationKind      = AnnotationPre + "/owner-application-kind"
+	LabelIPPoolOwnerApplicationNamespace = AnnotationPre + "/owner-application-namespace"
+	LabelIPPoolOwnerApplicationName      = AnnotationPre + "/owner-application-name"
+	LabelIPPoolOwnerApplicationUID       = AnnotationPre + "/owner-application-uid"
+	LabelIPPoolInterface                 = AnnotationPre + "/interface"
+	LabelIPPoolIPVersion                 = AnnotationPre + "/ip-version"
+	LabelValueIPVersionV4                = "IPv4"
+	LabelValueIPVersionV6                = "IPv6"
 
 	LabelSubnetCIDR = AnnotationPre + "/subnet-cidr"
 	LabelIPPoolCIDR = AnnotationPre + "/ippool-cidr"
diff --git a/pkg/ipam/pool_selections.go b/pkg/ipam/pool_selections.go
index c3956a17a..d4535e1d7 100644
--- a/pkg/ipam/pool_selections.go
+++ b/pkg/ipam/pool_selections.go
@@ -18,7 +18,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/spidernet-io/spiderpool/api/v1/agent/models"
-	subnetmanagercontrollers "github.com/spidernet-io/spiderpool/pkg/applicationcontroller/applicationinformers"
+	"github.com/spidernet-io/spiderpool/pkg/applicationcontroller/applicationinformers"
 	"github.com/spidernet-io/spiderpool/pkg/constant"
 	spiderpoolv2beta1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1"
 	"github.com/spidernet-io/spiderpool/pkg/logutils"
@@ -81,13 +81,13 @@ func (i *ipam) getPoolFromSubnetAnno(ctx context.Context, pod *corev1.Pod, nic s
 	logger := logutils.FromContext(ctx)
 
 	// get SpiderSubnet configuration from pod annotation
-	subnetAnnoConfig, err := subnetmanagercontrollers.GetSubnetAnnoConfig(pod.Annotations, logger)
+	subnetAnnoConfig, err := applicationinformers.GetSubnetAnnoConfig(pod.Annotations, logger)
 	if nil != err {
 		return nil, err
 	}
 
 	// default IPPool mode
-	if subnetmanagercontrollers.IsDefaultIPPoolMode(subnetAnnoConfig) {
+	if applicationinformers.IsDefaultIPPoolMode(subnetAnnoConfig) {
 		return nil, nil
 	}
 
@@ -206,11 +206,14 @@ func (i *ipam) findAppAutoPool(ctx context.Context, subnetName, ifName, labelIPP
 
 	var pool *spiderpoolv2beta1.SpiderIPPool
 	matchLabels := client.MatchingLabels{
-		constant.LabelIPPoolOwnerSpiderSubnet:   subnetName,
-		constant.LabelIPPoolOwnerApplication:    subnetmanagercontrollers.ApplicationNamespacedName(podController.AppNamespacedName),
-		constant.LabelIPPoolOwnerApplicationUID: string(podController.UID),
-		constant.LabelIPPoolInterface:           ifName,
-		constant.LabelIPPoolIPVersion:           labelIPPoolIPVersionValue,
+		constant.LabelIPPoolOwnerSpiderSubnet:         subnetName,
+		constant.LabelIPPoolOwnerApplicationGV:        applicationinformers.ApplicationLabelGV(podController.APIVersion),
+		constant.LabelIPPoolOwnerApplicationKind:      podController.Kind,
+		constant.LabelIPPoolOwnerApplicationNamespace: podController.Namespace,
+		constant.LabelIPPoolOwnerApplicationName:      podController.Name,
+		constant.LabelIPPoolOwnerApplicationUID:       string(podController.UID),
+		constant.LabelIPPoolInterface:                 ifName,
+		constant.LabelIPPoolIPVersion:                 labelIPPoolIPVersionValue,
 	}
 	for j := 1; j <= i.config.OperationRetries; j++ {
 		poolList, err := i.ipPoolManager.ListIPPools(ctx, constant.UseCache, matchLabels)
@@ -250,19 +253,15 @@ func (i *ipam) findAppAutoPool(ctx context.Context, subnetName, ifName, labelIPP
 func (i *ipam) applyThirdControllerAutoPool(ctx context.Context, subnetName string, podController types.PodTopController, autoPoolProperty types.AutoPoolProperty) (*spiderpoolv2beta1.SpiderIPPool, error) {
 	log := logutils.FromContext(ctx)
 
-	var labelIPPoolIPVersionValue string
-	if autoPoolProperty.IPVersion == constant.IPv4 {
-		labelIPPoolIPVersionValue = constant.LabelValueIPVersionV4
-	} else {
-		labelIPPoolIPVersionValue = constant.LabelValueIPVersionV6
-	}
-
 	var pool *spiderpoolv2beta1.SpiderIPPool
 	matchLabels := client.MatchingLabels{
-		constant.LabelIPPoolOwnerSpiderSubnet: subnetName,
-		constant.LabelIPPoolOwnerApplication:  subnetmanagercontrollers.ApplicationNamespacedName(podController.AppNamespacedName),
-		constant.LabelIPPoolIPVersion:         labelIPPoolIPVersionValue,
-		constant.LabelIPPoolInterface:         autoPoolProperty.IfName,
+		constant.LabelIPPoolOwnerSpiderSubnet:         subnetName,
+		constant.LabelIPPoolOwnerApplicationGV:        applicationinformers.ApplicationLabelGV(podController.APIVersion),
+		constant.LabelIPPoolOwnerApplicationKind:      podController.Kind,
+		constant.LabelIPPoolOwnerApplicationNamespace: podController.Namespace,
+		constant.LabelIPPoolOwnerApplicationName:      podController.Name,
+		constant.LabelIPPoolIPVersion:                 applicationinformers.AutoPoolIPVersionLabelValue(autoPoolProperty.IPVersion),
+		constant.LabelIPPoolInterface:                 autoPoolProperty.IfName,
 	}
 	for j := 1; j <= i.config.OperationRetries; j++ {
 		poolList, err := i.ipPoolManager.ListIPPools(ctx, constant.UseCache, matchLabels)
diff --git a/pkg/ippoolmanager/ippool_informer.go b/pkg/ippoolmanager/ippool_informer.go
index 1ad465a6e..e5f34f4e4 100644
--- a/pkg/ippoolmanager/ippool_informer.go
+++ b/pkg/ippoolmanager/ippool_informer.go
@@ -32,6 +32,7 @@ import (
 	listers "github.com/spidernet-io/spiderpool/pkg/k8s/client/listers/spiderpool.spidernet.io/v2beta1"
 	"github.com/spidernet-io/spiderpool/pkg/logutils"
 	"github.com/spidernet-io/spiderpool/pkg/metric"
+	"github.com/spidernet-io/spiderpool/pkg/types"
 )
 
 var informerLogger *zap.Logger
@@ -366,31 +367,34 @@ func (ic *IPPoolController) cleanAutoIPPoolLegacy(ctx context.Context, pool *spi
 
 	if pool.Status.AllocatedIPs == nil {
 		// unpack the IPPool corresponding application type,namespace and name
-		appNamespacedNameStr := poolLabels[constant.LabelIPPoolOwnerApplication]
-		appNamespacedName, isMatch := applicationinformers.ParseApplicationNamespacedName(appNamespacedNameStr)
+		appGVStr := poolLabels[constant.LabelIPPoolOwnerApplicationGV]
+		appAPIVersion, isMatch := applicationinformers.ParseApplicationGVStr(appGVStr)
 		if !isMatch {
-			return fmt.Errorf("%w: invalid IPPool label '%s' value '%s'", constant.ErrWrongInput, constant.LabelIPPoolOwnerApplication, appNamespacedNameStr)
+			return fmt.Errorf("%w: invalid IPPool label '%s' value '%s'", constant.ErrWrongInput, constant.LabelIPPoolOwnerApplicationGV, appGVStr)
+		}
+
+		appNamespacedName := types.AppNamespacedName{
+			APIVersion: appAPIVersion,
+			Kind:       poolLabels[constant.LabelIPPoolOwnerApplicationKind],
+			Namespace:  poolLabels[constant.LabelIPPoolOwnerApplicationNamespace],
+			Name:       poolLabels[constant.LabelIPPoolOwnerApplicationName],
 		}
 
 		enableDelete := false
 		// check the IPPool's corresponding application whether is existed or not
-		informerLogger.Sugar().Debugf("try to get auto-created IPPool '%s' corresponding application '%s/%s/%s'",
-			pool.Name, appNamespacedName.Kind, appNamespacedName.Namespace, appNamespacedName.Name)
+		informerLogger.Sugar().Debugf("try to get auto-created IPPool '%s' corresponding application '%v'", pool.Name, appNamespacedName)
 		isAppExist, appUID, err := applicationinformers.IsAppExist(ctx, ic.client, ic.dynamicClient, appNamespacedName)
 		if nil != err {
-			return fmt.Errorf("failed to get auto-created IPPool '%s' corresponding application '%s/%s/%s': %w",
-				pool.Name, appNamespacedName.Kind, appNamespacedName.Namespace, appNamespacedName.Name, err)
+			return fmt.Errorf("failed to get auto-created IPPool '%s' corresponding application '%v': %w", pool.Name, appNamespacedName, err)
 		}
 
 		// mismatch application UID
 		if !isAppExist {
-			informerLogger.Sugar().Warnf("auto-created IPPool '%s' corresponding application '%s/%s/%s' no longer exist, try to delete IPPool",
-				pool.Name, appNamespacedName.Kind, appNamespacedName.Namespace, appNamespacedName.Name)
+			informerLogger.Sugar().Warnf("auto-created IPPool '%s' corresponding application '%v' no longer exist, try to delete IPPool", pool.Name, appNamespacedName)
 			enableDelete = true
 		} else {
 			if string(appUID) != poolLabels[constant.LabelIPPoolOwnerApplicationUID] {
-				informerLogger.Sugar().Warnf("auto-created IPPool '%s' mismatches application '%s/%s/%s' UID '%s', try to delete IPPool",
-					pool.Name, appNamespacedName.Kind, appNamespacedName.Namespace, appNamespacedName.Name, appUID)
+				informerLogger.Sugar().Warnf("auto-created IPPool '%s' mismatches application '%v' UID '%s', try to delete IPPool", pool.Name, appNamespacedName, appUID)
 				enableDelete = true
 			}
 		}
diff --git a/pkg/ippoolmanager/utils.go b/pkg/ippoolmanager/utils.go
index 85c470def..83a670317 100644
--- a/pkg/ippoolmanager/utils.go
+++ b/pkg/ippoolmanager/utils.go
@@ -17,7 +17,7 @@ import (
 func IsAutoCreatedIPPool(pool *spiderpoolv2beta1.SpiderIPPool) bool {
 	// only the auto-created IPPool owns the annotation "ipam.spidernet.io/owner-application"
 	poolLabels := pool.GetLabels()
-	_, ok := poolLabels[constant.LabelIPPoolOwnerApplication]
+	_, ok := poolLabels[constant.LabelIPPoolOwnerApplicationName]
 	return ok
 }
 
diff --git a/pkg/subnetmanager/subnet_manager.go b/pkg/subnetmanager/subnet_manager.go
index 783f8bca1..4dda53672 100644
--- a/pkg/subnetmanager/subnet_manager.go
+++ b/pkg/subnetmanager/subnet_manager.go
@@ -121,14 +121,21 @@ func (sm *subnetManager) ReconcileAutoIPPool(ctx context.Context, pool *spiderpo
 		if nil != err {
 			return nil, fmt.Errorf("%w: failed to parse IPPool %s Spec IPs %s: %v", constant.ErrWrongInput, pool.Name, pool.Spec.IPs, err)
 		}
-		if len(poolIPs) == autoPoolProperty.DesiredIPNumber && pool.Labels[constant.LabelIPPoolOwnerApplicationUID] == string(podController.UID) {
-			log.Sugar().Debugf("Auto-created IPPool %s matches the desired IP number %d, no need to reconcile", pool.Name, autoPoolProperty.DesiredIPNumber)
-			return pool, nil
+		if len(poolIPs) == autoPoolProperty.DesiredIPNumber {
+			oldAppUID := pool.Labels[constant.LabelIPPoolOwnerApplicationUID]
+			oldReclaimIPPoolStr := pool.Labels[constant.LabelIPPoolReclaimIPPool]
+
+			if oldAppUID == string(podController.UID) &&
+				oldReclaimIPPoolStr == applicationinformers.IsReclaimAutoPoolLabelValue(autoPoolProperty.IsReclaimIPPool) {
+				log.Sugar().Debugf("Auto-created IPPool %s matches the desired IP number %d, no need to reconcile", pool.Name, autoPoolProperty.DesiredIPNumber)
+				return pool, nil
+			}
 		}
 
-		// refresh the label "ipam.spidernet.io/owner-application-uid"
+		// refresh the label "ipam.spidernet.io/owner-application-uid" and "ipam.spidernet.io/ippool-reclaim"
 		labels := pool.GetLabels()
 		labels[constant.LabelIPPoolOwnerApplicationUID] = string(podController.UID)
+		labels[constant.LabelIPPoolReclaimIPPool] = applicationinformers.IsReclaimAutoPoolLabelValue(autoPoolProperty.IsReclaimIPPool)
 		pool.SetLabels(labels)
 	} else {
 		pool = &spiderpoolv2beta1.SpiderIPPool{
@@ -147,10 +154,15 @@ func (sm *subnetManager) ReconcileAutoIPPool(ctx context.Context, pool *spiderpo
 
 		{
 			poolLabels := map[string]string{
-				constant.LabelIPPoolOwnerSpiderSubnet:   subnet.Name,
-				constant.LabelIPPoolOwnerApplication:    applicationinformers.ApplicationNamespacedName(podController.AppNamespacedName),
-				constant.LabelIPPoolOwnerApplicationUID: string(podController.UID),
-				constant.LabelIPPoolInterface:           autoPoolProperty.IfName,
+				constant.LabelIPPoolOwnerSpiderSubnet:         subnet.Name,
+				constant.LabelIPPoolOwnerApplicationGV:        applicationinformers.ApplicationLabelGV(podController.APIVersion),
+				constant.LabelIPPoolOwnerApplicationKind:      podController.Kind,
+				constant.LabelIPPoolOwnerApplicationNamespace: podController.Namespace,
+				constant.LabelIPPoolOwnerApplicationName:      podController.Name,
+				constant.LabelIPPoolOwnerApplicationUID:       string(podController.UID),
+				constant.LabelIPPoolInterface:                 autoPoolProperty.IfName,
+				constant.LabelIPPoolReclaimIPPool:             applicationinformers.IsReclaimAutoPoolLabelValue(autoPoolProperty.IsReclaimIPPool),
+				constant.LabelIPPoolIPVersion:                 applicationinformers.AutoPoolIPVersionLabelValue(autoPoolProperty.IPVersion),
 			}
 			// label IPPoolCIDR
 			cidrLabelValue, err := spiderpoolip.CIDRToLabelValue(*pool.Spec.IPVersion, pool.Spec.Subnet)
@@ -158,18 +170,7 @@ func (sm *subnetManager) ReconcileAutoIPPool(ctx context.Context, pool *spiderpo
 				return nil, fmt.Errorf("failed to parse '%s' when allocating empty Auto-created IPPool '%v'", pool.Spec.Subnet, pool)
 			}
 			poolLabels[constant.LabelIPPoolCIDR] = cidrLabelValue
-			if autoPoolProperty.IsReclaimIPPool {
-				poolLabels[constant.LabelIPPoolReclaimIPPool] = constant.True
-			} else {
-				poolLabels[constant.LabelIPPoolReclaimIPPool] = constant.False
-			}
-			// label IPVersion
-			if autoPoolProperty.IPVersion == constant.IPv4 {
-				poolLabels[constant.LabelIPPoolIPVersion] = constant.LabelValueIPVersionV4
-			} else {
-				poolLabels[constant.LabelIPPoolIPVersion] = constant.LabelValueIPVersionV6
-			}
-			pool.Labels = poolLabels
+			pool.SetLabels(poolLabels)
 		}
 
 		// set owner reference


Test patch:
diff --git a/pkg/ippoolmanager/ippool_webhook_test.go b/pkg/ippoolmanager/ippool_webhook_test.go
index a50c7ebde..d5aab102d 100644
--- a/pkg/ippoolmanager/ippool_webhook_test.go
+++ b/pkg/ippoolmanager/ippool_webhook_test.go
@@ -1762,12 +1762,12 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					subnetT.Spec.IPs = append(subnetT.Spec.IPs, "172.18.40.1-172.18.40.2")
 
 					autoPool := ipPoolT.DeepCopy()
-					autoPool.Labels = map[string]string{constant.LabelIPPoolOwnerApplication: applicationinformers.ApplicationNamespacedName(types.AppNamespacedName{
-						APIVersion: appsv1.SchemeGroupVersion.String(),
-						Kind:       constant.KindDeployment,
-						Namespace:  autoPool.Namespace,
-						Name:       autoPool.Name,
-					})}
+					autoPool.Labels = map[string]string{
+						constant.LabelIPPoolOwnerApplicationGV:        applicationinformers.ApplicationLabelGV(appsv1.SchemeGroupVersion.String()),
+						constant.LabelIPPoolOwnerApplicationKind:      constant.KindDeployment,
+						constant.LabelIPPoolOwnerApplicationNamespace: "test-ns",
+						constant.LabelIPPoolOwnerApplicationName:      "test-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")
@@ -1775,8 +1775,13 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					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.Labels[constant.LabelIPPoolOwnerApplication]),
+						IPs: []string{"172.18.40.1"},
+						Application: pointer.String(applicationinformers.ApplicationNamespacedName(types.AppNamespacedName{
+							APIVersion: appsv1.SchemeGroupVersion.String(),
+							Kind:       constant.KindDeployment,
+							Namespace:  "test-ns",
+							Name:       "test-name",
+						})),
 					}}
 					subnetAllocatedIPPools, err := convert.MarshalSubnetAllocatedIPPools(poolIPPreAllocations)
 					Expect(err).NotTo(HaveOccurred())
@@ -1799,12 +1804,12 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					subnetT.Spec.IPs = append(subnetT.Spec.IPs, "172.18.40.1-172.18.40.2")
 
 					autoPool := ipPoolT.DeepCopy()
-					autoPool.Labels = map[string]string{constant.LabelIPPoolOwnerApplication: applicationinformers.ApplicationNamespacedName(types.AppNamespacedName{
-						APIVersion: appsv1.SchemeGroupVersion.String(),
-						Kind:       constant.KindDeployment,
-						Namespace:  autoPool.Namespace,
-						Name:       autoPool.Name,
-					})}
+					autoPool.Labels = map[string]string{
+						constant.LabelIPPoolOwnerApplicationGV:        applicationinformers.ApplicationLabelGV(appsv1.SchemeGroupVersion.String()),
+						constant.LabelIPPoolOwnerApplicationKind:      constant.KindDeployment,
+						constant.LabelIPPoolOwnerApplicationNamespace: "test-ns",
+						constant.LabelIPPoolOwnerApplicationName:      "test-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")
@@ -1812,8 +1817,13 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					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.Labels[constant.LabelIPPoolOwnerApplication]),
+						IPs: []string{"172.18.40.1"},
+						Application: pointer.String(applicationinformers.ApplicationNamespacedName(types.AppNamespacedName{
+							APIVersion: appsv1.SchemeGroupVersion.String(),
+							Kind:       constant.KindDeployment,
+							Namespace:  "test-ns",
+							Name:       "test-name",
+						})),
 					}}
 					subnetAllocatedIPPools, err := convert.MarshalSubnetAllocatedIPPools(poolIPPreAllocations)
 					Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/ippoolmanager/utils_test.go b/pkg/ippoolmanager/utils_test.go
index 4b63059fe..d1136bb6e 100644
--- a/pkg/ippoolmanager/utils_test.go
+++ b/pkg/ippoolmanager/utils_test.go
@@ -9,7 +9,6 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	types2 "k8s.io/apimachinery/pkg/types"
 
-	"github.com/spidernet-io/spiderpool/pkg/applicationcontroller/applicationinformers"
 	"github.com/spidernet-io/spiderpool/pkg/constant"
 	spiderpoolv2beta1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1"
 	"github.com/spidernet-io/spiderpool/pkg/types"
@@ -20,12 +19,7 @@ var _ = Describe("IPPoolManager-utils", Label("ippool_manager_utils"), func() {
 		It("normal IPPool", func() {
 			var pool spiderpoolv2beta1.SpiderIPPool
 
-			label := map[string]string{constant.LabelIPPoolOwnerApplication: applicationinformers.ApplicationNamespacedName(types.AppNamespacedName{
-				APIVersion: appsv1.SchemeGroupVersion.String(),
-				Kind:       constant.KindDeployment,
-				Namespace:  "test-ns",
-				Name:       "test-name",
-			})}
+			label := map[string]string{constant.LabelIPPoolOwnerApplicationName: "test-name"}
 			pool.SetLabels(label)
 
 			isAutoCreatedIPPool := IsAutoCreatedIPPool(&pool)