Repository: kubernetes-sigs/cloud-provider-azure
Pull request #3804 (2023-04-23 02:36:13)

[release-1.27] clean up old pip list optimization
This is an automated cherry-pick of #3773

/assign jwtty

```release-note
NONE
```


Patch:
diff --git a/pkg/provider/azure_loadbalancer.go b/pkg/provider/azure_loadbalancer.go
index 691e5b4f1..4e9e50307 100644
--- a/pkg/provider/azure_loadbalancer.go
+++ b/pkg/provider/azure_loadbalancer.go
@@ -52,9 +52,8 @@ import (
 // We need to make sure the existence of the load balancer depends on the load balancer resource and public IP resource on Azure.
 func (az *Cloud) existsPip(clusterName string, service *v1.Service) bool {
 	v4Enabled, v6Enabled := getIPFamiliesEnabled(service)
-	var pips []network.PublicIPAddress
 	existsPipSingleStack := func(isIPv6 bool) bool {
-		pipName, _, err := az.determinePublicIPName(clusterName, service, &pips, isIPv6)
+		pipName, _, err := az.determinePublicIPName(clusterName, service, isIPv6)
 		if err != nil {
 			return false
 		}
@@ -121,8 +120,7 @@ func (az *Cloud) reconcileService(ctx context.Context, clusterName string, servi
 		return nil, err
 	}
 
-	var pips []network.PublicIPAddress
-	lbStatus, fipConfig, err := az.getServiceLoadBalancerStatus(service, lb, &pips)
+	lbStatus, fipConfig, err := az.getServiceLoadBalancerStatus(service, lb)
 	if err != nil {
 		klog.Errorf("getServiceLoadBalancerStatus(%s) failed: %v", serviceName, err)
 		if !errors.Is(err, ErrorNotVmssInstance) {
@@ -627,9 +625,6 @@ func (az *Cloud) getServiceLoadBalancer(service *v1.Service, clusterName string,
 		}
 	}
 
-	// reuse pip list to reduce api call
-	var pips []network.PublicIPAddress
-
 	// check if the service already has a load balancer
 	for i := range existingLBs {
 		existingLB := existingLBs[i]
@@ -666,7 +661,7 @@ func (az *Cloud) getServiceLoadBalancer(service *v1.Service, clusterName string,
 			continue
 		}
 		var fipConfig *network.FrontendIPConfiguration
-		status, fipConfig, err = az.getServiceLoadBalancerStatus(service, &existingLB, &pips)
+		status, fipConfig, err = az.getServiceLoadBalancerStatus(service, &existingLB)
 		if err != nil {
 			return nil, nil, false, err
 		}
@@ -800,8 +795,7 @@ func (az *Cloud) selectLoadBalancer(clusterName string, service *v1.Service, exi
 	return selectedLB, existsLb, nil
 }
 
-// pips: a non-nil pointer to a slice of existing PIPs, if the slice being pointed to is nil, listPIP would be called when needed and the slice would be filled
-func (az *Cloud) getServiceLoadBalancerStatus(service *v1.Service, lb *network.LoadBalancer, pips *[]network.PublicIPAddress) (status *v1.LoadBalancerStatus, fipConfig *network.FrontendIPConfiguration, err error) {
+func (az *Cloud) getServiceLoadBalancerStatus(service *v1.Service, lb *network.LoadBalancer) (status *v1.LoadBalancerStatus, fipConfig *network.FrontendIPConfiguration, err error) {
 	if lb == nil {
 		klog.V(10).Info("getServiceLoadBalancerStatus: lb is nil")
 		return nil, nil, nil
@@ -814,7 +808,7 @@ func (az *Cloud) getServiceLoadBalancerStatus(service *v1.Service, lb *network.L
 	serviceName := getServiceName(service)
 	for _, ipConfiguration := range *lb.FrontendIPConfigurations {
 		ipConfiguration := ipConfiguration
-		owns, isPrimaryService, err := az.serviceOwnsFrontendIP(ipConfiguration, service, pips)
+		owns, isPrimaryService, err := az.serviceOwnsFrontendIP(ipConfiguration, service)
 		if err != nil {
 			return nil, nil, fmt.Errorf("get(%s): lb(%s) - failed to filter frontend IP configs with error: %w", serviceName, pointer.StringDeref(lb.Name, ""), err)
 		}
@@ -868,15 +862,14 @@ func (az *Cloud) getServiceLoadBalancerStatus(service *v1.Service, lb *network.L
 	return nil, nil, nil
 }
 
-// pips: a non-nil pointer to a slice of existing PIPs, if the slice being pointed to is nil, listPIP would be called when needed and the slice would be filled
-func (az *Cloud) determinePublicIPName(clusterName string, service *v1.Service, pips *[]network.PublicIPAddress, isIPv6 bool) (string, bool, error) {
+func (az *Cloud) determinePublicIPName(clusterName string, service *v1.Service, isIPv6 bool) (string, bool, error) {
 	if name := getServicePIPName(service, isIPv6); name != "" {
 		return name, true, nil
 	}
 
 	pipResourceGroup := az.getPublicIPAddressResourceGroup(service)
 	if id := getServicePIPPrefixID(service, isIPv6); id != "" {
-		pipName, err := az.getPublicIPName(clusterName, service, pipResourceGroup, pips, isIPv6)
+		pipName, err := az.getPublicIPName(clusterName, service, pipResourceGroup, isIPv6)
 		return pipName, false, err
 	}
 
@@ -885,13 +878,13 @@ func (az *Cloud) determinePublicIPName(clusterName string, service *v1.Service,
 	// Assume that the service without loadBalancerIP set is a primary service.
 	// If a secondary service doesn't set the loadBalancerIP, it is not allowed to share the IP.
 	if len(loadBalancerIP) == 0 {
-		pipName, err := az.getPublicIPName(clusterName, service, pipResourceGroup, pips, isIPv6)
+		pipName, err := az.getPublicIPName(clusterName, service, pipResourceGroup, isIPv6)
 		return pipName, false, err
 	}
 
 	// For the services with loadBalancerIP set, an existing public IP is required, primary
 	// or secondary, or a public IP not found error would be reported.
-	pip, err := az.findMatchedPIPByLoadBalancerIP(service, loadBalancerIP, pipResourceGroup, pips)
+	pip, err := az.findMatchedPIPByLoadBalancerIP(service, loadBalancerIP, pipResourceGroup)
 	if err != nil {
 		return "", false, err
 	}
@@ -903,28 +896,15 @@ func (az *Cloud) determinePublicIPName(clusterName string, service *v1.Service,
 	return "", false, fmt.Errorf("user supplied IP Address %s was not found in resource group %s", loadBalancerIP, pipResourceGroup)
 }
 
-func (az *Cloud) safeListPIP(pipResourceGroup string, pips *[]network.PublicIPAddress) error {
-	if pips == nil {
-		// this should not happen
-		return fmt.Errorf("nil pip list passed")
-	} else if *pips == nil {
-		pipList, err := az.listPIP(pipResourceGroup)
-		if err != nil {
-			return err
-		}
-		*pips = pipList
-	}
-	return nil
-}
-
 // findMatchedPIPByIPFamilyAndServiceName is for IPv6. It tries to find a matching PIP whose name doesn't have IPv6 suffix.
 // Such PIP comes from old CCM without dual-stack support.
-func (az *Cloud) findMatchedPIPByIPFamilyAndServiceName(clusterName string, service *v1.Service, pipResourceGroup string, pips *[]network.PublicIPAddress) (*network.PublicIPAddress, error) {
-	if err := az.safeListPIP(pipResourceGroup, pips); err != nil {
-		return nil, fmt.Errorf("findMatchedPIPByIPFamilyAndServiceName: failed to ensurePIP: %w", err)
+func (az *Cloud) findMatchedPIPByIPFamilyAndServiceName(clusterName string, service *v1.Service, pipResourceGroup string) (*network.PublicIPAddress, error) {
+	pips, err := az.listPIP(pipResourceGroup)
+	if err != nil {
+		return nil, fmt.Errorf("findMatchedPIPByIPFamilyAndServiceName: failed to listPIP: %w", err)
 	}
 	baseName := az.GetLoadBalancerName(context.TODO(), clusterName, service)
-	for _, pip := range *pips {
+	for _, pip := range pips {
 		pip := pip
 		if pointer.StringDeref(pip.Name, "") == baseName && pip.PublicIPAddressPropertiesFormat != nil &&
 			pip.PublicIPAddressPropertiesFormat.PublicIPAddressVersion == network.IPv6 {
@@ -934,12 +914,12 @@ func (az *Cloud) findMatchedPIPByIPFamilyAndServiceName(clusterName string, serv
 	return nil, nil
 }
 
-// pips: a non-nil pointer to a slice of existing PIPs, if the slice being pointed to is nil, listPIP would be called when needed and the slice would be filled
-func (az *Cloud) findMatchedPIPByLoadBalancerIP(service *v1.Service, loadBalancerIP, pipResourceGroup string, pips *[]network.PublicIPAddress) (*network.PublicIPAddress, error) {
-	if err := az.safeListPIP(pipResourceGroup, pips); err != nil {
-		return nil, fmt.Errorf("findMatchedPIPByLoadBalancerIP: failed to ensurePIP: %w", err)
+func (az *Cloud) findMatchedPIPByLoadBalancerIP(service *v1.Service, loadBalancerIP, pipResourceGroup string) (*network.PublicIPAddress, error) {
+	pips, err := az.listPIP(pipResourceGroup)
+	if err != nil {
+		return nil, fmt.Errorf("findMatchedPIPByLoadBalancerIP: failed to listPIP: %w", err)
 	}
-	for _, pip := range *pips {
+	for _, pip := range pips {
 		pip := pip
 		if pip.PublicIPAddressPropertiesFormat.IPAddress != nil &&
 			*pip.PublicIPAddressPropertiesFormat.IPAddress == loadBalancerIP {
@@ -1365,9 +1345,8 @@ func getDomainNameLabel(pip *network.PublicIPAddress) string {
 	return pointer.StringDeref(pip.PublicIPAddressPropertiesFormat.DNSSettings.DomainNameLabel, "")
 }
 
-// pips: a non-nil pointer to a slice of existing PIPs, if the slice being pointed to is nil, listPIP would be called when needed and the slice would be filled
-func (az *Cloud) isFrontendIPChanged(clusterName string, config network.FrontendIPConfiguration, service *v1.Service, lbFrontendIPConfigName string, pips *[]network.PublicIPAddress) (bool, error) {
-	isServiceOwnsFrontendIP, isPrimaryService, err := az.serviceOwnsFrontendIP(config, service, pips)
+func (az *Cloud) isFrontendIPChanged(clusterName string, config network.FrontendIPConfiguration, service *v1.Service, lbFrontendIPConfigName string) (bool, error) {
+	isServiceOwnsFrontendIP, isPrimaryService, err := az.serviceOwnsFrontendIP(config, service)
 	if err != nil {
 		return false, err
 	}
@@ -1397,7 +1376,7 @@ func (az *Cloud) isFrontendIPChanged(clusterName string, config network.Frontend
 		}
 		return loadBalancerIP != "" && !strings.EqualFold(loadBalancerIP, pointer.StringDeref(config.PrivateIPAddress, "")), nil
 	}
-	pipName, _, err := az.determinePublicIPName(clusterName, service, pips, isIPv6)
+	pipName, _, err := az.determinePublicIPName(clusterName, service, isIPv6)
 	if err != nil {
 		return false, err
 	}
@@ -1526,11 +1505,10 @@ func findMatchedOutboundRuleFIPConfig(fipConfigID *string, outboundRuleFIPConfig
 func (az *Cloud) findFrontendIPConfigOfService(
 	fipConfigs *[]network.FrontendIPConfiguration,
 	service *v1.Service,
-	pips *[]network.PublicIPAddress,
 ) (*network.FrontendIPConfiguration, error) {
 	for _, config := range *fipConfigs {
 		config := config
-		owns, _, err := az.serviceOwnsFrontendIP(config, service, pips)
+		owns, _, err := az.serviceOwnsFrontendIP(config, service)
 		if err != nil {
 			return nil, err
 		}
@@ -1804,13 +1782,11 @@ func (az *Cloud) reconcileFrontendIPConfigs(clusterName string, service *v1.Serv
 		newConfigs = *lb.FrontendIPConfigurations
 	}
 
-	// Save pip list so it can be reused in loop
-	var pips []network.PublicIPAddress
 	var ownedFIPConfig *network.FrontendIPConfiguration
 	if !wantLb {
 		for i := len(newConfigs) - 1; i >= 0; i-- {
 			config := newConfigs[i]
-			isServiceOwnsFrontendIP, _, err := az.serviceOwnsFrontendIP(config, service, &pips)
+			isServiceOwnsFrontendIP, _, err := az.serviceOwnsFrontendIP(config, service)
 			if err != nil {
 				return nil, toDeleteConfigs, false, err
 			}
@@ -1848,13 +1824,13 @@ func (az *Cloud) reconcileFrontendIPConfigs(clusterName string, service *v1.Serv
 		)
 		for i := len(newConfigs) - 1; i >= 0; i-- {
 			config := newConfigs[i]
-			isServiceOwnsFrontendIP, _, _ := az.serviceOwnsFrontendIP(config, service, &pips)
+			isServiceOwnsFrontendIP, _, _ := az.serviceOwnsFrontendIP(config, service)
 			if !isServiceOwnsFrontendIP {
 				klog.V(4).Infof("reconcileFrontendIPConfigs for service (%s): the frontend IP configuration %s does not belong to the service", serviceName, pointer.StringDeref(config.Name, ""))
 				continue
 			}
 			klog.V(4).Infof("reconcileFrontendIPConfigs for service (%s): checking owned frontend IP configuration %s", serviceName, pointer.StringDeref(config.Name, ""))
-			isFipChanged, err = az.isFrontendIPChanged(clusterName, config, service, defaultLBFrontendIPConfigName, &pips)
+			isFipChanged, err = az.isFrontendIPChanged(clusterName, config, service, defaultLBFrontendIPConfigName)
 			if err != nil {
 				return nil, toDeleteConfigs, false, err
 			}
@@ -1868,7 +1844,7 @@ func (az *Cloud) reconcileFrontendIPConfigs(clusterName string, service *v1.Serv
 			break
 		}
 
-		ownedFIPConfig, err = az.findFrontendIPConfigOfService(&newConfigs, service, &pips)
+		ownedFIPConfig, err = az.findFrontendIPConfigOfService(&newConfigs, service)
 		if err != nil {
 			return nil, toDeleteConfigs, false, err
 		}
@@ -1918,7 +1894,7 @@ func (az *Cloud) reconcileFrontendIPConfigs(clusterName string, service *v1.Serv
 				fipConfigurationProperties = &configProperties
 			} else {
 				isIPv6 := utilnet.IsIPv6String(service.Spec.ClusterIP) // TODO: dualstack support
-				pipName, shouldPIPExisted, err := az.determinePublicIPName(clusterName, service, &pips, isIPv6)
+				pipName, shouldPIPExisted, err := az.determinePublicIPName(clusterName, service, isIPv6)
 				if err != nil {
 					return nil, toDeleteConfigs, false, err
 				}
@@ -3101,7 +3077,7 @@ func (az *Cloud) reconcilePublicIP(pips []network.PublicIPAddress, clusterName s
 	)
 
 	if !isInternal && wantLb {
-		desiredPipName, shouldPIPExisted, err = az.determinePublicIPName(clusterName, service, &pips, isIPv6)
+		desiredPipName, shouldPIPExisted, err = az.determinePublicIPName(clusterName, service, isIPv6)
 		if err != nil {
 			return nil, err
 		}
diff --git a/pkg/provider/azure_standard.go b/pkg/provider/azure_standard.go
index 85e89d398..b3ed6e488 100644
--- a/pkg/provider/azure_standard.go
+++ b/pkg/provider/azure_standard.go
@@ -326,10 +326,10 @@ func (az *Cloud) getRulePrefix(service *v1.Service) string {
 	return az.GetLoadBalancerName(context.TODO(), "", service)
 }
 
-func (az *Cloud) getPublicIPName(clusterName string, service *v1.Service, pipResourceGroup string, pips *[]network.PublicIPAddress, isIPv6 bool) (string, error) {
+func (az *Cloud) getPublicIPName(clusterName string, service *v1.Service, pipResourceGroup string, isIPv6 bool) (string, error) {
 	// For IPv6, the PIP may not have IPv6 suffix because it may be one created before dual-stack support.
 	if isIPv6 {
-		pip, err := az.findMatchedPIPByIPFamilyAndServiceName(clusterName, service, pipResourceGroup, pips)
+		pip, err := az.findMatchedPIPByIPFamilyAndServiceName(clusterName, service, pipResourceGroup)
 		if err != nil {
 			return "", err
 		}
@@ -359,7 +359,7 @@ func (az *Cloud) serviceOwnsRule(service *v1.Service, rule string) bool {
 // This means the name of the config can be tracked by the service UID.
 // 2. The secondary services must have their loadBalancer IP set if they want to share the same config as the primary
 // service. Hence, it can be tracked by the loadBalancer IP.
-func (az *Cloud) serviceOwnsFrontendIP(fip network.FrontendIPConfiguration, service *v1.Service, pips *[]network.PublicIPAddress) (bool, bool, error) {
+func (az *Cloud) serviceOwnsFrontendIP(fip network.FrontendIPConfiguration, service *v1.Service) (bool, bool, error) {
 	var isPrimaryService bool
 	baseName := az.GetLoadBalancerName(context.TODO(), "", service)
 	if strings.HasPrefix(pointer.StringDeref(fip.Name, ""), baseName) {
@@ -378,7 +378,7 @@ func (az *Cloud) serviceOwnsFrontendIP(fip network.FrontendIPConfiguration, serv
 	if !requiresInternalLoadBalancer(service) {
 		pipResourceGroup := az.getPublicIPAddressResourceGroup(service)
 		for _, loadBalancerIP := range loadBalancerIPs {
-			pip, err := az.findMatchedPIPByLoadBalancerIP(service, loadBalancerIP, pipResourceGroup, pips)
+			pip, err := az.findMatchedPIPByLoadBalancerIP(service, loadBalancerIP, pipResourceGroup)
 			if err != nil {
 				klog.Warningf("serviceOwnsFrontendIP: unexpected error when finding match public IP of the service %s with loadBalancerIP %s: %v", service.Name, loadBalancerIP, err)
 				return false, isPrimaryService, nil
diff --git a/pkg/provider/azure_utils.go b/pkg/provider/azure_utils.go
index 1c46c535a..c9dd45b78 100644
--- a/pkg/provider/azure_utils.go
+++ b/pkg/provider/azure_utils.go
@@ -443,9 +443,10 @@ func getResourceByIPFamily(resource string, isIPv6 bool) string {
 }
 
 // isFIPIPv6 checks if the frontend IP configuration is of IPv6.
-func (az *Cloud) isFIPIPv6(fip *network.FrontendIPConfiguration, pips *[]network.PublicIPAddress, isInternal bool) (isIPv6 bool, err error) {
-	if err := az.safeListPIP(az.ResourceGroup, pips); err != nil {
-		return false, fmt.Errorf("failed to ensure PIP is refreshed: %w", err)
+func (az *Cloud) isFIPIPv6(fip *network.FrontendIPConfiguration, pipResourceGroup string, isInternal bool) (isIPv6 bool, err error) {
+	pips, err := az.listPIP(pipResourceGroup)
+	if err != nil {
+		return false, fmt.Errorf("isFIPIPv6: failed to list pip: %w", err)
 	}
 	if isInternal {
 		if fip.FrontendIPConfigurationPropertiesFormat != nil {
@@ -463,7 +464,7 @@ func (az *Cloud) isFIPIPv6(fip *network.FrontendIPConfiguration, pips *[]network
 	if fip.FrontendIPConfigurationPropertiesFormat != nil && fip.FrontendIPConfigurationPropertiesFormat.PublicIPAddress != nil {
 		fipPIPID = pointer.StringDeref(fip.FrontendIPConfigurationPropertiesFormat.PublicIPAddress.ID, "")
 	}
-	for _, pip := range *pips {
+	for _, pip := range pips {
 		id := pointer.StringDeref(pip.ID, "")
 		if !strings.EqualFold(fipPIPID, id) {
 			continue


Test patch:
diff --git a/pkg/provider/azure_loadbalancer_test.go b/pkg/provider/azure_loadbalancer_test.go
index e5256a8f1..bc62680b0 100644
--- a/pkg/provider/azure_loadbalancer_test.go
+++ b/pkg/provider/azure_loadbalancer_test.go
@@ -2143,9 +2143,8 @@ func TestIsFrontendIPChanged(t *testing.T) {
 			service := test.service
 			setServiceLoadBalancerIP(&service, test.loadBalancerIP)
 			test.service.Annotations[consts.ServiceAnnotationLoadBalancerInternalSubnet] = test.annotations
-			existingPIPs := test.existingPIPs
 			flag, rerr := az.isFrontendIPChanged("testCluster", test.config,
-				&service, test.lbFrontendIPConfigName, &existingPIPs)
+				&service, test.lbFrontendIPConfigName)
 			if rerr != nil {
 				fmt.Println(rerr.Error())
 			}
@@ -2165,34 +2164,21 @@ func TestFindMatchedPIPByLoadBalancerIP(t *testing.T) {
 			IPAddress: pointer.String("1.2.3.4"),
 		},
 	}
-	var nilPIPs []network.PublicIPAddress
 	testCases := []struct {
 		desc          string
-		pips          *[]network.PublicIPAddress
-		pipListResult []network.PublicIPAddress
-		expectedPIPs  *[]network.PublicIPAddress
+		pips          []network.PublicIPAddress
+		expectedPIP   *network.PublicIPAddress
 		expectedError bool
 	}{
 		{
-			desc:          "findMatchedPIPByLoadBalancerIP shall return error if pip slice passed in is nil",
-			expectedError: true,
-		},
-		{
-			desc:          "findMatchedPIPByLoadBalancerIP shall list pips if pip slice passed in is nil",
-			pips:          &nilPIPs,
-			pipListResult: []network.PublicIPAddress{testPIP},
-			expectedPIPs:  &[]network.PublicIPAddress{testPIP},
+			desc:        "findMatchedPIPByLoadBalancerIP shall return the matched ip",
+			pips:        []network.PublicIPAddress{testPIP},
+			expectedPIP: &testPIP,
 		},
 		{
-			desc:          "findMatchedPIPByLoadBalancerIP shall not list pip again if pip slice is empty",
-			pips:          &[]network.PublicIPAddress{},
-			expectedPIPs:  &[]network.PublicIPAddress{},
-			expectedError: true, // pip not found
-		},
-		{
-			desc:         "findMatchedPIPByLoadBalancerIP shall not list pip again if pip slice already has pips",
-			pips:         &[]network.PublicIPAddress{testPIP},
-			expectedPIPs: &[]network.PublicIPAddress{testPIP},
+			desc:          "findMatchedPIPByLoadBalancerIP shall return error if ip is not found",
+			pips:          []network.PublicIPAddress{},
+			expectedError: true,
 		},
 	}
 	for _, test := range testCases {
@@ -2202,11 +2188,9 @@ func TestFindMatchedPIPByLoadBalancerIP(t *testing.T) {
 			setServiceLoadBalancerIP(&service, "1.2.3.4")
 
 			mockPIPsClient := az.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
-			if test.pipListResult != nil {
-				mockPIPsClient.EXPECT().List(gomock.Any(), "rg").Return(test.pipListResult, nil)
-			}
-			_, err := az.findMatchedPIPByLoadBalancerIP(&service, "1.2.3.4", "rg", test.pips)
-			assert.Equal(t, test.expectedPIPs, test.pips)
+			mockPIPsClient.EXPECT().List(gomock.Any(), "rg").Return(test.pips, nil)
+			pip, err := az.findMatchedPIPByLoadBalancerIP(&service, "1.2.3.4", "rg")
+			assert.Equal(t, test.expectedPIP, pip)
 			assert.Equal(t, test.expectedError, err != nil)
 		})
 	}
@@ -2267,8 +2251,7 @@ func TestDeterminePublicIPName(t *testing.T) {
 				err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", *existingPIP.Name, existingPIP)
 				assert.NoError(t, err.Error())
 			}
-			var pips []network.PublicIPAddress
-			pipName, _, err := az.determinePublicIPName("testCluster", &service, &pips, test.isIPv6)
+			pipName, _, err := az.determinePublicIPName("testCluster", &service, test.isIPv6)
 			assert.Equal(t, test.expectedPIPName, pipName)
 			assert.Equal(t, test.expectedError, err != nil)
 		})
@@ -3502,7 +3485,7 @@ func TestGetServiceLoadBalancerStatus(t *testing.T) {
 
 	for _, test := range testCases {
 		t.Run(test.desc, func(t *testing.T) {
-			status, _, err := az.getServiceLoadBalancerStatus(test.service, test.lb, nil)
+			status, _, err := az.getServiceLoadBalancerStatus(test.service, test.lb)
 			assert.Equal(t, test.expectedStatus, status)
 			assert.Equal(t, test.expectedError, err != nil)
 		})
diff --git a/pkg/provider/azure_standard_test.go b/pkg/provider/azure_standard_test.go
index 78546c7db..1945b20d2 100644
--- a/pkg/provider/azure_standard_test.go
+++ b/pkg/provider/azure_standard_test.go
@@ -37,6 +37,7 @@ import (
 	"k8s.io/utils/pointer"
 
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/interfaceclient/mockinterfaceclient"
+	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient/mockvmasclient"
 	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmclient/mockvmclient"
 	azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
@@ -1762,14 +1763,16 @@ func TestServiceOwnsFrontendIP(t *testing.T) {
 			desc: "serviceOwnsFrontendIP should detect the secondary external service dual-stack",
 			existingPIPs: []network.PublicIPAddress{
 				{
-					ID: pointer.String("pip"),
+					Name: pointer.String("pip"),
+					ID:   pointer.String("pip"),
 					PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
 						PublicIPAddressVersion: network.IPv4,
 						IPAddress:              pointer.String("4.3.2.1"),
 					},
 				},
 				{
-					ID: pointer.String("pip1"),
+					Name: pointer.String("pip1"),
+					ID:   pointer.String("pip1"),
 					PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
 						PublicIPAddressVersion: network.IPv6,
 						IPAddress:              pointer.String("fd00::eef0"),
@@ -1843,8 +1846,11 @@ func TestServiceOwnsFrontendIP(t *testing.T) {
 	for _, test := range testCases {
 		t.Run(test.desc, func(t *testing.T) {
 			cloud := GetTestCloud(ctrl)
-			existingPIPs := test.existingPIPs
-			isOwned, isPrimary, err := cloud.serviceOwnsFrontendIP(test.fip, test.service, &existingPIPs)
+			if test.existingPIPs != nil {
+				mockPIPsClient := cloud.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
+				mockPIPsClient.EXPECT().List(gomock.Any(), "rg").Return(test.existingPIPs, nil)
+			}
+			isOwned, isPrimary, err := cloud.serviceOwnsFrontendIP(test.fip, test.service)
 			assert.Equal(t, test.expectedErr, err)
 			assert.Equal(t, test.isOwned, isOwned)
 			assert.Equal(t, test.isPrimary, isPrimary)
@@ -2310,7 +2316,7 @@ func TestGetPublicIPName(t *testing.T) {
 	testcases := []struct {
 		desc            string
 		svc             *v1.Service
-		pips            *[]network.PublicIPAddress
+		pips            []network.PublicIPAddress
 		isIPv6          bool
 		expectedPIPName string
 	}{
@@ -2322,7 +2328,6 @@ func TestGetPublicIPName(t *testing.T) {
 					IPFamilies: []v1.IPFamily{v1.IPv4Protocol},
 				},
 			},
-			pips:            &[]network.PublicIPAddress{},
 			isIPv6:          false,
 			expectedPIPName: "azure-auid",
 		},
@@ -2339,7 +2344,6 @@ func TestGetPublicIPName(t *testing.T) {
 					IPFamilies: []v1.IPFamily{v1.IPv4Protocol},
 				},
 			},
-			pips:            &[]network.PublicIPAddress{},
 			isIPv6:          false,
 			expectedPIPName: "azure-auid-prefix-id",
 		},
@@ -2357,7 +2361,6 @@ func TestGetPublicIPName(t *testing.T) {
 					IPFamilies: []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol},
 				},
 			},
-			pips:            &[]network.PublicIPAddress{},
 			isIPv6:          false,
 			expectedPIPName: "azure-auid-prefix-id",
 		},
@@ -2375,7 +2378,7 @@ func TestGetPublicIPName(t *testing.T) {
 					IPFamilies: []v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol},
 				},
 			},
-			pips:            &[]network.PublicIPAddress{},
+			pips:            []network.PublicIPAddress{},
 			isIPv6:          true,
 			expectedPIPName: "azure-auid-prefix-id-ipv6-IPv6",
 		},
@@ -2389,7 +2392,7 @@ func TestGetPublicIPName(t *testing.T) {
 					IPFamilies: []v1.IPFamily{v1.IPv6Protocol},
 				},
 			},
-			pips: &[]network.PublicIPAddress{
+			pips: []network.PublicIPAddress{
 				{
 					Name: pointer.String("auid"),
 					PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
@@ -2404,11 +2407,15 @@ func TestGetPublicIPName(t *testing.T) {
 
 	ctrl := gomock.NewController(t)
 	defer ctrl.Finish()
-	az := GetTestCloud(ctrl)
 	rg := "rg0"
 	for _, tc := range testcases {
 		t.Run(tc.desc, func(t *testing.T) {
-			name, err := az.getPublicIPName("azure", tc.svc, rg, tc.pips, tc.isIPv6)
+			az := GetTestCloud(ctrl)
+			if tc.isIPv6 {
+				mockPIPsClient := az.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
+				mockPIPsClient.EXPECT().List(gomock.Any(), rg).Return(tc.pips, nil)
+			}
+			name, err := az.getPublicIPName("azure", tc.svc, rg, tc.isIPv6)
 			assert.Nil(t, err)
 			assert.Equal(t, tc.expectedPIPName, name)
 		})
diff --git a/pkg/provider/azure_test.go b/pkg/provider/azure_test.go
index 0aefa13e1..849ceeed4 100644
--- a/pkg/provider/azure_test.go
+++ b/pkg/provider/azure_test.go
@@ -1273,7 +1273,7 @@ func TestReconcileSecurityGroupNewServiceAddsPort(t *testing.T) {
 	mockLBBackendPool.EXPECT().ReconcileBackendPools(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, false, nil).AnyTimes()
 	mockLBBackendPool.EXPECT().EnsureHostsInPool(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
 	lb, _ := az.reconcileLoadBalancer(testClusterName, &svc1, clusterResources.nodes, true)
-	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc1, lb, nil)
+	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc1, lb)
 
 	sg, err := az.reconcileSecurityGroup(testClusterName, &svc1, &lbStatus.Ingress[0].IP, nil, true /* wantLb */)
 	if err != nil {
@@ -1302,7 +1302,7 @@ func TestReconcileSecurityGroupNewInternalServiceAddsPort(t *testing.T) {
 	mockLBBackendPool.EXPECT().EnsureHostsInPool(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
 
 	lb, _ := az.reconcileLoadBalancer(testClusterName, &svc1, clusterResources.nodes, true)
-	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc1, lb, nil)
+	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc1, lb)
 	sg, err := az.reconcileSecurityGroup(testClusterName, &svc1, &lbStatus.Ingress[0].IP, nil, true /* wantLb */)
 	if err != nil {
 		t.Errorf("Unexpected error: %q", err)
@@ -1339,7 +1339,7 @@ func TestReconcileSecurityGroupRemoveService(t *testing.T) {
 	lb, _ := az.reconcileLoadBalancer(testClusterName, &service1, clusterResources.nodes, true)
 	_, _ = az.reconcileLoadBalancer(testClusterName, &service2, clusterResources.nodes, true)
 
-	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&service1, lb, nil)
+	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&service1, lb)
 
 	sg := getTestSecurityGroup(az, service1, service2)
 	validateSecurityGroup(t, sg, service1, service2)
@@ -1378,7 +1378,7 @@ func TestReconcileSecurityGroupRemoveServiceRemovesPort(t *testing.T) {
 			svc,
 			"Standard"), nil).AnyTimes()
 	lb, _ := az.reconcileLoadBalancer(testClusterName, &svc, clusterResources.nodes, true)
-	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc, lb, nil)
+	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc, lb)
 
 	sg, err := az.reconcileSecurityGroup(testClusterName, &svcUpdated, &lbStatus.Ingress[0].IP, nil, true /* wantLb */)
 	if err != nil {
@@ -1409,7 +1409,7 @@ func TestReconcileSecurityWithSourceRanges(t *testing.T) {
 	expectedLBs := make([]network.LoadBalancer, 0)
 	setMockLBs(az, ctrl, &expectedLBs, "service", 1, 1, false)
 	lb, _ := az.reconcileLoadBalancer(testClusterName, &svc, clusterResources.nodes, true)
-	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc, lb, nil)
+	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc, lb)
 
 	sg, err := az.reconcileSecurityGroup(testClusterName, &svc, &lbStatus.Ingress[0].IP, nil, true /* wantLb */)
 	if err != nil {
@@ -1457,7 +1457,7 @@ func TestReconcileSecurityGroupEtagMismatch(t *testing.T) {
 	mockLBBackendPool.EXPECT().EnsureHostsInPool(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
 
 	lb, _ := az.reconcileLoadBalancer(testClusterName, &svc1, clusterResources.nodes, true)
-	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc1, lb, nil)
+	lbStatus, _, _ := az.getServiceLoadBalancerStatus(&svc1, lb)
 
 	newSG, err := az.reconcileSecurityGroup(testClusterName, &svc1, &lbStatus.Ingress[0].IP, nil, true /* wantLb */)
 	assert.Nil(t, newSG)
diff --git a/pkg/provider/azure_utils_test.go b/pkg/provider/azure_utils_test.go
index 4515552ac..008d60b12 100644
--- a/pkg/provider/azure_utils_test.go
+++ b/pkg/provider/azure_utils_test.go
@@ -30,6 +30,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/utils/pointer"
 
+	"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient"
 	azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
 	"sigs.k8s.io/cloud-provider-azure/pkg/consts"
 )
@@ -885,7 +886,7 @@ func TestIsFIPIPv6(t *testing.T) {
 	testcases := []struct {
 		desc           string
 		fip            *network.FrontendIPConfiguration
-		pips           *[]network.PublicIPAddress
+		pips           []network.PublicIPAddress
 		isInternal     bool
 		expectedIsIPv6 bool
 	}{
@@ -897,7 +898,7 @@ func TestIsFIPIPv6(t *testing.T) {
 					PrivateIPAddress:        pointer.String("10.0.0.1"),
 				},
 			},
-			&[]network.PublicIPAddress{},
+			[]network.PublicIPAddress{},
 			true,
 			false,
 		},
@@ -908,16 +909,18 @@ func TestIsFIPIPv6(t *testing.T) {
 					PublicIPAddress: &network.PublicIPAddress{ID: pointer.String("pip-id0")},
 				},
 			},
-			&[]network.PublicIPAddress{
+			[]network.PublicIPAddress{
 				{
-					ID: pointer.String("pip-id0"),
+					Name: pointer.String("pip0"),
+					ID:   pointer.String("pip-id0"),
 					PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
 						PublicIPAddressVersion: network.IPv6,
 						IPAddress:              pointer.String("2001::1"),
 					},
 				},
 				{
-					ID: pointer.String("pip-id1"),
+					Name: pointer.String("pip1"),
+					ID:   pointer.String("pip-id1"),
 					PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
 						PublicIPAddressVersion: network.IPv4,
 						IPAddress:              pointer.String("10.0.0.1"),
@@ -931,7 +934,9 @@ func TestIsFIPIPv6(t *testing.T) {
 	for _, tc := range testcases {
 		t.Run(tc.desc, func(t *testing.T) {
 			az := GetTestCloud(ctrl)
-			isIPv6, err := az.isFIPIPv6(tc.fip, tc.pips, tc.isInternal)
+			mockPIPsClient := az.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
+			mockPIPsClient.EXPECT().List(gomock.Any(), "rg").Return(tc.pips, nil)
+			isIPv6, err := az.isFIPIPv6(tc.fip, "rg", tc.isInternal)
 			assert.Nil(t, err)
 			assert.Equal(t, tc.expectedIsIPv6, isIPv6)
 		})