Switch from fake storage to mock clients in azure unit tests.

This commit is contained in:
t-qini 2020-04-12 16:23:46 +08:00
parent cc75cd5aba
commit 68600b843f
25 changed files with 1512 additions and 1198 deletions

View File

@ -64,22 +64,31 @@ go_library(
"//staging/src/k8s.io/legacy-cloud-providers/azure/cache:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/diskclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/diskclient/mockdiskclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/fileclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/interfaceclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/interfaceclient/mockinterfaceclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient/mockloadbalancerclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/publicipclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/publicipclient/mockpublicipclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/routeclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/routeclient/mockrouteclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/routetableclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/routetableclient/mockroutetableclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/securitygroupclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/securitygroupclient/mocksecuritygroupclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/snapshotclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/storageaccountclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/subnetclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/subnetclient/mocksubnetclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmsizeclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/retry:go_default_library",
"//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute:go_default_library",
"//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network:go_default_library",
@ -130,8 +139,18 @@ go_test(
"//staging/src/k8s.io/legacy-cloud-providers/azure/auth:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/cache:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/diskclient/mockdiskclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/fileclient/mockfileclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/interfaceclient/mockinterfaceclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient/mockloadbalancerclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/publicipclient/mockpublicipclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/routetableclient/mockroutetableclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/securitygroupclient/mocksecuritygroupclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/storageaccountclient/mockstorageaccountclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/subnetclient/mocksubnetclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/mockvmsets:go_default_library",
"//staging/src/k8s.io/legacy-cloud-providers/azure/retry:go_default_library",
"//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute:go_default_library",

View File

@ -47,6 +47,7 @@ import (
azcache "k8s.io/legacy-cloud-providers/azure/cache"
azclients "k8s.io/legacy-cloud-providers/azure/clients"
"k8s.io/legacy-cloud-providers/azure/clients/diskclient"
"k8s.io/legacy-cloud-providers/azure/clients/fileclient"
"k8s.io/legacy-cloud-providers/azure/clients/interfaceclient"
"k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient"
"k8s.io/legacy-cloud-providers/azure/clients/publicipclient"
@ -61,6 +62,7 @@ import (
"k8s.io/legacy-cloud-providers/azure/clients/vmssclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient"
"k8s.io/legacy-cloud-providers/azure/retry"
"sigs.k8s.io/yaml"
)
@ -234,7 +236,7 @@ type Cloud struct {
StorageAccountClient storageaccountclient.Interface
DisksClient diskclient.Interface
SnapshotsClient snapshotclient.Interface
FileClient FileClient
FileClient fileclient.Interface
VirtualMachineScaleSetsClient vmssclient.Interface
VirtualMachineScaleSetVMsClient vmssvmclient.Interface
VirtualMachineSizesClient vmsizeclient.Interface
@ -590,7 +592,7 @@ func (az *Cloud) configAzureClients(
az.SecurityGroupsClient = securitygroupclient.New(securityGroupClientConfig)
az.PublicIPAddressesClient = publicipclient.New(publicIPClientConfig)
// fileClient is not based on armclient, but it's still backoff retried.
az.FileClient = newAzureFileClient(&az.Environment, azClientConfig.Backoff)
az.FileClient = fileclient.NewAzureFileClient(&az.Environment, azClientConfig.Backoff)
}
func (az *Cloud) getAzureClientConfig(servicePrincipalToken *adal.ServicePrincipalToken) *azclients.ClientConfig {

View File

@ -20,14 +20,20 @@ package azure
import (
"fmt"
"net/http"
"reflect"
"testing"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
"github.com/Azure/go-autorest/autorest/to"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/types"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/legacy-cloud-providers/azure/clients/diskclient/mockdiskclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient"
"k8s.io/legacy-cloud-providers/azure/retry"
"k8s.io/utils/pointer"
)
@ -40,12 +46,14 @@ func TestCommonAttachDisk(t *testing.T) {
vmList map[string]string
nodeName types.NodeName
isDataDisksFull bool
existedDisk compute.Disk
expectedLun int32
expectedErr bool
}{
{
desc: "LUN -1 and error shall be returned if there's no such instance corresponding to given nodeName",
nodeName: "vm1",
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
expectedLun: -1,
expectedErr: true,
},
@ -54,6 +62,7 @@ func TestCommonAttachDisk(t *testing.T) {
vmList: map[string]string{"vm1": "PowerState/Running"},
nodeName: "vm1",
isDataDisksFull: true,
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
expectedLun: -1,
expectedErr: true,
},
@ -61,6 +70,15 @@ func TestCommonAttachDisk(t *testing.T) {
desc: "correct LUN and no error shall be returned if everything is good",
vmList: map[string]string{"vm1": "PowerState/Running"},
nodeName: "vm1",
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
expectedLun: 1,
expectedErr: false,
},
{
desc: "an error shall be returned if there's no matching disk",
vmList: map[string]string{"vm1": "PowerState/Running"},
nodeName: "vm1",
existedDisk: compute.Disk{Name: to.StringPtr("disk-name-1")},
expectedLun: -1,
expectedErr: true,
},
@ -76,9 +94,21 @@ func TestCommonAttachDisk(t *testing.T) {
cloud: testCloud,
vmLockMap: newLockMap(),
}
diskURI := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/disk-name",
testCloud.SubscriptionID, testCloud.ResourceGroup)
setTestVirtualMachines(testCloud, test.vmList, test.isDataDisksFull)
diskURI := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s",
testCloud.SubscriptionID, testCloud.ResourceGroup, *test.existedDisk.Name)
expectedVMs := setTestVirtualMachines(testCloud, test.vmList, test.isDataDisksFull)
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
if len(expectedVMs) == 0 {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
}
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
mockDisksClient := testCloud.DisksClient.(*mockdiskclient.MockInterface)
mockDisksClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, "disk-name").Return(test.existedDisk, nil).AnyTimes()
mockDisksClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Not("disk-name")).Return(compute.Disk{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
lun, err := common.AttachDisk(true, "", diskURI, test.nodeName, compute.CachingTypesReadOnly)
assert.Equal(t, test.expectedLun, lun, "TestCase[%d]: %s", i, test.desc)
@ -130,7 +160,15 @@ func TestCommonDetachDisk(t *testing.T) {
}
diskURI := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/disk-name",
testCloud.SubscriptionID, testCloud.ResourceGroup)
setTestVirtualMachines(testCloud, test.vmList, false)
expectedVMs := setTestVirtualMachines(testCloud, test.vmList, false)
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
if len(expectedVMs) == 0 {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
}
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
err := common.DetachDisk(test.diskName, diskURI, test.nodeName)
assert.Equal(t, test.expectedErr, err != nil, "TestCase[%d]: %s, err: %v", i, test.desc, err)
@ -172,7 +210,11 @@ func TestGetDiskLun(t *testing.T) {
cloud: testCloud,
vmLockMap: newLockMap(),
}
setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
expectedVMs := setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
lun, err := common.GetDiskLun(test.diskName, test.diskURI, "vm1")
assert.Equal(t, test.expectedLun, lun, "TestCase[%d]: %s", i, test.desc)
@ -214,7 +256,11 @@ func TestGetNextDiskLun(t *testing.T) {
cloud: testCloud,
vmLockMap: newLockMap(),
}
setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, test.isDataDisksFull)
expectedVMs := setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, test.isDataDisksFull)
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
lun, err := common.GetNextDiskLun("vm1")
assert.Equal(t, test.expectedLun, lun, "TestCase[%d]: %s", i, test.desc)
@ -259,7 +305,12 @@ func TestDisksAreAttached(t *testing.T) {
cloud: testCloud,
vmLockMap: newLockMap(),
}
setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
expectedVMs := setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, "vm2", gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
attached, err := common.DisksAreAttached(test.diskNames, test.nodeName)
assert.Equal(t, test.expectedAttached, attached, "TestCase[%d]: %s", i, test.desc)
@ -267,7 +318,7 @@ func TestDisksAreAttached(t *testing.T) {
}
}
func TestFilteredDetatchingDisks(t *testing.T) {
func TestFilteredDetachingDisks(t *testing.T) {
disks := []compute.DataDisk{
{
@ -448,10 +499,10 @@ func TestCheckDiskExists(t *testing.T) {
newDiskName := "newdisk"
newDiskURI := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s",
testCloud.SubscriptionID, testCloud.ResourceGroup, newDiskName)
fDC := newFakeDisksClient()
rerr := fDC.CreateOrUpdate(ctx, testCloud.ResourceGroup, newDiskName, compute.Disk{})
assert.Equal(t, rerr == nil, true, "return error: %v", rerr)
testCloud.DisksClient = fDC
mockDisksClient := testCloud.DisksClient.(*mockdiskclient.MockInterface)
mockDisksClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, newDiskName).Return(compute.Disk{}, nil).AnyTimes()
mockDisksClient.EXPECT().Get(gomock.Any(), gomock.Not(testCloud.ResourceGroup), gomock.Any()).Return(compute.Disk{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
testCases := []struct {
diskURI string
@ -503,10 +554,10 @@ func TestFilterNonExistingDisks(t *testing.T) {
testCloud.SubscriptionID, testCloud.ResourceGroup)
newDiskName := "newdisk"
newDiskURI := diskURIPrefix + newDiskName
fDC := newFakeDisksClient()
rerr := fDC.CreateOrUpdate(ctx, testCloud.ResourceGroup, newDiskName, compute.Disk{})
assert.Equal(t, rerr == nil, true, "return error: %v", rerr)
testCloud.DisksClient = fDC
mockDisksClient := testCloud.DisksClient.(*mockdiskclient.MockInterface)
mockDisksClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, newDiskName).Return(compute.Disk{}, nil).AnyTimes()
mockDisksClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Not(newDiskName)).Return(compute.Disk{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
disks := []compute.DataDisk{
{

View File

@ -19,6 +19,7 @@ limitations under the License.
package azure
import (
"net/http"
"testing"
"time"
@ -28,7 +29,10 @@ import (
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/types"
cloudprovider "k8s.io/cloud-provider"
azcache "k8s.io/legacy-cloud-providers/azure/cache"
"k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient"
"k8s.io/legacy-cloud-providers/azure/retry"
)
var (
@ -59,7 +63,13 @@ func TestStandardAttachDisk(t *testing.T) {
for i, test := range testCases {
testCloud := GetTestCloud(ctrl)
vmSet := testCloud.vmSet
setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
expectedVMs := setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, "vm2", gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
err := vmSet.AttachDisk(true, "",
"uri", test.nodeName, 0, compute.CachingTypesReadOnly, "", false)
@ -99,7 +109,13 @@ func TestStandardDetachDisk(t *testing.T) {
for i, test := range testCases {
testCloud := GetTestCloud(ctrl)
vmSet := testCloud.vmSet
setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
expectedVMs := setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, "vm2", gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
err := vmSet.DetachDisk(test.diskName, "", test.nodeName)
assert.Equal(t, test.expectedError, err != nil, "TestCase[%d]: %s", i, test.desc)
@ -152,7 +168,13 @@ func TestGetDataDisks(t *testing.T) {
for i, test := range testCases {
testCloud := GetTestCloud(ctrl)
vmSet := testCloud.vmSet
setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
expectedVMs := setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false)
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Not("vm1"), gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
dataDisks, err := vmSet.GetDataDisks(test.nodeName, test.crt)
assert.Equal(t, test.expectedDataDisks, dataDisks, "TestCase[%d]: %s", i, test.desc)

View File

@ -19,757 +19,30 @@ limitations under the License.
package azure
import (
"context"
"errors"
"fmt"
"math/rand"
"net/http"
"sync"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network"
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-06-01/storage"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/to"
"github.com/golang/mock/gomock"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/record"
"k8s.io/legacy-cloud-providers/azure/auth"
"k8s.io/legacy-cloud-providers/azure/clients/diskclient/mockdiskclient"
"k8s.io/legacy-cloud-providers/azure/clients/interfaceclient/mockinterfaceclient"
"k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient/mockloadbalancerclient"
"k8s.io/legacy-cloud-providers/azure/clients/publicipclient/mockpublicipclient"
"k8s.io/legacy-cloud-providers/azure/clients/routeclient/mockrouteclient"
"k8s.io/legacy-cloud-providers/azure/clients/routetableclient/mockroutetableclient"
"k8s.io/legacy-cloud-providers/azure/clients/securitygroupclient/mocksecuritygroupclient"
"k8s.io/legacy-cloud-providers/azure/clients/subnetclient/mocksubnetclient"
"k8s.io/legacy-cloud-providers/azure/retry"
"k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient"
)
var (
errPreconditionFailedEtagMismatch = fmt.Errorf("PreconditionFailedEtagMismatch")
)
type fakeAzureLBClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]network.LoadBalancer
}
func newFakeAzureLBClient() *fakeAzureLBClient {
fLBC := &fakeAzureLBClient{}
fLBC.FakeStore = make(map[string]map[string]network.LoadBalancer)
fLBC.mutex = &sync.Mutex{}
return fLBC
}
func (fLBC *fakeAzureLBClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, loadBalancerName string, parameters network.LoadBalancer, etag string) *retry.Error {
fLBC.mutex.Lock()
defer fLBC.mutex.Unlock()
if _, ok := fLBC.FakeStore[resourceGroupName]; !ok {
fLBC.FakeStore[resourceGroupName] = make(map[string]network.LoadBalancer)
}
// For dynamic ip allocation, just fill in the PrivateIPAddress
if parameters.FrontendIPConfigurations != nil {
for idx, config := range *parameters.FrontendIPConfigurations {
if config.PrivateIPAllocationMethod == network.Dynamic {
// Here we randomly assign an ip as private ip
// It doesn't smart enough to know whether it is in the subnet's range
(*parameters.FrontendIPConfigurations)[idx].PrivateIPAddress = getRandomIPPtr()
}
}
}
fLBC.FakeStore[resourceGroupName][loadBalancerName] = parameters
return nil
}
func (fLBC *fakeAzureLBClient) Delete(ctx context.Context, resourceGroupName string, loadBalancerName string) *retry.Error {
fLBC.mutex.Lock()
defer fLBC.mutex.Unlock()
if rgLBs, ok := fLBC.FakeStore[resourceGroupName]; ok {
if _, ok := rgLBs[loadBalancerName]; ok {
delete(rgLBs, loadBalancerName)
return nil
}
}
return nil
}
func (fLBC *fakeAzureLBClient) Get(ctx context.Context, resourceGroupName string, loadBalancerName string, expand string) (result network.LoadBalancer, err *retry.Error) {
fLBC.mutex.Lock()
defer fLBC.mutex.Unlock()
if _, ok := fLBC.FakeStore[resourceGroupName]; ok {
if entity, ok := fLBC.FakeStore[resourceGroupName][loadBalancerName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such LB"))
}
func (fLBC *fakeAzureLBClient) List(ctx context.Context, resourceGroupName string) (result []network.LoadBalancer, err *retry.Error) {
fLBC.mutex.Lock()
defer fLBC.mutex.Unlock()
var value []network.LoadBalancer
if _, ok := fLBC.FakeStore[resourceGroupName]; ok {
for _, v := range fLBC.FakeStore[resourceGroupName] {
value = append(value, v)
}
}
return value, nil
}
type fakeAzurePIPClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]network.PublicIPAddress
SubscriptionID string
}
const publicIPAddressIDTemplate = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/publicIPAddresses/%s"
// returns the full identifier of a publicIPAddress.
func getpublicIPAddressID(subscriptionID string, resourceGroupName, pipName string) string {
return fmt.Sprintf(
publicIPAddressIDTemplate,
subscriptionID,
resourceGroupName,
pipName)
}
func newFakeAzurePIPClient(subscriptionID string) *fakeAzurePIPClient {
fAPC := &fakeAzurePIPClient{}
fAPC.FakeStore = make(map[string]map[string]network.PublicIPAddress)
fAPC.SubscriptionID = subscriptionID
fAPC.mutex = &sync.Mutex{}
return fAPC
}
func (fAPC *fakeAzurePIPClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, publicIPAddressName string, parameters network.PublicIPAddress) *retry.Error {
fAPC.mutex.Lock()
defer fAPC.mutex.Unlock()
if _, ok := fAPC.FakeStore[resourceGroupName]; !ok {
fAPC.FakeStore[resourceGroupName] = make(map[string]network.PublicIPAddress)
}
// assign id
pipID := getpublicIPAddressID(fAPC.SubscriptionID, resourceGroupName, publicIPAddressName)
parameters.ID = &pipID
// only create in the case user has not provided
if parameters.PublicIPAddressPropertiesFormat != nil &&
parameters.PublicIPAddressPropertiesFormat.PublicIPAllocationMethod == network.Static {
// assign ip
parameters.IPAddress = getRandomIPPtr()
}
fAPC.FakeStore[resourceGroupName][publicIPAddressName] = parameters
return nil
}
func (fAPC *fakeAzurePIPClient) Delete(ctx context.Context, resourceGroupName string, publicIPAddressName string) *retry.Error {
fAPC.mutex.Lock()
defer fAPC.mutex.Unlock()
if rgPIPs, ok := fAPC.FakeStore[resourceGroupName]; ok {
if _, ok := rgPIPs[publicIPAddressName]; ok {
delete(rgPIPs, publicIPAddressName)
return nil
}
}
return retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such PIP"))
}
func (fAPC *fakeAzurePIPClient) Get(ctx context.Context, resourceGroupName string, publicIPAddressName string, expand string) (result network.PublicIPAddress, err *retry.Error) {
fAPC.mutex.Lock()
defer fAPC.mutex.Unlock()
if _, ok := fAPC.FakeStore[resourceGroupName]; ok {
if entity, ok := fAPC.FakeStore[resourceGroupName][publicIPAddressName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such PIP"))
}
func (fAPC *fakeAzurePIPClient) GetVirtualMachineScaleSetPublicIPAddress(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, IPConfigurationName string, publicIPAddressName string, expand string) (result network.PublicIPAddress, err *retry.Error) {
fAPC.mutex.Lock()
defer fAPC.mutex.Unlock()
if _, ok := fAPC.FakeStore[resourceGroupName]; ok {
if entity, ok := fAPC.FakeStore[resourceGroupName][publicIPAddressName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such PIP"))
}
func (fAPC *fakeAzurePIPClient) List(ctx context.Context, resourceGroupName string) (result []network.PublicIPAddress, err *retry.Error) {
fAPC.mutex.Lock()
defer fAPC.mutex.Unlock()
var value []network.PublicIPAddress
if _, ok := fAPC.FakeStore[resourceGroupName]; ok {
for _, v := range fAPC.FakeStore[resourceGroupName] {
value = append(value, v)
}
}
return value, nil
}
func (fAPC *fakeAzurePIPClient) setFakeStore(store map[string]map[string]network.PublicIPAddress) {
fAPC.mutex.Lock()
defer fAPC.mutex.Unlock()
fAPC.FakeStore = store
}
type fakeAzureInterfacesClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]network.Interface
}
func newFakeAzureInterfacesClient() *fakeAzureInterfacesClient {
fIC := &fakeAzureInterfacesClient{}
fIC.FakeStore = make(map[string]map[string]network.Interface)
fIC.mutex = &sync.Mutex{}
return fIC
}
func (fIC *fakeAzureInterfacesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, networkInterfaceName string, parameters network.Interface) *retry.Error {
fIC.mutex.Lock()
defer fIC.mutex.Unlock()
if _, ok := fIC.FakeStore[resourceGroupName]; !ok {
fIC.FakeStore[resourceGroupName] = make(map[string]network.Interface)
}
fIC.FakeStore[resourceGroupName][networkInterfaceName] = parameters
return nil
}
func (fIC *fakeAzureInterfacesClient) Get(ctx context.Context, resourceGroupName string, networkInterfaceName string, expand string) (result network.Interface, err *retry.Error) {
fIC.mutex.Lock()
defer fIC.mutex.Unlock()
if _, ok := fIC.FakeStore[resourceGroupName]; ok {
if entity, ok := fIC.FakeStore[resourceGroupName][networkInterfaceName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such Interface"))
}
func (fIC *fakeAzureInterfacesClient) GetVirtualMachineScaleSetNetworkInterface(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, expand string) (result network.Interface, err *retry.Error) {
fIC.mutex.Lock()
defer fIC.mutex.Unlock()
if _, ok := fIC.FakeStore[resourceGroupName]; ok {
if entity, ok := fIC.FakeStore[resourceGroupName][networkInterfaceName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such Interface"))
}
func (fIC *fakeAzureInterfacesClient) Delete(ctx context.Context, resourceGroupName string, networkInterfaceName string) *retry.Error {
return nil
}
func (fIC *fakeAzureInterfacesClient) setFakeStore(store map[string]map[string]network.Interface) {
fIC.mutex.Lock()
defer fIC.mutex.Unlock()
fIC.FakeStore = store
}
type fakeAzureVirtualMachinesClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]compute.VirtualMachine
}
func newFakeAzureVirtualMachinesClient() *fakeAzureVirtualMachinesClient {
fVMC := &fakeAzureVirtualMachinesClient{}
fVMC.FakeStore = make(map[string]map[string]compute.VirtualMachine)
fVMC.mutex = &sync.Mutex{}
return fVMC
}
func (fVMC *fakeAzureVirtualMachinesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, VMName string, parameters compute.VirtualMachine, source string) *retry.Error {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
if _, ok := fVMC.FakeStore[resourceGroupName]; !ok {
fVMC.FakeStore[resourceGroupName] = make(map[string]compute.VirtualMachine)
}
fVMC.FakeStore[resourceGroupName][VMName] = parameters
return nil
}
func (fVMC *fakeAzureVirtualMachinesClient) Update(ctx context.Context, resourceGroupName string, VMName string, parameters compute.VirtualMachineUpdate, source string) *retry.Error {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
if _, ok := fVMC.FakeStore[resourceGroupName]; !ok {
fVMC.FakeStore[resourceGroupName] = make(map[string]compute.VirtualMachine)
}
return nil
}
func (fVMC *fakeAzureVirtualMachinesClient) Get(ctx context.Context, resourceGroupName string, VMName string, expand compute.InstanceViewTypes) (result compute.VirtualMachine, err *retry.Error) {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
if _, ok := fVMC.FakeStore[resourceGroupName]; ok {
if entity, ok := fVMC.FakeStore[resourceGroupName][VMName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such VM"))
}
func (fVMC *fakeAzureVirtualMachinesClient) List(ctx context.Context, resourceGroupName string) (result []compute.VirtualMachine, err *retry.Error) {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
result = []compute.VirtualMachine{}
if _, ok := fVMC.FakeStore[resourceGroupName]; ok {
for _, v := range fVMC.FakeStore[resourceGroupName] {
result = append(result, v)
}
}
return result, nil
}
func (fVMC *fakeAzureVirtualMachinesClient) Delete(ctx context.Context, resourceGroupName string, VMName string) *retry.Error {
return nil
}
func (fVMC *fakeAzureVirtualMachinesClient) setFakeStore(store map[string]map[string]compute.VirtualMachine) {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
fVMC.FakeStore = store
}
type fakeAzureNSGClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]network.SecurityGroup
}
func newFakeAzureNSGClient() *fakeAzureNSGClient {
fNSG := &fakeAzureNSGClient{}
fNSG.FakeStore = make(map[string]map[string]network.SecurityGroup)
fNSG.mutex = &sync.Mutex{}
return fNSG
}
func (fNSG *fakeAzureNSGClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, parameters network.SecurityGroup, etag string) *retry.Error {
fNSG.mutex.Lock()
defer fNSG.mutex.Unlock()
if _, ok := fNSG.FakeStore[resourceGroupName]; !ok {
fNSG.FakeStore[resourceGroupName] = make(map[string]network.SecurityGroup)
}
if nsg, ok := fNSG.FakeStore[resourceGroupName][networkSecurityGroupName]; ok {
if etag != "" && to.String(nsg.Etag) != "" && etag != to.String(nsg.Etag) {
return retry.GetError(&http.Response{
StatusCode: http.StatusPreconditionFailed,
}, errPreconditionFailedEtagMismatch)
}
}
fNSG.FakeStore[resourceGroupName][networkSecurityGroupName] = parameters
return nil
}
func (fNSG *fakeAzureNSGClient) Delete(ctx context.Context, resourceGroupName string, networkSecurityGroupName string) *retry.Error {
fNSG.mutex.Lock()
defer fNSG.mutex.Unlock()
if rgSGs, ok := fNSG.FakeStore[resourceGroupName]; ok {
if _, ok := rgSGs[networkSecurityGroupName]; ok {
delete(rgSGs, networkSecurityGroupName)
return nil
}
}
return retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such NSG"))
}
func (fNSG *fakeAzureNSGClient) Get(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, expand string) (result network.SecurityGroup, err *retry.Error) {
fNSG.mutex.Lock()
defer fNSG.mutex.Unlock()
if _, ok := fNSG.FakeStore[resourceGroupName]; ok {
if entity, ok := fNSG.FakeStore[resourceGroupName][networkSecurityGroupName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such NSG"))
}
func (fNSG *fakeAzureNSGClient) List(ctx context.Context, resourceGroupName string) (result []network.SecurityGroup, err *retry.Error) {
fNSG.mutex.Lock()
defer fNSG.mutex.Unlock()
var value []network.SecurityGroup
if _, ok := fNSG.FakeStore[resourceGroupName]; ok {
for _, v := range fNSG.FakeStore[resourceGroupName] {
value = append(value, v)
}
}
return value, nil
}
func getRandomIPPtr() *string {
return to.StringPtr(fmt.Sprintf("%d.%d.%d.%d", rand.Intn(256), rand.Intn(256), rand.Intn(256), rand.Intn(256)))
}
type fakeVirtualMachineScaleSetVMsClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]compute.VirtualMachineScaleSetVM
}
func newFakeVirtualMachineScaleSetVMsClient() *fakeVirtualMachineScaleSetVMsClient {
fVMC := &fakeVirtualMachineScaleSetVMsClient{}
fVMC.FakeStore = make(map[string]map[string]compute.VirtualMachineScaleSetVM)
fVMC.mutex = &sync.Mutex{}
return fVMC
}
func (fVMC *fakeVirtualMachineScaleSetVMsClient) setFakeStore(store map[string]map[string]compute.VirtualMachineScaleSetVM) {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
fVMC.FakeStore = store
}
func (fVMC *fakeVirtualMachineScaleSetVMsClient) List(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, expand string) (result []compute.VirtualMachineScaleSetVM, err *retry.Error) {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
result = []compute.VirtualMachineScaleSetVM{}
if _, ok := fVMC.FakeStore[resourceGroupName]; ok {
for _, v := range fVMC.FakeStore[resourceGroupName] {
result = append(result, v)
}
}
return result, nil
}
func (fVMC *fakeVirtualMachineScaleSetVMsClient) Get(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string, expand compute.InstanceViewTypes) (result compute.VirtualMachineScaleSetVM, err *retry.Error) {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
vmKey := fmt.Sprintf("%s_%s", VMScaleSetName, instanceID)
if scaleSetMap, ok := fVMC.FakeStore[resourceGroupName]; ok {
if entity, ok := scaleSetMap[vmKey]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such VirtualMachineScaleSetVM"))
}
func (fVMC *fakeVirtualMachineScaleSetVMsClient) Update(ctx context.Context, resourceGroupName string, VMScaleSetName string, instanceID string, parameters compute.VirtualMachineScaleSetVM, source string) *retry.Error {
fVMC.mutex.Lock()
defer fVMC.mutex.Unlock()
vmKey := fmt.Sprintf("%s_%s", VMScaleSetName, instanceID)
if scaleSetMap, ok := fVMC.FakeStore[resourceGroupName]; ok {
if _, ok := scaleSetMap[vmKey]; ok {
scaleSetMap[vmKey] = parameters
}
}
return nil
}
func (fVMC *fakeVirtualMachineScaleSetVMsClient) UpdateVMs(ctx context.Context, resourceGroupName string, VMScaleSetName string, instances map[string]compute.VirtualMachineScaleSetVM, source string) *retry.Error {
return nil
}
type fakeVirtualMachineScaleSetsClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]compute.VirtualMachineScaleSet
}
func newFakeVirtualMachineScaleSetsClient() *fakeVirtualMachineScaleSetsClient {
fVMSSC := &fakeVirtualMachineScaleSetsClient{}
fVMSSC.FakeStore = make(map[string]map[string]compute.VirtualMachineScaleSet)
fVMSSC.mutex = &sync.Mutex{}
return fVMSSC
}
func (fVMSSC *fakeVirtualMachineScaleSetsClient) setFakeStore(store map[string]map[string]compute.VirtualMachineScaleSet) {
fVMSSC.mutex.Lock()
defer fVMSSC.mutex.Unlock()
fVMSSC.FakeStore = store
}
func (fVMSSC *fakeVirtualMachineScaleSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, VMScaleSetName string, parameters compute.VirtualMachineScaleSet) *retry.Error {
fVMSSC.mutex.Lock()
defer fVMSSC.mutex.Unlock()
if _, ok := fVMSSC.FakeStore[resourceGroupName]; !ok {
fVMSSC.FakeStore[resourceGroupName] = make(map[string]compute.VirtualMachineScaleSet)
}
fVMSSC.FakeStore[resourceGroupName][VMScaleSetName] = parameters
return nil
}
func (fVMSSC *fakeVirtualMachineScaleSetsClient) CreateOrUpdateAsync(ctx context.Context, resourceGroupName string, VMScaleSetName string, parameters compute.VirtualMachineScaleSet) (*azure.Future, *retry.Error) {
return nil, nil
}
func (fVMSSC *fakeVirtualMachineScaleSetsClient) WaitForAsyncOperationResult(ctx context.Context, future *azure.Future) (*http.Response, error) {
return nil, nil
}
func (fVMSSC *fakeVirtualMachineScaleSetsClient) Get(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result compute.VirtualMachineScaleSet, err *retry.Error) {
fVMSSC.mutex.Lock()
defer fVMSSC.mutex.Unlock()
if scaleSetMap, ok := fVMSSC.FakeStore[resourceGroupName]; ok {
if entity, ok := scaleSetMap[VMScaleSetName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such ScaleSet"))
}
func (fVMSSC *fakeVirtualMachineScaleSetsClient) List(ctx context.Context, resourceGroupName string) (result []compute.VirtualMachineScaleSet, err *retry.Error) {
fVMSSC.mutex.Lock()
defer fVMSSC.mutex.Unlock()
result = []compute.VirtualMachineScaleSet{}
if _, ok := fVMSSC.FakeStore[resourceGroupName]; ok {
for _, v := range fVMSSC.FakeStore[resourceGroupName] {
result = append(result, v)
}
}
return result, nil
}
func (fVMSSC *fakeVirtualMachineScaleSetsClient) UpdateInstances(ctx context.Context, resourceGroupName string, VMScaleSetName string, VMInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) *retry.Error {
return nil
}
func (fVMSSC *fakeVirtualMachineScaleSetsClient) DeleteInstances(ctx context.Context, resourceGroupName string, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) *retry.Error {
return nil
}
type fakeFileClient struct {
}
func (fFC *fakeFileClient) createFileShare(accountName, accountKey, name string, sizeGiB int) error {
return nil
}
func (fFC *fakeFileClient) deleteFileShare(accountName, accountKey, name string) error {
return nil
}
func (fFC *fakeFileClient) resizeFileShare(accountName, accountKey, name string, sizeGiB int) error {
return nil
}
type fakeStorageAccountClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]storage.Account
Keys storage.AccountListKeysResult
Accounts []storage.Account
Err error
}
func newFakeStorageAccountClient() *fakeStorageAccountClient {
fSAC := &fakeStorageAccountClient{}
fSAC.FakeStore = make(map[string]map[string]storage.Account)
fSAC.mutex = &sync.Mutex{}
return fSAC
}
func (fSAC *fakeStorageAccountClient) Create(ctx context.Context, resourceGroupName string, accountName string, parameters storage.AccountCreateParameters) *retry.Error {
fSAC.mutex.Lock()
defer fSAC.mutex.Unlock()
if _, ok := fSAC.FakeStore[resourceGroupName]; !ok {
fSAC.FakeStore[resourceGroupName] = make(map[string]storage.Account)
}
fSAC.FakeStore[resourceGroupName][accountName] = storage.Account{
Name: &accountName,
Sku: parameters.Sku,
Kind: parameters.Kind,
Location: parameters.Location,
Identity: parameters.Identity,
Tags: parameters.Tags,
AccountProperties: &storage.AccountProperties{},
}
return nil
}
func (fSAC *fakeStorageAccountClient) Delete(ctx context.Context, resourceGroupName string, accountName string) *retry.Error {
fSAC.mutex.Lock()
defer fSAC.mutex.Unlock()
if rgAccounts, ok := fSAC.FakeStore[resourceGroupName]; ok {
if _, ok := rgAccounts[accountName]; ok {
delete(rgAccounts, accountName)
return nil
}
}
return retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such StorageAccount"))
}
func (fSAC *fakeStorageAccountClient) ListKeys(ctx context.Context, resourceGroupName string, accountName string) (result storage.AccountListKeysResult, err *retry.Error) {
return fSAC.Keys, nil
}
func (fSAC *fakeStorageAccountClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result []storage.Account, err *retry.Error) {
return fSAC.Accounts, nil
}
func (fSAC *fakeStorageAccountClient) GetProperties(ctx context.Context, resourceGroupName string, accountName string) (result storage.Account, err *retry.Error) {
fSAC.mutex.Lock()
defer fSAC.mutex.Unlock()
if _, ok := fSAC.FakeStore[resourceGroupName]; ok {
if entity, ok := fSAC.FakeStore[resourceGroupName][accountName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such StorageAccount"))
}
type fakeDisksClient struct {
mutex *sync.Mutex
FakeStore map[string]map[string]compute.Disk
}
func newFakeDisksClient() *fakeDisksClient {
fDC := &fakeDisksClient{}
fDC.FakeStore = make(map[string]map[string]compute.Disk)
fDC.mutex = &sync.Mutex{}
return fDC
}
func (fDC *fakeDisksClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, diskName string, diskParameter compute.Disk) *retry.Error {
fDC.mutex.Lock()
defer fDC.mutex.Unlock()
provisioningStateSucceeded := string(compute.ProvisioningStateSucceeded)
diskParameter.DiskProperties = &compute.DiskProperties{ProvisioningState: &provisioningStateSucceeded}
diskParameter.ID = &diskName
if _, ok := fDC.FakeStore[resourceGroupName]; !ok {
fDC.FakeStore[resourceGroupName] = make(map[string]compute.Disk)
}
fDC.FakeStore[resourceGroupName][diskName] = diskParameter
return nil
}
func (fDC *fakeDisksClient) Delete(ctx context.Context, resourceGroupName string, diskName string) *retry.Error {
fDC.mutex.Lock()
defer fDC.mutex.Unlock()
if rgDisks, ok := fDC.FakeStore[resourceGroupName]; ok {
if _, ok := rgDisks[diskName]; ok {
delete(rgDisks, diskName)
return nil
}
}
return retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such Disk"))
}
func (fDC *fakeDisksClient) Get(ctx context.Context, resourceGroupName string, diskName string) (result compute.Disk, err *retry.Error) {
fDC.mutex.Lock()
defer fDC.mutex.Unlock()
if _, ok := fDC.FakeStore[resourceGroupName]; ok {
if entity, ok := fDC.FakeStore[resourceGroupName][diskName]; ok {
return entity, nil
}
}
return result, retry.GetError(
&http.Response{
StatusCode: http.StatusNotFound,
},
errors.New("Not such Disk"))
}
// GetTestCloud returns a fake azure cloud for unit tests in Azure related CSI drivers
func GetTestCloud(ctrl *gomock.Controller) (az *Cloud) {
az = &Cloud{
@ -798,17 +71,17 @@ func GetTestCloud(ctrl *gomock.Controller) (az *Cloud) {
routeCIDRs: map[string]string{},
eventRecorder: &record.FakeRecorder{},
}
az.DisksClient = newFakeDisksClient()
az.InterfacesClient = newFakeAzureInterfacesClient()
az.LoadBalancerClient = newFakeAzureLBClient()
az.PublicIPAddressesClient = newFakeAzurePIPClient(az.Config.SubscriptionID)
az.DisksClient = mockdiskclient.NewMockInterface(ctrl)
az.InterfacesClient = mockinterfaceclient.NewMockInterface(ctrl)
az.LoadBalancerClient = mockloadbalancerclient.NewMockInterface(ctrl)
az.PublicIPAddressesClient = mockpublicipclient.NewMockInterface(ctrl)
az.RoutesClient = mockrouteclient.NewMockInterface(ctrl)
az.RouteTablesClient = mockroutetableclient.NewMockInterface(ctrl)
az.SecurityGroupsClient = newFakeAzureNSGClient()
az.SecurityGroupsClient = mocksecuritygroupclient.NewMockInterface(ctrl)
az.SubnetsClient = mocksubnetclient.NewMockInterface(ctrl)
az.VirtualMachineScaleSetsClient = newFakeVirtualMachineScaleSetsClient()
az.VirtualMachineScaleSetVMsClient = newFakeVirtualMachineScaleSetVMsClient()
az.VirtualMachinesClient = newFakeAzureVirtualMachinesClient()
az.VirtualMachineScaleSetsClient = mockvmssclient.NewMockInterface(ctrl)
az.VirtualMachineScaleSetVMsClient = mockvmssvmclient.NewMockInterface(ctrl)
az.VirtualMachinesClient = mockvmclient.NewMockInterface(ctrl)
az.vmSet = newAvailabilitySet(az)
az.vmCache, _ = az.newVMCache()
az.lbCache, _ = az.newLBCache()

View File

@ -18,124 +18,15 @@ limitations under the License.
package azure
import (
"fmt"
"net/http"
azs "github.com/Azure/azure-sdk-for-go/storage"
"github.com/Azure/go-autorest/autorest/azure"
"k8s.io/klog"
"k8s.io/legacy-cloud-providers/azure/retry"
)
const (
useHTTPS = true
)
var (
// refer https://github.com/Azure/azure-sdk-for-go/blob/master/storage/client.go#L88.
defaultValidStatusCodes = []int{
http.StatusRequestTimeout, // 408
http.StatusInternalServerError, // 500
http.StatusBadGateway, // 502
http.StatusServiceUnavailable, // 503
http.StatusGatewayTimeout, // 504
}
)
// FileClient is the interface for creating file shares, interface for test
// injection.
type FileClient interface {
createFileShare(accountName, accountKey, name string, sizeGiB int) error
deleteFileShare(accountName, accountKey, name string) error
resizeFileShare(accountName, accountKey, name string, sizeGiB int) error
}
// create file share
func (az *Cloud) createFileShare(accountName, accountKey, name string, sizeGiB int) error {
return az.FileClient.createFileShare(accountName, accountKey, name, sizeGiB)
return az.FileClient.CreateFileShare(accountName, accountKey, name, sizeGiB)
}
func (az *Cloud) deleteFileShare(accountName, accountKey, name string) error {
return az.FileClient.deleteFileShare(accountName, accountKey, name)
return az.FileClient.DeleteFileShare(accountName, accountKey, name)
}
func (az *Cloud) resizeFileShare(accountName, accountKey, name string, sizeGiB int) error {
return az.FileClient.resizeFileShare(accountName, accountKey, name, sizeGiB)
}
type azureFileClient struct {
env *azure.Environment
backoff *retry.Backoff
}
func newAzureFileClient(env *azure.Environment, backoff *retry.Backoff) *azureFileClient {
return &azureFileClient{
env: env,
backoff: backoff,
}
}
func (f *azureFileClient) createFileShare(accountName, accountKey, name string, sizeGiB int) error {
fileClient, err := f.getFileSvcClient(accountName, accountKey)
if err != nil {
return err
}
share := fileClient.GetShareReference(name)
share.Properties.Quota = sizeGiB
newlyCreated, err := share.CreateIfNotExists(nil)
if err != nil {
return fmt.Errorf("failed to create file share, err: %v", err)
}
if !newlyCreated {
klog.V(2).Infof("file share(%s) under account(%s) already exists", name, accountName)
}
return nil
}
// delete a file share
func (f *azureFileClient) deleteFileShare(accountName, accountKey, name string) error {
fileClient, err := f.getFileSvcClient(accountName, accountKey)
if err != nil {
return err
}
return fileClient.GetShareReference(name).Delete(nil)
}
func (f *azureFileClient) resizeFileShare(accountName, accountKey, name string, sizeGiB int) error {
fileClient, err := f.getFileSvcClient(accountName, accountKey)
if err != nil {
return err
}
share := fileClient.GetShareReference(name)
if share.Properties.Quota >= sizeGiB {
klog.Warningf("file share size(%dGi) is already greater or equal than requested size(%dGi), accountName: %s, shareName: %s",
share.Properties.Quota, sizeGiB, accountName, name)
return nil
}
share.Properties.Quota = sizeGiB
if err = share.SetProperties(nil); err != nil {
return fmt.Errorf("failed to set quota on file share %s, err: %v", name, err)
}
klog.V(4).Infof("resize file share completed, accountName: %s, shareName: %s, sizeGiB: %d", accountName, name, sizeGiB)
return nil
}
func (f *azureFileClient) getFileSvcClient(accountName, accountKey string) (*azs.FileServiceClient, error) {
fileClient, err := azs.NewClient(accountName, accountKey, f.env.StorageEndpointSuffix, azs.DefaultAPIVersion, useHTTPS)
if err != nil {
return nil, fmt.Errorf("error creating azure client: %v", err)
}
if f.backoff != nil {
fileClient.Sender = &azs.DefaultSender{
RetryAttempts: f.backoff.Steps,
ValidStatusCodes: defaultValidStatusCodes,
RetryDuration: f.backoff.Duration,
}
}
fc := fileClient.GetFileService()
return &fc, nil
return az.FileClient.ResizeFileShare(accountName, accountKey, name, sizeGiB)
}

View File

@ -32,14 +32,14 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient"
"k8s.io/legacy-cloud-providers/azure/retry"
)
// setTestVirtualMachines sets test virtual machine with powerstate.
func setTestVirtualMachines(c *Cloud, vmList map[string]string, isDataDisksFull bool) {
virtualMachineClient := c.VirtualMachinesClient.(*fakeAzureVirtualMachinesClient)
store := map[string]map[string]compute.VirtualMachine{
"rg": make(map[string]compute.VirtualMachine),
}
func setTestVirtualMachines(c *Cloud, vmList map[string]string, isDataDisksFull bool) []compute.VirtualMachine {
expectedVMs := make([]compute.VirtualMachine, 0)
for nodeName, powerState := range vmList {
instanceID := fmt.Sprintf("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/%s", nodeName)
@ -76,10 +76,11 @@ func setTestVirtualMachines(c *Cloud, vmList map[string]string, isDataDisksFull
}
vm.StorageProfile.DataDisks = &dataDisks
}
store["rg"][nodeName] = vm
expectedVMs = append(expectedVMs, vm)
}
virtualMachineClient.setFakeStore(store)
return expectedVMs
}
func TestInstanceID(t *testing.T) {
@ -142,7 +143,14 @@ func TestInstanceID(t *testing.T) {
for _, vm := range test.vmList {
vmListWithPowerState[vm] = ""
}
setTestVirtualMachines(cloud, vmListWithPowerState, false)
expectedVMs := setTestVirtualMachines(cloud, vmListWithPowerState, false)
mockVMsClient := cloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), cloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
mockVMsClient.EXPECT().Get(gomock.Any(), cloud.ResourceGroup, "vm3", gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
mockVMsClient.EXPECT().Update(gomock.Any(), cloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
instanceID, err := cloud.InstanceID(context.Background(), types.NodeName(test.nodeName))
if test.expectError {
if err == nil {
@ -222,7 +230,13 @@ func TestInstanceShutdownByProviderID(t *testing.T) {
defer ctrl.Finish()
for _, test := range testcases {
cloud := GetTestCloud(ctrl)
setTestVirtualMachines(cloud, test.vmList, false)
expectedVMs := setTestVirtualMachines(cloud, test.vmList, false)
mockVMsClient := cloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
for _, vm := range expectedVMs {
mockVMsClient.EXPECT().Get(gomock.Any(), cloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
}
mockVMsClient.EXPECT().Get(gomock.Any(), cloud.ResourceGroup, "vm8", gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
providerID := "azure://" + cloud.getStandardMachineID("subscription", "rg", test.nodeName)
hasShutdown, err := cloud.InstanceShutdownByProviderID(context.Background(), providerID)
if test.expectError {

View File

@ -21,6 +21,7 @@ package azure
import (
"context"
"fmt"
"net/http"
"reflect"
"strconv"
"strings"
@ -34,7 +35,11 @@ import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient/mockloadbalancerclient"
"k8s.io/legacy-cloud-providers/azure/clients/publicipclient/mockpublicipclient"
"k8s.io/legacy-cloud-providers/azure/clients/securitygroupclient/mocksecuritygroupclient"
"k8s.io/legacy-cloud-providers/azure/clients/subnetclient/mocksubnetclient"
"k8s.io/legacy-cloud-providers/azure/retry"
)
func TestFindProbe(t *testing.T) {
@ -359,23 +364,25 @@ func TestEnsureLoadBalancerDeleted(t *testing.T) {
tests := []struct {
desc string
service v1.Service
isInternalSvc bool
expectCreateError bool
}{
{
desc: "external service should be created and deleted successfully",
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
service: getTestService("service1", v1.ProtocolTCP, nil, false, 80),
},
{
desc: "internal service should be created and deleted successfully",
service: getInternalTestService("test2", 80),
desc: "internal service should be created and deleted successfully",
service: getInternalTestService("service2", 80),
isInternalSvc: true,
},
{
desc: "annotated service with same resourceGroup should be created and deleted successfully",
service: getResourceGroupTestService("test3", "rg", "", 80),
service: getResourceGroupTestService("service3", "rg", "", 80),
},
{
desc: "annotated service with different resourceGroup shouldn't be created but should be deleted successfully",
service: getResourceGroupTestService("test4", "random-rg", "1.2.3.4", 80),
service: getResourceGroupTestService("service4", "random-rg", "1.2.3.4", 80),
expectCreateError: true,
},
}
@ -383,13 +390,19 @@ func TestEnsureLoadBalancerDeleted(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
az := GetTestCloud(ctrl)
clusterResources, expectedInterfaces, expectedVirtualMachines := getClusterResources(az, vmCount, availabilitySetCount)
setMockEnv(az, ctrl, expectedInterfaces, expectedVirtualMachines, 4)
for i, c := range tests {
clusterResources := getClusterResources(az, vmCount, availabilitySetCount)
getTestSecurityGroup(az)
if c.service.Annotations[ServiceAnnotationLoadBalancerInternal] == "true" {
validateTestSubnet(t, az, &c.service)
}
expectedLBs := make([]network.LoadBalancer, 0)
setMockLBs(az, ctrl, &expectedLBs, "service", 1, i+1, c.isInternalSvc)
// create the service first.
lbStatus, err := az.EnsureLoadBalancer(context.TODO(), testClusterName, &c.service, clusterResources.nodes)
if c.expectCreateError {
@ -403,12 +416,18 @@ func TestEnsureLoadBalancerDeleted(t *testing.T) {
assert.Equal(t, len(*result[0].LoadBalancingRules), 1, "TestCase[%d]: %s", i, c.desc)
}
expectedLBs = make([]network.LoadBalancer, 0)
setMockLBs(az, ctrl, &expectedLBs, "service", 1, i+1, c.isInternalSvc)
// finally, delete it.
err = az.EnsureLoadBalancerDeleted(context.TODO(), testClusterName, &c.service)
expectedLBs = make([]network.LoadBalancer, 0)
mockLBsClient := mockloadbalancerclient.NewMockInterface(ctrl)
mockLBsClient.EXPECT().List(gomock.Any(), az.Config.ResourceGroup).Return(expectedLBs, nil)
az.LoadBalancerClient = mockLBsClient
assert.Nil(t, err, "TestCase[%d]: %s", i, c.desc)
result, rerr := az.LoadBalancerClient.List(context.Background(), az.Config.ResourceGroup)
assert.Nil(t, rerr, "TestCase[%d]: %s", i, c.desc)
assert.Equal(t, len(result), 0, "TestCase[%d]: %s", i, c.desc)
assert.Equal(t, 0, len(result), "TestCase[%d]: %s", i, c.desc)
}
}
@ -596,44 +615,44 @@ func TestGetServiceLoadBalancer(t *testing.T) {
expectedError bool
}{
{
desc: "getServiceLoadBalancer shall return corresponding lb, status, exists if there are exsisted lbs",
desc: "getServiceLoadBalancer shall return corresponding lb, status, exists if there are existed lbs",
existingLBs: []network.LoadBalancer{
{
Name: to.StringPtr("lb1"),
LoadBalancerPropertiesFormat: &network.LoadBalancerPropertiesFormat{
FrontendIPConfigurations: &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
},
},
},
},
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
service: getTestService("service1", v1.ProtocolTCP, nil, false, 80),
wantLB: false,
expectedLB: &network.LoadBalancer{
Name: to.StringPtr("lb1"),
LoadBalancerPropertiesFormat: &network.LoadBalancerPropertiesFormat{
FrontendIPConfigurations: &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
},
},
},
expectedStatus: &v1.LoadBalancerStatus{Ingress: []v1.LoadBalancerIngress{{IP: "", Hostname: ""}}},
expectedStatus: &v1.LoadBalancerStatus{Ingress: []v1.LoadBalancerIngress{{IP: "1.2.3.4", Hostname: ""}}},
expectedExists: true,
expectedError: false,
},
{
desc: "getServiceLoadBalancer shall report error if there're loadbalancer mode annotations on a standard lb",
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
service: getTestService("service1", v1.ProtocolTCP, nil, false, 80),
annotations: map[string]string{ServiceAnnotationLoadBalancerMode: "__auto__"},
sku: "standard",
expectedExists: false,
@ -671,7 +690,7 @@ func TestGetServiceLoadBalancer(t *testing.T) {
},
},
},
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
service: getTestService("service1", v1.ProtocolTCP, nil, false, 80),
annotations: map[string]string{ServiceAnnotationLoadBalancerMode: "__auto__"},
wantLB: true,
expectedLB: &network.LoadBalancer{
@ -687,7 +706,7 @@ func TestGetServiceLoadBalancer(t *testing.T) {
},
{
desc: "getServiceLoadBalancer shall create a new lb otherwise",
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
service: getTestService("service1", v1.ProtocolTCP, nil, false, 80),
expectedLB: &network.LoadBalancer{
Name: to.StringPtr("testCluster"),
Location: to.StringPtr("westus"),
@ -702,7 +721,13 @@ func TestGetServiceLoadBalancer(t *testing.T) {
defer ctrl.Finish()
for i, test := range testCases {
az := GetTestCloud(ctrl)
clusterResources := getClusterResources(az, 3, 3)
clusterResources, expectedInterfaces, expectedVirtualMachines := getClusterResources(az, 3, 3)
setMockEnv(az, ctrl, expectedInterfaces, expectedVirtualMachines, 1)
mockLBsClient := mockloadbalancerclient.NewMockInterface(ctrl)
mockLBsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
mockLBsClient.EXPECT().List(gomock.Any(), "rg").Return(test.existingLBs, nil)
az.LoadBalancerClient = mockLBsClient
for _, existingLB := range test.existingLBs {
err := az.LoadBalancerClient.CreateOrUpdate(context.TODO(), "rg", *existingLB.Name, existingLB, "")
@ -732,8 +757,8 @@ func TestIsFrontendIPChanged(t *testing.T) {
lbFrontendIPConfigName string
annotations string
loadBalancerIP string
exsistingSubnet network.Subnet
exsistingPIPs []network.PublicIPAddress
existingSubnet network.Subnet
existingPIPs []network.PublicIPAddress
expectedFlag bool
expectedError bool
}{
@ -794,7 +819,7 @@ func TestIsFrontendIPChanged(t *testing.T) {
lbFrontendIPConfigName: "btest1-name",
service: getInternalTestService("test1", 80),
annotations: "testSubnet",
exsistingSubnet: network.Subnet{Name: to.StringPtr("testSubnet1")},
existingSubnet: network.Subnet{Name: to.StringPtr("testSubnet1")},
expectedFlag: true,
expectedError: false,
},
@ -854,7 +879,7 @@ func TestIsFrontendIPChanged(t *testing.T) {
lbFrontendIPConfigName: "btest1-name",
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
loadBalancerIP: "1.1.1.1",
exsistingPIPs: []network.PublicIPAddress{
existingPIPs: []network.PublicIPAddress{
{
Name: to.StringPtr("pipName"),
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
@ -877,12 +902,14 @@ func TestIsFrontendIPChanged(t *testing.T) {
lbFrontendIPConfigName: "btest1-name",
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
loadBalancerIP: "1.1.1.1",
exsistingPIPs: []network.PublicIPAddress{
existingPIPs: []network.PublicIPAddress{
{
Name: to.StringPtr("pipName"),
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
IPAddress: to.StringPtr("1.1.1.1"),
},
ID: to.StringPtr("/subscriptions/subscription" +
"/resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pipName"),
},
},
expectedFlag: false,
@ -900,7 +927,7 @@ func TestIsFrontendIPChanged(t *testing.T) {
lbFrontendIPConfigName: "btest1-name",
service: getTestService("test1", v1.ProtocolTCP, nil, false, 80),
loadBalancerIP: "1.1.1.1",
exsistingPIPs: []network.PublicIPAddress{
existingPIPs: []network.PublicIPAddress{
{
Name: to.StringPtr("pipName"),
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
@ -916,14 +943,19 @@ func TestIsFrontendIPChanged(t *testing.T) {
for i, test := range testCases {
az := GetTestCloud(ctrl)
mockSubnetsClient := az.SubnetsClient.(*mocksubnetclient.MockInterface)
mockSubnetsClient.EXPECT().Get(gomock.Any(), "rg", "vnet", "testSubnet", "").Return(test.exsistingSubnet, nil).AnyTimes()
mockSubnetsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", "vnet", "testSubnet", test.exsistingSubnet).Return(nil)
err := az.SubnetsClient.CreateOrUpdate(context.TODO(), "rg", "vnet", "testSubnet", test.exsistingSubnet)
mockSubnetsClient.EXPECT().Get(gomock.Any(), "rg", "vnet", "testSubnet", "").Return(test.existingSubnet, nil).AnyTimes()
mockSubnetsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", "vnet", "testSubnet", test.existingSubnet).Return(nil)
err := az.SubnetsClient.CreateOrUpdate(context.TODO(), "rg", "vnet", "testSubnet", test.existingSubnet)
if err != nil {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
}
for _, existingPIP := range test.exsistingPIPs {
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", "pipName", existingPIP)
mockPIPsClient := az.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
mockPIPsClient.EXPECT().List(gomock.Any(), "rg").Return(test.existingPIPs, nil).AnyTimes()
mockPIPsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
for _, existingPIP := range test.existingPIPs {
mockPIPsClient.EXPECT().Get(gomock.Any(), "rg", *existingPIP.Name, gomock.Any()).Return(existingPIP, nil).AnyTimes()
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", *existingPIP.Name, existingPIP)
if err != nil {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
}
@ -944,7 +976,7 @@ func TestDeterminePublicIPName(t *testing.T) {
testCases := []struct {
desc string
loadBalancerIP string
exsistingPIPs []network.PublicIPAddress
existingPIPs []network.PublicIPAddress
expectedIP string
expectedError bool
}{
@ -964,7 +996,7 @@ func TestDeterminePublicIPName(t *testing.T) {
desc: "determinePublicIpName shall return loadBalancerIP in service.Spec if it's in the " +
"resource group",
loadBalancerIP: "1.2.3.4",
exsistingPIPs: []network.PublicIPAddress{
existingPIPs: []network.PublicIPAddress{
{
Name: to.StringPtr("pipName"),
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
@ -980,8 +1012,13 @@ func TestDeterminePublicIPName(t *testing.T) {
az := GetTestCloud(ctrl)
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
service.Spec.LoadBalancerIP = test.loadBalancerIP
for _, existingPIP := range test.exsistingPIPs {
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", "test", existingPIP)
mockPIPsClient := az.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
mockPIPsClient.EXPECT().List(gomock.Any(), "rg").Return(test.existingPIPs, nil).AnyTimes()
mockPIPsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
for _, existingPIP := range test.existingPIPs {
mockPIPsClient.EXPECT().Get(gomock.Any(), "rg", *existingPIP.Name, gomock.Any()).Return(existingPIP, nil).AnyTimes()
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", *existingPIP.Name, existingPIP)
if err != nil {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
}
@ -1163,7 +1200,7 @@ func getTestLoadBalancer(name, rgName, clusterName, identifier *string, service
{
Name: identifier,
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
},
@ -1188,7 +1225,7 @@ func getTestLoadBalancer(name, rgName, clusterName, identifier *string, service
strings.ToLower(string(service.Spec.Ports[0].Protocol)))),
FrontendIPConfiguration: &network.SubResource{
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/" + *rgName + "/providers/" +
"Microsoft.Network/loadBalancers/" + *name + "/frontendIPConfigurations/atest1"),
"Microsoft.Network/loadBalancers/" + *name + "/frontendIPConfigurations/aservice1"),
},
BackendAddressPool: &network.SubResource{
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/" + *rgName + "/providers/" +
@ -1200,7 +1237,7 @@ func getTestLoadBalancer(name, rgName, clusterName, identifier *string, service
EnableFloatingIP: to.BoolPtr(true),
EnableTCPReset: to.BoolPtr(strings.EqualFold(lbSku, "standard")),
Probe: &network.SubResource{
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/" + *rgName + "/providers/Microsoft.Network/loadBalancers/testCluster/probes/atest1-TCP-80"),
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/" + *rgName + "/providers/Microsoft.Network/loadBalancers/testCluster/probes/aservice1-TCP-80"),
},
},
},
@ -1214,98 +1251,97 @@ func TestReconcileLoadBalancer(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
service1 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
basicLb1 := getTestLoadBalancer(to.StringPtr("lb1"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service1, "Basic")
service1 := getTestService("service1", v1.ProtocolTCP, nil, false, 80)
basicLb1 := getTestLoadBalancer(to.StringPtr("lb1"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service1, "Basic")
service2 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
basicLb2 := getTestLoadBalancer(to.StringPtr("lb1"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("btest1"), service2, "Basic")
basicLb2 := getTestLoadBalancer(to.StringPtr("lb1"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("bservice1"), service2, "Basic")
basicLb2.Name = to.StringPtr("testCluster")
basicLb2.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("btest1"),
Name: to.StringPtr("bservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-bservice1")},
},
},
}
service3 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
modifiedLb1 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service3, "Basic")
service3 := getTestService("service1", v1.ProtocolTCP, nil, false, 80)
modifiedLb1 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service3, "Basic")
modifiedLb1.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
{
Name: to.StringPtr("btest1"),
Name: to.StringPtr("bservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-bservice1")},
},
},
}
modifiedLb1.Probes = &[]network.Probe{
{
Name: to.StringPtr("atest1-" + string(service3.Spec.Ports[0].Protocol) +
Name: to.StringPtr("aservice1-" + string(service3.Spec.Ports[0].Protocol) +
"-" + strconv.Itoa(int(service3.Spec.Ports[0].Port))),
ProbePropertiesFormat: &network.ProbePropertiesFormat{
Port: to.Int32Ptr(10080),
},
},
{
Name: to.StringPtr("atest1-" + string(service3.Spec.Ports[0].Protocol) +
Name: to.StringPtr("aservice1-" + string(service3.Spec.Ports[0].Protocol) +
"-" + strconv.Itoa(int(service3.Spec.Ports[0].Port))),
ProbePropertiesFormat: &network.ProbePropertiesFormat{
Port: to.Int32Ptr(10081),
},
},
}
expectedLb1 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service3, "Basic")
expectedLb1 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service3, "Basic")
(*expectedLb1.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].DisableOutboundSnat = to.BoolPtr(false)
(*expectedLb1.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].EnableTCPReset = nil
expectedLb1.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("btest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("bservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("/subscriptions/subscription/" +
"resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pipName")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-bservice1")},
},
},
}
service4 := getTestService("test1", v1.ProtocolTCP, map[string]string{"service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset": "true"}, false, 80)
existingSLB := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service4, "Standard")
service4 := getTestService("service1", v1.ProtocolTCP, map[string]string{"service.beta.kubernetes.io/azure-load-balancer-disable-tcp-reset": "true"}, false, 80)
existingSLB := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service4, "Standard")
existingSLB.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
{
Name: to.StringPtr("btest1"),
Name: to.StringPtr("bservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-bservice1")},
},
},
}
existingSLB.Probes = &[]network.Probe{
{
Name: to.StringPtr("atest1-" + string(service4.Spec.Ports[0].Protocol) +
Name: to.StringPtr("aservice1-" + string(service4.Spec.Ports[0].Protocol) +
"-" + strconv.Itoa(int(service4.Spec.Ports[0].Port))),
ProbePropertiesFormat: &network.ProbePropertiesFormat{
Port: to.Int32Ptr(10080),
},
},
{
Name: to.StringPtr("atest1-" + string(service4.Spec.Ports[0].Protocol) +
Name: to.StringPtr("aservice1-" + string(service4.Spec.Ports[0].Protocol) +
"-" + strconv.Itoa(int(service4.Spec.Ports[0].Port))),
ProbePropertiesFormat: &network.ProbePropertiesFormat{
Port: to.Int32Ptr(10081),
@ -1313,51 +1349,50 @@ func TestReconcileLoadBalancer(t *testing.T) {
},
}
expectedSLb := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service4, "Standard")
expectedSLb := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service4, "Standard")
(*expectedSLb.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].DisableOutboundSnat = to.BoolPtr(true)
(*expectedSLb.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].EnableTCPReset = to.BoolPtr(false)
expectedSLb.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("btest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("bservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("/subscriptions/subscription/" +
"resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pipName")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-bservice1")},
},
},
}
service5 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
slb5 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service5, "Standard")
service5 := getTestService("service1", v1.ProtocolTCP, nil, false, 80)
slb5 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service5, "Standard")
slb5.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
{
Name: to.StringPtr("btest1"),
Name: to.StringPtr("bservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-bservice1")},
},
},
}
slb5.Probes = &[]network.Probe{
{
Name: to.StringPtr("atest1-" + string(service4.Spec.Ports[0].Protocol) +
Name: to.StringPtr("aservice1-" + string(service4.Spec.Ports[0].Protocol) +
"-" + strconv.Itoa(int(service4.Spec.Ports[0].Port))),
ProbePropertiesFormat: &network.ProbePropertiesFormat{
Port: to.Int32Ptr(10080),
},
},
{
Name: to.StringPtr("atest1-" + string(service4.Spec.Ports[0].Protocol) +
Name: to.StringPtr("aservice1-" + string(service4.Spec.Ports[0].Protocol) +
"-" + strconv.Itoa(int(service4.Spec.Ports[0].Port))),
ProbePropertiesFormat: &network.ProbePropertiesFormat{
Port: to.Int32Ptr(10081),
@ -1365,70 +1400,67 @@ func TestReconcileLoadBalancer(t *testing.T) {
},
}
//change to false to test that reconcilication will fix it
//change to false to test that reconciliation will fix it
(*slb5.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].EnableTCPReset = to.BoolPtr(false)
expectedSLb5 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service5, "Standard")
expectedSLb5 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service5, "Standard")
(*expectedSLb5.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].DisableOutboundSnat = to.BoolPtr(true)
expectedSLb5.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("btest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("bservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("/subscriptions/subscription/" +
"resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pipName")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-bservice1")},
},
},
}
service6 := getTestService("test1", v1.ProtocolUDP, nil, false, 80)
lb6 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service6, "basic")
service6 := getTestService("service1", v1.ProtocolUDP, nil, false, 80)
lb6 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service6, "basic")
lb6.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{}
lb6.Probes = &[]network.Probe{}
expectedLB6 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service6, "basic")
expectedLB6 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service6, "basic")
expectedLB6.Probes = &[]network.Probe{}
(*expectedLB6.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].Probe = nil
(*expectedLB6.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].EnableTCPReset = nil
(*expectedLB6.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].DisableOutboundSnat = to.BoolPtr(false)
expectedLB6.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("/subscriptions/subscription/" +
"resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pipName")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
}
service7 := getTestService("test1", v1.ProtocolUDP, nil, false, 80)
service7 := getTestService("service1", v1.ProtocolUDP, nil, false, 80)
service7.Spec.HealthCheckNodePort = 10081
service7.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeLocal
lb7 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service7, "basic")
lb7 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service7, "basic")
lb7.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{}
lb7.Probes = &[]network.Probe{}
expectedLB7 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service7, "basic")
expectedLB7 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("rg"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service7, "basic")
(*expectedLB7.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].Probe = &network.SubResource{
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Network/loadBalancers/testCluster/probes/atest1-UDP-80"),
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Network/loadBalancers/testCluster/probes/aservice1-UDP-80"),
}
(*expectedLB7.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].EnableTCPReset = nil
(*expectedLB7.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].DisableOutboundSnat = to.BoolPtr(false)
expectedLB7.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("/subscriptions/subscription/" +
"resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pipName")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
}
expectedLB7.Probes = &[]network.Probe{
{
Name: to.StringPtr("atest1-" + string(service7.Spec.Ports[0].Protocol) +
Name: to.StringPtr("aservice1-" + string(service7.Spec.Ports[0].Protocol) +
"-" + strconv.Itoa(int(service7.Spec.Ports[0].Port))),
ProbePropertiesFormat: &network.ProbePropertiesFormat{
Port: to.Int32Ptr(10081),
@ -1440,24 +1472,23 @@ func TestReconcileLoadBalancer(t *testing.T) {
},
}
service8 := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
lb8 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("anotherRG"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service8, "Standard")
service8 := getTestService("service1", v1.ProtocolTCP, nil, false, 80)
lb8 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("anotherRG"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service8, "Standard")
lb8.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{}
lb8.Probes = &[]network.Probe{}
expectedLB8 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("anotherRG"), to.StringPtr("testCluster"), to.StringPtr("atest1"), service8, "Standard")
expectedLB8 := getTestLoadBalancer(to.StringPtr("testCluster"), to.StringPtr("anotherRG"), to.StringPtr("testCluster"), to.StringPtr("aservice1"), service8, "Standard")
(*expectedLB8.LoadBalancerPropertiesFormat.LoadBalancingRules)[0].DisableOutboundSnat = to.BoolPtr(false)
expectedLB8.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("/subscriptions/subscription/" +
"resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pipName")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
}
expectedLB8.Probes = &[]network.Probe{
{
Name: to.StringPtr("atest1-" + string(service8.Spec.Ports[0].Protocol) +
Name: to.StringPtr("aservice1-" + string(service8.Spec.Ports[0].Protocol) +
"-" + strconv.Itoa(int(service7.Spec.Ports[0].Port))),
ProbePropertiesFormat: &network.ProbePropertiesFormat{
Port: to.Int32Ptr(10080),
@ -1501,7 +1532,7 @@ func TestReconcileLoadBalancer(t *testing.T) {
expectedError: nil,
},
{
desc: "reconcileLoadBalancer shall remove and reconstruct the correspoind field of lb",
desc: "reconcileLoadBalancer shall remove and reconstruct the correspond field of lb",
loadBalancerSku: "basic",
service: service3,
existingLB: modifiedLb1,
@ -1578,7 +1609,9 @@ func TestReconcileLoadBalancer(t *testing.T) {
}
az.LoadBalancerResourceGroup = test.loadBalancerResourceGroup
clusterResources := getClusterResources(az, 3, 3)
clusterResources, expectedInterfaces, expectedVirtualMachines := getClusterResources(az, 3, 3)
setMockEnv(az, ctrl, expectedInterfaces, expectedVirtualMachines, 1)
test.service.Spec.LoadBalancerIP = "1.2.3.4"
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", "pipName", network.PublicIPAddress{
@ -1591,6 +1624,12 @@ func TestReconcileLoadBalancer(t *testing.T) {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
}
mockLBsClient := mockloadbalancerclient.NewMockInterface(ctrl)
mockLBsClient.EXPECT().List(gomock.Any(), az.getLoadBalancerResourceGroup()).Return([]network.LoadBalancer{test.existingLB}, nil)
mockLBsClient.EXPECT().Get(gomock.Any(), az.getLoadBalancerResourceGroup(), *test.existingLB.Name, gomock.Any()).Return(test.existingLB, nil).AnyTimes()
mockLBsClient.EXPECT().CreateOrUpdate(gomock.Any(), az.getLoadBalancerResourceGroup(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
az.LoadBalancerClient = mockLBsClient
err = az.LoadBalancerClient.CreateOrUpdate(context.TODO(), az.getLoadBalancerResourceGroup(), "lb1", test.existingLB, "")
if err != nil {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
@ -1610,29 +1649,21 @@ func TestGetServiceLoadBalancerStatus(t *testing.T) {
defer ctrl.Finish()
az := GetTestCloud(ctrl)
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
internalService := getInternalTestService("test1", 80)
service := getTestService("service1", v1.ProtocolTCP, nil, false, 80)
internalService := getInternalTestService("service1", 80)
PIPClient := newFakeAzurePIPClient(az.Config.SubscriptionID)
PIPClient.setFakeStore(map[string]map[string]network.PublicIPAddress{
"rg": {"id1": network.PublicIPAddress{
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
IPAddress: to.StringPtr("1.2.3.4"),
},
}},
})
az.PublicIPAddressesClient = PIPClient
setMockPublicIPs(az, ctrl, 1)
lb1 := getTestLoadBalancer(to.StringPtr("lb1"), to.StringPtr("rg"), to.StringPtr("testCluster"),
to.StringPtr("test1"), internalService, "Basic")
to.StringPtr("aservice1"), internalService, "Basic")
lb1.FrontendIPConfigurations = nil
lb2 := getTestLoadBalancer(to.StringPtr("lb2"), to.StringPtr("rg"), to.StringPtr("testCluster"),
to.StringPtr("test1"), internalService, "Basic")
to.StringPtr("aservice1"), internalService, "Basic")
lb2.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
PrivateIPAddress: to.StringPtr("private"),
},
},
@ -1641,18 +1672,18 @@ func TestGetServiceLoadBalancerStatus(t *testing.T) {
to.StringPtr("test1"), internalService, "Basic")
lb3.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("btest1"),
Name: to.StringPtr("bservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-bservice1")},
PrivateIPAddress: to.StringPtr("private"),
},
},
}
lb4 := getTestLoadBalancer(to.StringPtr("lb4"), to.StringPtr("rg"), to.StringPtr("testCluster"),
to.StringPtr("test1"), service, "Basic")
to.StringPtr("aservice1"), service, "Basic")
lb4.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: nil},
PrivateIPAddress: to.StringPtr("private"),
@ -1660,10 +1691,10 @@ func TestGetServiceLoadBalancerStatus(t *testing.T) {
},
}
lb5 := getTestLoadBalancer(to.StringPtr("lb5"), to.StringPtr("rg"), to.StringPtr("testCluster"),
to.StringPtr("test1"), service, "Basic")
to.StringPtr("aservice1"), service, "Basic")
lb5.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: nil,
PrivateIPAddress: to.StringPtr("private"),
@ -1671,10 +1702,10 @@ func TestGetServiceLoadBalancerStatus(t *testing.T) {
},
}
lb6 := getTestLoadBalancer(to.StringPtr("lb6"), to.StringPtr("rg"), to.StringPtr("testCluster"),
to.StringPtr("test1"), service, "Basic")
to.StringPtr("aservice1"), service, "Basic")
lb6.FrontendIPConfigurations = &[]network.FrontendIPConfiguration{
{
Name: to.StringPtr("atest1"),
Name: to.StringPtr("aservice1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("illegal/id/")},
PrivateIPAddress: to.StringPtr("private"),
@ -1834,7 +1865,13 @@ func TestReconcileSecurityGroup(t *testing.T) {
for i, test := range testCases {
az := GetTestCloud(ctrl)
mockSGsClient := az.SecurityGroupsClient.(*mocksecuritygroupclient.MockInterface)
mockSGsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
if len(test.existingSgs) == 0 {
mockSGsClient.EXPECT().Get(gomock.Any(), "rg", gomock.Any(), gomock.Any()).Return(network.SecurityGroup{}, &retry.Error{HTTPStatusCode: http.StatusNotFound}).AnyTimes()
}
for name, sg := range test.existingSgs {
mockSGsClient.EXPECT().Get(gomock.Any(), "rg", name, gomock.Any()).Return(sg, nil).AnyTimes()
err := az.SecurityGroupsClient.CreateOrUpdate(context.TODO(), "rg", name, sg, "")
if err != nil {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
@ -1885,6 +1922,9 @@ func TestSafeDeletePublicIP(t *testing.T) {
for i, test := range testCases {
az := GetTestCloud(ctrl)
mockPIPsClient := az.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
mockPIPsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", "pip1", gomock.Any()).Return(nil).AnyTimes()
mockPIPsClient.EXPECT().Delete(gomock.Any(), "rg", "pip1").Return(nil).AnyTimes()
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", "pip1", network.PublicIPAddress{
Name: to.StringPtr("pip1"),
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
@ -1897,6 +1937,9 @@ func TestSafeDeletePublicIP(t *testing.T) {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
}
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
mockLBsClient := mockloadbalancerclient.NewMockInterface(ctrl)
mockLBsClient.EXPECT().CreateOrUpdate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
az.LoadBalancerClient = mockLBsClient
rerr := az.safeDeletePublicIP(&service, "rg", test.pip, test.lb)
assert.Equal(t, 0, len(*test.lb.FrontendIPConfigurations), "TestCase[%d]: %s", i, test.desc)
assert.Equal(t, 0, len(*test.lb.LoadBalancingRules), "TestCase[%d]: %s", i, test.desc)
@ -2007,9 +2050,18 @@ func TestReconcilePublicIP(t *testing.T) {
for i, test := range testCases {
az := GetTestCloud(ctrl)
mockPIPsClient := az.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
mockPIPsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
mockPIPsClient.EXPECT().List(gomock.Any(), "rg").Return(test.existingPIPs, nil).AnyTimes()
if i == 2 {
mockPIPsClient.EXPECT().Get(gomock.Any(), "rg", "testCluster-atest1", gomock.Any()).Return(network.PublicIPAddress{}, &retry.Error{HTTPStatusCode: http.StatusNotFound}).Times(1)
mockPIPsClient.EXPECT().Get(gomock.Any(), "rg", "testCluster-atest1", gomock.Any()).Return(network.PublicIPAddress{ID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/testCluster-atest1")}, nil).Times(1)
}
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
service.Annotations = test.annotations
for _, pip := range test.existingPIPs {
mockPIPsClient.EXPECT().Get(gomock.Any(), "rg", *pip.Name, gomock.Any()).Return(pip, nil).AnyTimes()
mockPIPsClient.EXPECT().Delete(gomock.Any(), "rg", *pip.Name).Return(nil).AnyTimes()
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", to.String(pip.Name), pip)
if err != nil {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
@ -2152,6 +2204,43 @@ func TestEnsurePublicIPExists(t *testing.T) {
for i, test := range testCases {
az := GetTestCloud(ctrl)
service := getTestService("test1", v1.ProtocolTCP, nil, test.isIPv6, 80)
mockPIPsClient := az.PublicIPAddressesClient.(*mockpublicipclient.MockInterface)
mockPIPsClient.EXPECT().CreateOrUpdate(gomock.Any(), "rg", gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
mockPIPsClient.EXPECT().Get(gomock.Any(), "rg", "pip1", gomock.Any()).DoAndReturn(func(ctx context.Context, resourceGroupName string, publicIPAddressName string, expand string) (network.PublicIPAddress, *retry.Error) {
var basicPIP network.PublicIPAddress
if len(test.existingPIPs) == 0 {
basicPIP = network.PublicIPAddress{
Name: to.StringPtr("pip1"),
}
} else {
basicPIP = test.existingPIPs[0]
}
basicPIP.ID = to.StringPtr("/subscriptions/subscription/resourceGroups/rg" +
"/providers/Microsoft.Network/publicIPAddresses/pip1")
if basicPIP.PublicIPAddressPropertiesFormat == nil {
return basicPIP, nil
}
if test.foundDNSLabelAnnotation {
if test.inputDNSLabel != "" {
basicPIP.DNSSettings.DomainNameLabel = &test.inputDNSLabel
} else {
basicPIP.DNSSettings = nil
}
}
if test.isIPv6 {
basicPIP.PublicIPAddressPropertiesFormat.PublicIPAddressVersion = "IPv6"
basicPIP.PublicIPAllocationMethod = "Dynamic"
} else {
basicPIP.PublicIPAddressPropertiesFormat.PublicIPAddressVersion = "IPv4"
}
return basicPIP, nil
}).AnyTimes()
for _, pip := range test.existingPIPs {
err := az.PublicIPAddressesClient.CreateOrUpdate(context.TODO(), "rg", to.String(pip.Name), pip)
if err != nil {
@ -2207,6 +2296,10 @@ func TestShouldUpdateLoadBalancer(t *testing.T) {
for i, test := range testCases {
az := GetTestCloud(ctrl)
service := getTestService("test1", v1.ProtocolTCP, nil, false, 80)
setMockPublicIPs(az, ctrl, 1)
mockLBsClient := mockloadbalancerclient.NewMockInterface(ctrl)
az.LoadBalancerClient = mockLBsClient
mockLBsClient.EXPECT().CreateOrUpdate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
if test.lbHasDeletionTimestamp {
service.ObjectMeta.DeletionTimestamp = &metav1.Time{Time: time.Now()}
}
@ -2218,7 +2311,7 @@ func TestShouldUpdateLoadBalancer(t *testing.T) {
{
Name: to.StringPtr("atest1"),
FrontendIPConfigurationPropertiesFormat: &network.FrontendIPConfigurationPropertiesFormat{
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("id1")},
PublicIPAddress: &network.PublicIPAddress{ID: to.StringPtr("testCluster-aservice1")},
},
},
},
@ -2228,6 +2321,9 @@ func TestShouldUpdateLoadBalancer(t *testing.T) {
if err != nil {
t.Fatalf("TestCase[%d] meets unexpected error: %v", i, err)
}
mockLBsClient.EXPECT().List(gomock.Any(), "rg").Return([]network.LoadBalancer{lb}, nil)
} else {
mockLBsClient.EXPECT().List(gomock.Any(), "rg").Return(nil, nil)
}
shouldUpdateLoadBalancer := az.shouldUpdateLoadBalancer(testClusterName, &service)
assert.Equal(t, test.expectedOutput, shouldUpdateLoadBalancer, "TestCase[%d]: %s", i, test.desc)

View File

@ -22,13 +22,20 @@ import (
"testing"
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-06-01/storage"
"github.com/golang/mock/gomock"
"k8s.io/legacy-cloud-providers/azure/clients/fileclient/mockfileclient"
"k8s.io/legacy-cloud-providers/azure/clients/storageaccountclient/mockstorageaccountclient"
)
func TestCreateFileShare(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cloud := &Cloud{}
fake := newFakeStorageAccountClient()
cloud.StorageAccountClient = fake
cloud.FileClient = &fakeFileClient{}
mockFileClient := mockfileclient.NewMockInterface(ctrl)
mockFileClient.EXPECT().CreateFileShare(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
cloud.FileClient = mockFileClient
name := "baz"
sku := "sku"
@ -115,9 +122,11 @@ func TestCreateFileShare(t *testing.T) {
}
for _, test := range tests {
fake.Accounts = test.accounts
fake.Keys = test.keys
fake.Err = test.err
mockStorageAccountsClient := mockstorageaccountclient.NewMockInterface(ctrl)
cloud.StorageAccountClient = mockStorageAccountsClient
mockStorageAccountsClient.EXPECT().ListKeys(gomock.Any(), "rg", gomock.Any()).Return(test.keys, nil).AnyTimes()
mockStorageAccountsClient.EXPECT().ListByResourceGroup(gomock.Any(), "rg").Return(test.accounts, nil).AnyTimes()
mockStorageAccountsClient.EXPECT().Create(gomock.Any(), "rg", gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
account, key, err := cloud.CreateFileShare(test.name, test.acct, test.acctType, test.acctKind, "rg", test.loc, test.gb)
if test.expectErr && err == nil {

View File

@ -22,13 +22,17 @@ import (
"fmt"
"testing"
"k8s.io/legacy-cloud-providers/azure/clients/storageaccountclient/mockstorageaccountclient"
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-06-01/storage"
"github.com/golang/mock/gomock"
)
func TestGetStorageAccessKeys(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cloud := &Cloud{}
fake := newFakeStorageAccountClient()
cloud.StorageAccountClient = fake
value := "foo bar"
tests := []struct {
@ -63,9 +67,9 @@ func TestGetStorageAccessKeys(t *testing.T) {
}
for _, test := range tests {
expectedKey := test.expectedKey
fake.Keys = test.results
fake.Err = test.err
mockStorageAccountsClient := mockstorageaccountclient.NewMockInterface(ctrl)
cloud.StorageAccountClient = mockStorageAccountsClient
mockStorageAccountsClient.EXPECT().ListKeys(gomock.Any(), "rg", gomock.Any()).Return(test.results, nil).AnyTimes()
key, err := cloud.GetStorageAccesskey("acct", "rg")
if test.expectErr && err == nil {
t.Errorf("Unexpected non-error")
@ -75,8 +79,8 @@ func TestGetStorageAccessKeys(t *testing.T) {
t.Errorf("Unexpected error: %v", err)
continue
}
if key != expectedKey {
t.Errorf("expected: %s, saw %s", expectedKey, key)
if key != test.expectedKey {
t.Errorf("expected: %s, saw %s", test.expectedKey, key)
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -413,11 +413,11 @@ func (ss *scaleSet) GetIPByNodeName(nodeName string) (string, string, error) {
if len(matches) == 7 {
resourceGroupName := matches[1]
virtualMachineScaleSetName := matches[2]
virtualmachineIndex := matches[3]
virtualMachineIndex := matches[3]
networkInterfaceName := matches[4]
IPConfigurationName := matches[5]
publicIPAddressName := matches[6]
pip, existsPip, err := ss.getVMSSPublicIPAddress(resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName, publicIPAddressName)
pip, existsPip, err := ss.getVMSSPublicIPAddress(resourceGroupName, virtualMachineScaleSetName, virtualMachineIndex, networkInterfaceName, IPConfigurationName, publicIPAddressName)
if err != nil {
klog.Errorf("ss.getVMSSPublicIPAddress() failed with error: %v", err)
return "", "", err

View File

@ -19,7 +19,6 @@ limitations under the License.
package azure
import (
"context"
"sync"
"testing"
@ -27,8 +26,11 @@ import (
"github.com/Azure/go-autorest/autorest/to"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
cloudprovider "k8s.io/cloud-provider"
azcache "k8s.io/legacy-cloud-providers/azure/cache"
"k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient"
)
func TestExtractVmssVMName(t *testing.T) {
@ -81,16 +83,23 @@ func TestVMSSVMCache(t *testing.T) {
vmssName := "vmss"
vmList := []string{"vmssee6c2000000", "vmssee6c2000001", "vmssee6c2000002"}
ss, err := newTestScaleSet(ctrl, vmssName, "", 0, vmList)
ss, err := newTestScaleSet(ctrl)
assert.NoError(t, err)
mockVMSSClient := mockvmssclient.NewMockInterface(ctrl)
mockVMSSVMClient := mockvmssvmclient.NewMockInterface(ctrl)
ss.cloud.VirtualMachineScaleSetsClient = mockVMSSClient
ss.cloud.VirtualMachineScaleSetVMsClient = mockVMSSVMClient
expectedScaleSet := compute.VirtualMachineScaleSet{Name: &vmssName}
mockVMSSClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachineScaleSet{expectedScaleSet}, nil).AnyTimes()
expectedVMs, _, _ := buildTestVirtualMachineEnv(ss.cloud, vmssName, "", 0, vmList, "")
mockVMSSVMClient.EXPECT().List(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedVMs, nil).AnyTimes()
// validate getting VMSS VM via cache.
virtualMachines, rerr := ss.VirtualMachineScaleSetVMsClient.List(
context.Background(), "rg", "vmss", "")
assert.Nil(t, rerr)
assert.Equal(t, 3, len(virtualMachines))
for i := range virtualMachines {
vm := virtualMachines[i]
for i := range expectedVMs {
vm := expectedVMs[i]
vmName := to.String(vm.OsProfile.ComputerName)
ssName, instanceID, realVM, err := ss.getVmssVM(vmName, azcache.CacheReadTypeDefault)
assert.Nil(t, err)
@ -100,7 +109,7 @@ func TestVMSSVMCache(t *testing.T) {
}
// validate deleteCacheForNode().
vm := virtualMachines[0]
vm := expectedVMs[0]
vmName := to.String(vm.OsProfile.ComputerName)
err = ss.deleteCacheForNode(vmName)
assert.NoError(t, err)
@ -112,7 +121,7 @@ func TestVMSSVMCache(t *testing.T) {
_, ok := cachedVirtualMachines.Load(vmName)
assert.Equal(t, false, ok)
// the VM should be get back after another cache refresh.
// the VM should be back after another cache refresh.
ssName, instanceID, realVM, err := ss.getVmssVM(vmName, azcache.CacheReadTypeDefault)
assert.NoError(t, err)
assert.Equal(t, "vmss", ssName)
@ -126,15 +135,22 @@ func TestVMSSVMCacheWithDeletingNodes(t *testing.T) {
vmssName := "vmss"
vmList := []string{"vmssee6c2000000", "vmssee6c2000001", "vmssee6c2000002"}
ss, err := newTestScaleSetWithState(ctrl, vmssName, "", 0, vmList, "Deleting")
ss, err := newTestScaleSetWithState(ctrl)
assert.NoError(t, err)
virtualMachines, rerr := ss.VirtualMachineScaleSetVMsClient.List(
context.Background(), "rg", "vmss", "")
assert.Nil(t, rerr)
assert.Equal(t, 3, len(virtualMachines))
for i := range virtualMachines {
vm := virtualMachines[i]
mockVMSSClient := mockvmssclient.NewMockInterface(ctrl)
mockVMSSVMClient := mockvmssvmclient.NewMockInterface(ctrl)
ss.cloud.VirtualMachineScaleSetsClient = mockVMSSClient
ss.cloud.VirtualMachineScaleSetVMsClient = mockVMSSVMClient
expectedScaleSet := compute.VirtualMachineScaleSet{Name: &vmssName}
mockVMSSClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachineScaleSet{expectedScaleSet}, nil).AnyTimes()
expectedVMs, _, _ := buildTestVirtualMachineEnv(ss.cloud, vmssName, "", 0, vmList, string(compute.ProvisioningStateDeleting))
mockVMSSVMClient.EXPECT().List(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedVMs, nil).AnyTimes()
for i := range expectedVMs {
vm := expectedVMs[i]
vmName := to.String(vm.OsProfile.ComputerName)
assert.Equal(t, vm.ProvisioningState, to.StringPtr(string(compute.ProvisioningStateDeleting)))

View File

@ -23,6 +23,15 @@ import (
"strings"
"testing"
cloudprovider "k8s.io/cloud-provider"
azcache "k8s.io/legacy-cloud-providers/azure/cache"
"k8s.io/legacy-cloud-providers/azure/clients/interfaceclient/mockinterfaceclient"
"k8s.io/legacy-cloud-providers/azure/clients/publicipclient/mockpublicipclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient"
"k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient"
"k8s.io/legacy-cloud-providers/azure/retry"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network"
"github.com/Azure/go-autorest/autorest/to"
@ -35,13 +44,12 @@ const (
fakePublicIP = "10.10.10.10"
)
func newTestScaleSet(ctrl *gomock.Controller, scaleSetName, zone string, faultDomain int32, vmList []string) (*scaleSet, error) {
return newTestScaleSetWithState(ctrl, scaleSetName, zone, faultDomain, vmList, "Running")
func newTestScaleSet(ctrl *gomock.Controller) (*scaleSet, error) {
return newTestScaleSetWithState(ctrl)
}
func newTestScaleSetWithState(ctrl *gomock.Controller, scaleSetName, zone string, faultDomain int32, vmList []string, state string) (*scaleSet, error) {
func newTestScaleSetWithState(ctrl *gomock.Controller) (*scaleSet, error) {
cloud := GetTestCloud(ctrl)
setTestVirtualMachineCloud(cloud, scaleSetName, zone, faultDomain, vmList, state)
ss, err := newScaleSet(cloud)
if err != nil {
return nil, err
@ -50,37 +58,18 @@ func newTestScaleSetWithState(ctrl *gomock.Controller, scaleSetName, zone string
return ss.(*scaleSet), nil
}
func setTestVirtualMachineCloud(ss *Cloud, scaleSetName, zone string, faultDomain int32, vmList []string, state string) {
virtualMachineScaleSetsClient := newFakeVirtualMachineScaleSetsClient()
virtualMachineScaleSetVMsClient := newFakeVirtualMachineScaleSetVMsClient()
publicIPAddressesClient := newFakeAzurePIPClient("rg")
interfaceClient := newFakeAzureInterfacesClient()
func buildTestVirtualMachineEnv(ss *Cloud, scaleSetName, zone string, faultDomain int32, vmList []string, state string) ([]compute.VirtualMachineScaleSetVM, network.Interface, network.PublicIPAddress) {
expectedVMSSVMs := make([]compute.VirtualMachineScaleSetVM, 0)
expectedInterface := network.Interface{}
expectedPIP := network.PublicIPAddress{}
// set test scale sets.
scaleSets := make(map[string]map[string]compute.VirtualMachineScaleSet)
scaleSets["rg"] = map[string]compute.VirtualMachineScaleSet{
scaleSetName: {
Name: &scaleSetName,
},
}
virtualMachineScaleSetsClient.setFakeStore(scaleSets)
testInterfaces := map[string]map[string]network.Interface{
"rg": make(map[string]network.Interface),
}
testPIPs := map[string]map[string]network.PublicIPAddress{
"rg": make(map[string]network.PublicIPAddress),
}
ssVMs := map[string]map[string]compute.VirtualMachineScaleSetVM{
"rg": make(map[string]compute.VirtualMachineScaleSetVM),
}
for i := range vmList {
nodeName := vmList[i]
ID := fmt.Sprintf("/subscriptions/script/resourceGroups/rg/providers/Microsoft.Compute/virtualMachineScaleSets/%s/virtualMachines/%d", scaleSetName, i)
interfaceID := fmt.Sprintf("/subscriptions/script/resourceGroups/rg/providers/Microsoft.Compute/virtualMachineScaleSets/%s/virtualMachines/%d/networkInterfaces/%s", scaleSetName, i, nodeName)
publicAddressID := fmt.Sprintf("/subscriptions/script/resourceGroups/rg/providers/Microsoft.Compute/virtualMachineScaleSets/%s/virtualMachines/%d/networkInterfaces/%s/ipConfigurations/ipconfig1/publicIPAddresses/%s", scaleSetName, i, nodeName, nodeName)
instanceID := fmt.Sprintf("%d", i)
vmName := fmt.Sprintf("%s_%s", scaleSetName, instanceID)
publicAddressID := fmt.Sprintf("/subscriptions/script/resourceGroups/rg/providers/Microsoft.Compute/virtualMachineScaleSets/%s/virtualMachines/%d/networkInterfaces/%s/ipConfigurations/ipconfig1/publicIPAddresses/%s", scaleSetName, i, nodeName, nodeName)
// set vmss virtual machine.
networkInterfaces := []compute.NetworkInterfaceReference{
@ -128,10 +117,9 @@ func setTestVirtualMachineCloud(ss *Cloud, scaleSetName, zone string, faultDomai
zones := []string{zone}
vmssVM.Zones = &zones
}
ssVMs["rg"][vmName] = vmssVM
// set interfaces.
testInterfaces["rg"][nodeName] = network.Interface{
expectedInterface = network.Interface{
ID: &interfaceID,
InterfacePropertiesFormat: &network.InterfacePropertiesFormat{
IPConfigurations: &[]network.InterfaceIPConfiguration{
@ -149,21 +137,17 @@ func setTestVirtualMachineCloud(ss *Cloud, scaleSetName, zone string, faultDomai
}
// set public IPs.
testPIPs["rg"][nodeName] = network.PublicIPAddress{
expectedPIP = network.PublicIPAddress{
ID: to.StringPtr(publicAddressID),
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
IPAddress: to.StringPtr(fakePublicIP),
},
}
}
virtualMachineScaleSetVMsClient.setFakeStore(ssVMs)
interfaceClient.setFakeStore(testInterfaces)
publicIPAddressesClient.setFakeStore(testPIPs)
ss.VirtualMachineScaleSetsClient = virtualMachineScaleSetsClient
ss.VirtualMachineScaleSetVMsClient = virtualMachineScaleSetVMsClient
ss.InterfacesClient = interfaceClient
ss.PublicIPAddressesClient = publicIPAddressesClient
expectedVMSSVMs = append(expectedVMSSVMs, vmssVM)
}
return expectedVMSSVMs, expectedInterface, expectedPIP
}
func TestGetScaleSetVMInstanceID(t *testing.T) {
@ -231,9 +215,23 @@ func TestGetInstanceIDByNodeName(t *testing.T) {
}
for _, test := range testCases {
ss, err := newTestScaleSet(ctrl, test.scaleSet, "", 0, test.vmList)
ss, err := newTestScaleSet(ctrl)
assert.NoError(t, err, test.description)
mockVMSSClient := mockvmssclient.NewMockInterface(ctrl)
mockVMSSVMClient := mockvmssvmclient.NewMockInterface(ctrl)
ss.cloud.VirtualMachineScaleSetsClient = mockVMSSClient
ss.cloud.VirtualMachineScaleSetVMsClient = mockVMSSVMClient
expectedScaleSet := compute.VirtualMachineScaleSet{Name: &test.scaleSet}
mockVMSSClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachineScaleSet{expectedScaleSet}, nil).AnyTimes()
expectedVMs, _, _ := buildTestVirtualMachineEnv(ss.cloud, test.scaleSet, "", 0, test.vmList, "")
mockVMSSVMClient.EXPECT().List(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedVMs, nil).AnyTimes()
mockVMsClient := ss.cloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
mockVMsClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachine{}, nil).AnyTimes()
real, err := ss.GetInstanceIDByNodeName(test.nodeName)
if test.expectError {
assert.Error(t, err, test.description)
@ -302,10 +300,22 @@ func TestGetZoneByNodeName(t *testing.T) {
if test.location != "" {
cloud.Location = test.location
}
setTestVirtualMachineCloud(cloud, test.scaleSet, test.zone, test.faultDomain, test.vmList, "Running")
scaleset, err := newScaleSet(cloud)
ss, err := newTestScaleSet(ctrl)
assert.NoError(t, err, test.description)
ss := scaleset.(*scaleSet)
mockVMSSClient := mockvmssclient.NewMockInterface(ctrl)
mockVMSSVMClient := mockvmssvmclient.NewMockInterface(ctrl)
ss.cloud.VirtualMachineScaleSetsClient = mockVMSSClient
ss.cloud.VirtualMachineScaleSetVMsClient = mockVMSSVMClient
expectedScaleSet := compute.VirtualMachineScaleSet{Name: &test.scaleSet}
mockVMSSClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachineScaleSet{expectedScaleSet}, nil).AnyTimes()
expectedVMs, _, _ := buildTestVirtualMachineEnv(ss.cloud, test.scaleSet, test.zone, test.faultDomain, test.vmList, "")
mockVMSSVMClient.EXPECT().List(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedVMs, nil).AnyTimes()
mockVMsClient := ss.cloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
mockVMsClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachine{}, nil).AnyTimes()
real, err := ss.GetZoneByNodeName(test.nodeName)
if test.expectError {
@ -348,9 +358,29 @@ func TestGetIPByNodeName(t *testing.T) {
}
for _, test := range testCases {
ss, err := newTestScaleSet(ctrl, test.scaleSet, "", 0, test.vmList)
ss, err := newTestScaleSet(ctrl)
assert.NoError(t, err, test.description)
mockVMSSClient := mockvmssclient.NewMockInterface(ctrl)
mockVMSSVMClient := mockvmssvmclient.NewMockInterface(ctrl)
mockInterfaceClient := mockinterfaceclient.NewMockInterface(ctrl)
mockPIPClient := mockpublicipclient.NewMockInterface(ctrl)
ss.cloud.VirtualMachineScaleSetsClient = mockVMSSClient
ss.cloud.VirtualMachineScaleSetVMsClient = mockVMSSVMClient
ss.cloud.InterfacesClient = mockInterfaceClient
ss.cloud.PublicIPAddressesClient = mockPIPClient
expectedScaleSet := compute.VirtualMachineScaleSet{Name: &test.scaleSet}
mockVMSSClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachineScaleSet{expectedScaleSet}, nil).AnyTimes()
expectedVMs, expectedInterface, expectedPIP := buildTestVirtualMachineEnv(ss.cloud, test.scaleSet, "", 0, test.vmList, "")
mockVMSSVMClient.EXPECT().List(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedVMs, nil).AnyTimes()
mockInterfaceClient.EXPECT().GetVirtualMachineScaleSetNetworkInterface(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedInterface, nil).AnyTimes()
mockPIPClient.EXPECT().GetVirtualMachineScaleSetPublicIPAddress(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedPIP, nil).AnyTimes()
mockVMsClient := ss.cloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
mockVMsClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachine{}, nil).AnyTimes()
privateIP, publicIP, err := ss.GetIPByNodeName(test.nodeName)
if test.expectError {
assert.Error(t, err, test.description)
@ -400,9 +430,20 @@ func TestGetNodeNameByIPConfigurationID(t *testing.T) {
}
for _, test := range testCases {
ss, err := newTestScaleSet(ctrl, test.scaleSet, "", 0, test.vmList)
ss, err := newTestScaleSet(ctrl)
assert.NoError(t, err, test.description)
mockVMSSClient := mockvmssclient.NewMockInterface(ctrl)
mockVMSSVMClient := mockvmssvmclient.NewMockInterface(ctrl)
ss.cloud.VirtualMachineScaleSetsClient = mockVMSSClient
ss.cloud.VirtualMachineScaleSetVMsClient = mockVMSSVMClient
expectedScaleSet := compute.VirtualMachineScaleSet{Name: &test.scaleSet}
mockVMSSClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachineScaleSet{expectedScaleSet}, nil).AnyTimes()
expectedVMs, _, _ := buildTestVirtualMachineEnv(ss.cloud, test.scaleSet, "", 0, test.vmList, "")
mockVMSSVMClient.EXPECT().List(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedVMs, nil).AnyTimes()
nodeName, err := ss.getNodeNameByIPConfigurationID(test.ipConfigurationID)
if test.expectError {
assert.Error(t, err, test.description)
@ -451,3 +492,105 @@ func TestExtractResourceGroupByVMSSNicID(t *testing.T) {
assert.Equal(t, test.expected, resourceGroup, test.description)
}
}
func TestGetVMSS(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
testCases := []struct {
description string
existedVMSSName string
vmssName string
vmssListError *retry.Error
expectedErr error
}{
{
description: "getVMSS should return the correct VMSS",
existedVMSSName: "vmss-1",
vmssName: "vmss-1",
},
{
description: "getVMSS should return cloudprovider.InstanceNotFound if there's no matching VMSS",
existedVMSSName: "vmss-1",
vmssName: "vmss-2",
expectedErr: cloudprovider.InstanceNotFound,
},
{
description: "getVMSS should report an error if there's something wrong during an api call",
existedVMSSName: "vmss-1",
vmssName: "vmss-1",
vmssListError: &retry.Error{RawError: fmt.Errorf("error during vmss list")},
expectedErr: fmt.Errorf("Retriable: false, RetryAfter: 0s, HTTPStatusCode: 0, RawError: error during vmss list"),
},
}
for _, test := range testCases {
ss, err := newTestScaleSet(ctrl)
assert.NoError(t, err, test.description)
mockVMSSClient := mockvmssclient.NewMockInterface(ctrl)
ss.cloud.VirtualMachineScaleSetsClient = mockVMSSClient
expected := compute.VirtualMachineScaleSet{Name: to.StringPtr(test.existedVMSSName)}
mockVMSSClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachineScaleSet{expected}, test.vmssListError).AnyTimes()
actual, err := ss.getVMSS(test.vmssName, azcache.CacheReadTypeDefault)
assert.Equal(t, test.expectedErr, err, test.description)
if actual != nil {
assert.Equal(t, expected, *actual, test.description)
}
}
}
func TestGetVmssVM(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
testCases := []struct {
description string
nodeName string
existedNodeNames []string
existedVMSSName string
expectedError error
}{
{
description: "getVmssVM should return the correct name of vmss, the instance id of the node, and the corresponding vmss instance",
nodeName: "vmss-vm-000000",
existedNodeNames: []string{"vmss-vm-000000"},
existedVMSSName: "vmss",
},
{
description: "getVmssVM should report an error of instance not found if there's no matches",
nodeName: "vmss-vm-000001",
existedNodeNames: []string{"vmss-vm-000000"},
existedVMSSName: "vmss",
expectedError: cloudprovider.InstanceNotFound,
},
}
for _, test := range testCases {
ss, err := newTestScaleSet(ctrl)
assert.NoError(t, err, test.description)
expectedVMSS := compute.VirtualMachineScaleSet{Name: to.StringPtr(test.existedVMSSName)}
mockVMSSClient := ss.cloud.VirtualMachineScaleSetsClient.(*mockvmssclient.MockInterface)
mockVMSSClient.EXPECT().List(gomock.Any(), ss.ResourceGroup).Return([]compute.VirtualMachineScaleSet{expectedVMSS}, nil).AnyTimes()
expectedVMSSVMs, _, _ := buildTestVirtualMachineEnv(ss.cloud, test.existedVMSSName, "", 0, test.existedNodeNames, "")
var expectedVMSSVM compute.VirtualMachineScaleSetVM
for _, expected := range expectedVMSSVMs {
if strings.EqualFold(*expected.OsProfile.ComputerName, test.nodeName) {
expectedVMSSVM = expected
}
}
mockVMSSVMClient := ss.cloud.VirtualMachineScaleSetVMsClient.(*mockvmssvmclient.MockInterface)
mockVMSSVMClient.EXPECT().List(gomock.Any(), ss.ResourceGroup, test.existedVMSSName, gomock.Any()).Return(expectedVMSSVMs, nil).AnyTimes()
_, _, vmssVM, err := ss.getVmssVM(test.nodeName, azcache.CacheReadTypeDefault)
if vmssVM != nil {
assert.Equal(t, expectedVMSSVM, *vmssVM, test.description)
}
assert.Equal(t, test.expectedError, err, test.description)
}
}

View File

@ -29,6 +29,7 @@ filegroup(
":package-srcs",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/armclient:all-srcs",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/diskclient:all-srcs",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/fileclient:all-srcs",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/interfaceclient:all-srcs",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient:all-srcs",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/publicipclient:all-srcs",

View File

@ -0,0 +1,36 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"azure_fileclient.go",
"doc.go",
"interface.go",
],
importmap = "k8s.io/kubernetes/vendor/k8s.io/legacy-cloud-providers/azure/clients/fileclient",
importpath = "k8s.io/legacy-cloud-providers/azure/clients/fileclient",
visibility = ["//visibility:public"],
deps = [
"//staging/src/k8s.io/legacy-cloud-providers/azure/retry:go_default_library",
"//vendor/github.com/Azure/azure-sdk-for-go/storage:go_default_library",
"//vendor/github.com/Azure/go-autorest/autorest/azure:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/fileclient/mockfileclient:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,124 @@
// +build !providerless
/*
Copyright 2020 The Kubernetes Authors.
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
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fileclient
import (
"fmt"
"net/http"
azs "github.com/Azure/azure-sdk-for-go/storage"
"github.com/Azure/go-autorest/autorest/azure"
"k8s.io/klog"
"k8s.io/legacy-cloud-providers/azure/retry"
)
const (
useHTTPS = true
)
var (
// refer https://github.com/Azure/azure-sdk-for-go/blob/master/storage/client.go#L88.
defaultValidStatusCodes = []int{
http.StatusRequestTimeout, // 408
http.StatusInternalServerError, // 500
http.StatusBadGateway, // 502
http.StatusServiceUnavailable, // 503
http.StatusGatewayTimeout, // 504
}
)
// AzureFileClient implements the azure file client interface
type AzureFileClient struct {
env *azure.Environment
backoff *retry.Backoff
}
// NewAzureFileClient creates a azure file client
func NewAzureFileClient(env *azure.Environment, backoff *retry.Backoff) *AzureFileClient {
return &AzureFileClient{
env: env,
backoff: backoff,
}
}
// CreateFileShare creates a file share
func (f *AzureFileClient) CreateFileShare(accountName, accountKey, name string, sizeGiB int) error {
fileClient, err := f.getFileSvcClient(accountName, accountKey)
if err != nil {
return err
}
share := fileClient.GetShareReference(name)
share.Properties.Quota = sizeGiB
newlyCreated, err := share.CreateIfNotExists(nil)
if err != nil {
return fmt.Errorf("failed to create file share, err: %v", err)
}
if !newlyCreated {
klog.V(2).Infof("file share(%s) under account(%s) already exists", name, accountName)
}
return nil
}
// DeleteFileShare deletes a file share
func (f *AzureFileClient) DeleteFileShare(accountName, accountKey, name string) error {
fileClient, err := f.getFileSvcClient(accountName, accountKey)
if err != nil {
return err
}
return fileClient.GetShareReference(name).Delete(nil)
}
// ResizeFileShare resizes a file share
func (f *AzureFileClient) ResizeFileShare(accountName, accountKey, name string, sizeGiB int) error {
fileClient, err := f.getFileSvcClient(accountName, accountKey)
if err != nil {
return err
}
share := fileClient.GetShareReference(name)
if share.Properties.Quota >= sizeGiB {
klog.Warningf("file share size(%dGi) is already greater or equal than requested size(%dGi), accountName: %s, shareName: %s",
share.Properties.Quota, sizeGiB, accountName, name)
return nil
}
share.Properties.Quota = sizeGiB
if err = share.SetProperties(nil); err != nil {
return fmt.Errorf("failed to set quota on file share %s, err: %v", name, err)
}
klog.V(4).Infof("resize file share completed, accountName: %s, shareName: %s, sizeGiB: %d", accountName, name, sizeGiB)
return nil
}
func (f *AzureFileClient) getFileSvcClient(accountName, accountKey string) (*azs.FileServiceClient, error) {
fileClient, err := azs.NewClient(accountName, accountKey, f.env.StorageEndpointSuffix, azs.DefaultAPIVersion, useHTTPS)
if err != nil {
return nil, fmt.Errorf("error creating azure client: %v", err)
}
if f.backoff != nil {
fileClient.Sender = &azs.DefaultSender{
RetryAttempts: f.backoff.Steps,
ValidStatusCodes: defaultValidStatusCodes,
RetryDuration: f.backoff.Duration,
}
}
fc := fileClient.GetFileService()
return &fc, nil
}

View File

@ -0,0 +1,20 @@
// +build !providerless
/*
Copyright 2020 The Kubernetes Authors.
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
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package fileclient implements the client for azure file.
package fileclient // import "k8s.io/legacy-cloud-providers/azure/clients/fileclient"

View File

@ -0,0 +1,27 @@
// +build !providerless
/*
Copyright 2020 The Kubernetes Authors.
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
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fileclient
// Interface is the client interface for creating file shares, interface for test injection.
// mockgen -source=$GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/legacy-cloud-providers/azure/clients/fileclient/interface.go -package=mockfileclient Interface > $GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/legacy-cloud-providers/azure/clients/fileclient/mockfileclient/interface.go
type Interface interface {
CreateFileShare(accountName, accountKey, name string, sizeGiB int) error
DeleteFileShare(accountName, accountKey, name string) error
ResizeFileShare(accountName, accountKey, name string, sizeGiB int) error
}

View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"interface.go",
],
importmap = "k8s.io/kubernetes/vendor/k8s.io/legacy-cloud-providers/azure/clients/fileclient/mockfileclient",
importpath = "k8s.io/legacy-cloud-providers/azure/clients/fileclient/mockfileclient",
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/golang/mock/gomock:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,20 @@
// +build !providerless
/*
Copyright 2020 The Kubernetes Authors.
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
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package mockfileclient implements the mock client for azure file.
package mockfileclient // import "k8s.io/legacy-cloud-providers/azure/clients/filelient/mockfileclient"

View File

@ -0,0 +1,90 @@
// +build !providerless
/*
Copyright 2020 The Kubernetes Authors.
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
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mockfileclient
import (
reflect "reflect"
gomock "github.com/golang/mock/gomock"
)
// MockInterface is a mock of Interface interface
type MockInterface struct {
ctrl *gomock.Controller
recorder *MockInterfaceMockRecorder
}
// MockInterfaceMockRecorder is the mock recorder for MockInterface
type MockInterfaceMockRecorder struct {
mock *MockInterface
}
// NewMockInterface creates a new mock instance
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
mock := &MockInterface{ctrl: ctrl}
mock.recorder = &MockInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
return m.recorder
}
// CreateFileShare mocks base method
func (m *MockInterface) CreateFileShare(accountName, accountKey, name string, sizeGiB int) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateFileShare", accountName, accountKey, name, sizeGiB)
ret0, _ := ret[0].(error)
return ret0
}
// CreateFileShare indicates an expected call of CreateFileShare
func (mr *MockInterfaceMockRecorder) CreateFileShare(accountName, accountKey, name, sizeGiB interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateFileShare", reflect.TypeOf((*MockInterface)(nil).CreateFileShare), accountName, accountKey, name, sizeGiB)
}
// DeleteFileShare mocks base method
func (m *MockInterface) DeleteFileShare(accountName, accountKey, name string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteFileShare", accountName, accountKey, name)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteFileShare indicates an expected call of DeleteFileShare
func (mr *MockInterfaceMockRecorder) DeleteFileShare(accountName, accountKey, name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteFileShare", reflect.TypeOf((*MockInterface)(nil).DeleteFileShare), accountName, accountKey, name)
}
// ResizeFileShare mocks base method
func (m *MockInterface) ResizeFileShare(accountName, accountKey, name string, sizeGiB int) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ResizeFileShare", accountName, accountKey, name, sizeGiB)
ret0, _ := ret[0].(error)
return ret0
}
// ResizeFileShare indicates an expected call of ResizeFileShare
func (mr *MockInterfaceMockRecorder) ResizeFileShare(accountName, accountKey, name, sizeGiB interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResizeFileShare", reflect.TypeOf((*MockInterface)(nil).ResizeFileShare), accountName, accountKey, name, sizeGiB)
}

View File

@ -12,6 +12,7 @@ go_library(
deps = [
"//staging/src/k8s.io/legacy-cloud-providers/azure/retry:go_default_library",
"//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute:go_default_library",
"//vendor/github.com/Azure/go-autorest/autorest/azure:go_default_library",
"//vendor/github.com/golang/mock/gomock:go_default_library",
],
)

View File

@ -20,9 +20,11 @@ package mockvmssclient
import (
context "context"
http "net/http"
reflect "reflect"
compute "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
azure "github.com/Azure/go-autorest/autorest/azure"
gomock "github.com/golang/mock/gomock"
retry "k8s.io/legacy-cloud-providers/azure/retry"
)
@ -94,6 +96,36 @@ func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, VMSc
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, VMScaleSetName, parameters)
}
// CreateOrUpdateAsync mocks base method
func (m *MockInterface) CreateOrUpdateAsync(ctx context.Context, resourceGroupName, VMScaleSetName string, parameters compute.VirtualMachineScaleSet) (*azure.Future, *retry.Error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateOrUpdateAsync", ctx, resourceGroupName, VMScaleSetName, parameters)
ret0, _ := ret[0].(*azure.Future)
ret1, _ := ret[1].(*retry.Error)
return ret0, ret1
}
// CreateOrUpdateAsync indicates an expected call of CreateOrUpdateAsync
func (mr *MockInterfaceMockRecorder) CreateOrUpdateAsync(ctx, resourceGroupName, VMScaleSetName, parameters interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdateAsync", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdateAsync), ctx, resourceGroupName, VMScaleSetName, parameters)
}
// WaitForAsyncOperationResult mocks base method
func (m *MockInterface) WaitForAsyncOperationResult(ctx context.Context, future *azure.Future) (*http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "WaitForAsyncOperationResult", ctx, future)
ret0, _ := ret[0].(*http.Response)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// WaitForAsyncOperationResult indicates an expected call of WaitForAsyncOperationResult
func (mr *MockInterfaceMockRecorder) WaitForAsyncOperationResult(ctx, future interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForAsyncOperationResult", reflect.TypeOf((*MockInterface)(nil).WaitForAsyncOperationResult), ctx, future)
}
// DeleteInstances mocks base method
func (m *MockInterface) DeleteInstances(ctx context.Context, resourceGroupName, vmScaleSetName string, vmInstanceIDs compute.VirtualMachineScaleSetVMInstanceRequiredIDs) *retry.Error {
m.ctrl.T.Helper()

9
vendor/modules.txt vendored
View File

@ -1873,22 +1873,31 @@ k8s.io/legacy-cloud-providers/azure/cache
k8s.io/legacy-cloud-providers/azure/clients
k8s.io/legacy-cloud-providers/azure/clients/armclient
k8s.io/legacy-cloud-providers/azure/clients/diskclient
k8s.io/legacy-cloud-providers/azure/clients/diskclient/mockdiskclient
k8s.io/legacy-cloud-providers/azure/clients/fileclient
k8s.io/legacy-cloud-providers/azure/clients/interfaceclient
k8s.io/legacy-cloud-providers/azure/clients/interfaceclient/mockinterfaceclient
k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient
k8s.io/legacy-cloud-providers/azure/clients/loadbalancerclient/mockloadbalancerclient
k8s.io/legacy-cloud-providers/azure/clients/publicipclient
k8s.io/legacy-cloud-providers/azure/clients/publicipclient/mockpublicipclient
k8s.io/legacy-cloud-providers/azure/clients/routeclient
k8s.io/legacy-cloud-providers/azure/clients/routeclient/mockrouteclient
k8s.io/legacy-cloud-providers/azure/clients/routetableclient
k8s.io/legacy-cloud-providers/azure/clients/routetableclient/mockroutetableclient
k8s.io/legacy-cloud-providers/azure/clients/securitygroupclient
k8s.io/legacy-cloud-providers/azure/clients/securitygroupclient/mocksecuritygroupclient
k8s.io/legacy-cloud-providers/azure/clients/snapshotclient
k8s.io/legacy-cloud-providers/azure/clients/storageaccountclient
k8s.io/legacy-cloud-providers/azure/clients/subnetclient
k8s.io/legacy-cloud-providers/azure/clients/subnetclient/mocksubnetclient
k8s.io/legacy-cloud-providers/azure/clients/vmclient
k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient
k8s.io/legacy-cloud-providers/azure/clients/vmsizeclient
k8s.io/legacy-cloud-providers/azure/clients/vmssclient
k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient
k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient
k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient
k8s.io/legacy-cloud-providers/azure/metrics
k8s.io/legacy-cloud-providers/azure/retry
k8s.io/legacy-cloud-providers/gce