diff --git a/pkg/azure/access/helpers/disk.go b/pkg/azure/access/helpers/disk.go index fc2a2b7a..d90a1051 100644 --- a/pkg/azure/access/helpers/disk.go +++ b/pkg/azure/access/helpers/disk.go @@ -6,6 +6,8 @@ package helpers import ( "context" + "time" + "k8s.io/klog/v2" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" @@ -17,6 +19,9 @@ import ( const ( diskDeleteServiceLabel = "disk_delete" + diskCreateServiceLabel = "disk_create" + + defaultDiskOperationTimeout = 10 * time.Minute ) // DeleteDisk deletes disk for passed in resourceGroup and diskName. @@ -38,3 +43,25 @@ func DeleteDisk(ctx context.Context, client *armcompute.DisksClient, resourceGro klog.Infof("Successfully deleted Disk: %s, for ResourceGroup: %s", diskName, resourceGroup) return } + +// CreateDisk creates a Disk given a resourceGroup and disk creation parameters. +// NOTE: All calls to this Azure API are instrumented as prometheus metric. +func CreateDisk(ctx context.Context, client *armcompute.DisksClient, resourceGroup, diskName string, diskCreationParams armcompute.Disk) (disk *armcompute.Disk, err error) { + defer instrument.AZAPIMetricRecorderFn(diskCreateServiceLabel, &err)() + + createCtx, cancelFn := context.WithTimeout(ctx, defaultDiskOperationTimeout) + defer cancelFn() + poller, err := client.BeginCreateOrUpdate(createCtx, resourceGroup, diskName, diskCreationParams, nil) + if err != nil { + errors.LogAzAPIError(err, "Failed to trigger create of Disk [Name: %s, ResourceGroup: %s]", resourceGroup, diskName) + return + } + createResp, err := poller.PollUntilDone(createCtx, nil) + if err != nil { + errors.LogAzAPIError(err, "Polling failed while waiting for create of Disk: %s for ResourceGroup: %s", diskName, resourceGroup) + return + } + disk = &createResp.Disk + klog.Infof("Successfully created Disk: %s, for ResourceGroup: %s", diskName, resourceGroup) + return +} diff --git a/pkg/azure/api/providerspec.go b/pkg/azure/api/providerspec.go index 0fcfd69a..9c4caa95 100644 --- a/pkg/azure/api/providerspec.go +++ b/pkg/azure/api/providerspec.go @@ -206,6 +206,8 @@ type AzureDataDisk struct { StorageAccountType string `json:"storageAccountType,omitempty"` // DiskSizeGB is the size of an empty disk in gigabytes. DiskSizeGB int32 `json:"diskSizeGB,omitempty"` + // ImageRef optionally specifies an image source + ImageRef *AzureImageReference `json:"imageRef,omitempty"` } // AzureManagedDiskParameters is the parameters of a managed disk. diff --git a/pkg/azure/api/validation/validation.go b/pkg/azure/api/validation/validation.go index 6433bff5..21f6e2b0 100644 --- a/pkg/azure/api/validation/validation.go +++ b/pkg/azure/api/validation/validation.go @@ -243,6 +243,10 @@ func validateDataDisks(disks []api.AzureDataDisk, fldPath *field.Path) field.Err if utils.IsEmptyString(disk.StorageAccountType) { allErrs = append(allErrs, field.Required(fldPath.Child("storageAccountType"), "must provide storageAccountType")) } + + if disk.ImageRef != nil { + allErrs = append(allErrs, validateStorageImageRef(*disk.ImageRef, fldPath.Child("imageRef"))...) + } } for lun, numOccurrence := range luns { diff --git a/pkg/azure/api/validation/validation_test.go b/pkg/azure/api/validation/validation_test.go index 4a063d0c..747c9e1d 100644 --- a/pkg/azure/api/validation/validation_test.go +++ b/pkg/azure/api/validation/validation_test.go @@ -489,7 +489,8 @@ func TestValidateCloudConfiguration(t *testing.T) { g := NewWithT(t) t.Parallel() for _, entry := range table { - t.Run(entry.description, func(_ *testing.T) { + t.Run(entry.description, func(t *testing.T) { + t.Parallel() errList := validateCloudConfiguration(entry.cloudConfiguration, fldPath) if entry.matcher != nil { g.Expect(errList).To(entry.matcher) diff --git a/pkg/azure/provider/helpers/connectconfig_test.go b/pkg/azure/provider/helpers/connectconfig_test.go index 1b4f9eb7..9e4c515f 100644 --- a/pkg/azure/provider/helpers/connectconfig_test.go +++ b/pkg/azure/provider/helpers/connectconfig_test.go @@ -28,7 +28,8 @@ func TestDetermineAzureCloudConfiguration(t *testing.T) { g := NewWithT(t) t.Parallel() for _, test := range tests { - t.Run(test.description, func(_ *testing.T) { + t.Run(test.description, func(t *testing.T) { + t.Parallel() cloudConfiguration := DetermineAzureCloudConfiguration(test.testConfiguration) g.Expect(cloudConfiguration).To(Equal(*test.expectedOutput)) }) diff --git a/pkg/azure/provider/helpers/driver.go b/pkg/azure/provider/helpers/driver.go index c5462099..78c01aee 100644 --- a/pkg/azure/provider/helpers/driver.go +++ b/pkg/azure/provider/helpers/driver.go @@ -36,12 +36,18 @@ import ( "github.com/gardener/machine-controller-manager-provider-azure/pkg/azure/utils" ) +// DataDiskLun is a type alias for int32 which semantically represents a dataDisk lun +type DataDiskLun int32 + +// DiskID is a type alias for *string which semantically represents a Disk ID +type DiskID *string + // ExtractProviderSpecAndConnectConfig extracts api.AzureProviderSpec from mcc and access.ConnectConfig from secret. func ExtractProviderSpecAndConnectConfig(mcc *v1alpha1.MachineClass, secret *corev1.Secret) (api.AzureProviderSpec, access.ConnectConfig, error) { var ( - err error - providerSpec api.AzureProviderSpec - connectConfig access.ConnectConfig + err error + providerSpec api.AzureProviderSpec + connectConfig access.ConnectConfig ) // validate provider Spec provider. Exit early if it is not azure. if err = validation.ValidateMachineClassProvider(mcc); err != nil { @@ -127,7 +133,7 @@ func createDataDiskNames(providerSpec api.AzureProviderSpec, vmName string) []st dataDisks := providerSpec.Properties.StorageProfile.DataDisks diskNames := make([]string, 0, len(dataDisks)) for _, disk := range dataDisks { - diskName := utils.CreateDataDiskName(vmName, disk) + diskName := utils.CreateDataDiskName(vmName, disk.Name, disk.Lun) diskNames = append(diskNames, diskName) } return diskNames @@ -534,12 +540,12 @@ func checkAndAcceptAgreementIfNotAccepted(ctx context.Context, factory access.Fa } // CreateVM gathers the VM creation parameters and invokes a call to create or update the VM. -func CreateVM(ctx context.Context, factory access.Factory, connectConfig access.ConnectConfig, providerSpec api.AzureProviderSpec, imageRef armcompute.ImageReference, plan *armcompute.Plan, secret *corev1.Secret, nicID string, vmName string) (*armcompute.VirtualMachine, error) { +func CreateVM(ctx context.Context, factory access.Factory, connectConfig access.ConnectConfig, providerSpec api.AzureProviderSpec, vmImageRef armcompute.ImageReference, plan *armcompute.Plan, secret *corev1.Secret, nicID string, vmName string, imageRefDiskIDs map[DataDiskLun]DiskID) (*armcompute.VirtualMachine, error) { vmAccess, err := factory.GetVirtualMachinesAccess(connectConfig) if err != nil { return nil, status.WrapError(codes.Internal, fmt.Sprintf("Failed to create virtual machine access to process request: [resourceGroup: %s, vmName: %s], Err: %v", providerSpec.ResourceGroup, vmName, err), err) } - vmCreationParams, err := createVMCreationParams(providerSpec, imageRef, plan, secret, nicID, vmName) + vmCreationParams, err := createVMCreationParams(providerSpec, vmImageRef, plan, secret, nicID, vmName, imageRefDiskIDs) if err != nil { return nil, status.WrapError(codes.Internal, fmt.Sprintf("Failed to create virtual machine parameters to create VM: [ResourceGroup: %s, Name: %s], Err: %v", providerSpec.ResourceGroup, vmName, err), err) } @@ -552,6 +558,94 @@ func CreateVM(ctx context.Context, factory access.Factory, connectConfig access. return vm, nil } +// CreateDisksWithImageRef creates a disk with CreationData (e.g. ImageReference or GalleryImageReference) +func CreateDisksWithImageRef(ctx context.Context, factory access.Factory, connectConfig access.ConnectConfig, providerSpec api.AzureProviderSpec, vmName string) (map[DataDiskLun]DiskID, error) { + disksAccess, err := factory.GetDisksAccess(connectConfig) + if err != nil { + return nil, status.WrapError(codes.Internal, fmt.Sprintf("Failed to create disk access for VM: [ResourceGroup: %s], Err: %v", providerSpec.ResourceGroup, err), err) + } + + disks := make(map[DataDiskLun]DiskID) + dataDiskSpecs := providerSpec.Properties.StorageProfile.DataDisks + if utils.IsSliceNilOrEmpty(dataDiskSpecs) { + return disks, nil + } + + for _, specDataDisk := range dataDiskSpecs { + // skip if dataDisk does not have imageRef property + if specDataDisk.ImageRef == nil { + continue + } + diskName := utils.CreateDataDiskName(vmName, specDataDisk.Name, specDataDisk.Lun) + diskCreationParams, err := createDiskCreationParams(ctx, specDataDisk, providerSpec, factory, connectConfig) + if err != nil { + errCode := accesserrors.GetMatchingErrorCode(err) + return nil, status.WrapError(errCode, fmt.Sprintf("Failed to create disk creation params: [ResourceGroup: %s, Name: %s], Err: %v", providerSpec.ResourceGroup, diskName, err), err) + } + disk, err := accesshelpers.CreateDisk(ctx, disksAccess, providerSpec.ResourceGroup, diskName, diskCreationParams) + if err != nil { + errCode := accesserrors.GetMatchingErrorCode(err) + return nil, status.WrapError(errCode, fmt.Sprintf("Failed to create Disk: [ResourceGroup: %s, Name: %s], Err: %v", providerSpec.ResourceGroup, diskName, err), err) + } + disks[DataDiskLun(specDataDisk.Lun)] = disk.ID + klog.Infof("Successfully created Disk: [ResourceGroup: %s, Name: %s]", providerSpec.ResourceGroup, diskName) + } + + return disks, nil +} + +func createDiskCreationParams(ctx context.Context, specDataDisk api.AzureDataDisk, providerSpec api.AzureProviderSpec, factory access.Factory, connectConfig access.ConnectConfig) (params armcompute.Disk, err error) { + creationData, err := createDiskCreationData(ctx, specDataDisk, providerSpec.Location, factory, connectConfig) + if err != nil { + return armcompute.Disk{}, err + } + params = armcompute.Disk{ + Location: to.Ptr(providerSpec.Location), + Properties: &armcompute.DiskProperties{ + CreationData: creationData, + DiskSizeGB: to.Ptr[int32](specDataDisk.DiskSizeGB), + OSType: to.Ptr(armcompute.OperatingSystemTypesLinux), + }, + SKU: &armcompute.DiskSKU{ + Name: to.Ptr(armcompute.DiskStorageAccountTypes(specDataDisk.StorageAccountType)), + }, + Tags: utils.CreateResourceTags(providerSpec.Tags), + Zones: getZonesFromProviderSpec(providerSpec), + } + return +} + +func createDiskCreationData(ctx context.Context, specDataDisk api.AzureDataDisk, location string, factory access.Factory, connectConfig access.ConnectConfig) (*armcompute.CreationData, error) { + creationData := &armcompute.CreationData{ + CreateOption: to.Ptr(armcompute.DiskCreateOptionFromImage), + } + if !utils.IsEmptyString(specDataDisk.ImageRef.ID) { + creationData.ImageReference = &armcompute.ImageDiskReference{ + ID: &specDataDisk.ImageRef.ID, + } + } else if !utils.IsNilOrEmptyStringPtr(specDataDisk.ImageRef.SharedGalleryImageID) { + creationData.GalleryImageReference = &armcompute.ImageDiskReference{ + SharedGalleryImageID: specDataDisk.ImageRef.SharedGalleryImageID, + } + } else if !utils.IsNilOrEmptyStringPtr(specDataDisk.ImageRef.CommunityGalleryImageID) { + creationData.GalleryImageReference = &armcompute.ImageDiskReference{ + CommunityGalleryImageID: specDataDisk.ImageRef.CommunityGalleryImageID, + } + } else if !utils.IsNilOrEmptyStringPtr(specDataDisk.ImageRef.URN) { + imageRef := utils.ToImageReference(*specDataDisk.ImageRef.URN) + + image, err := getVirtualMachineImage(ctx, factory, connectConfig, location, imageRef) + if err != nil { + return nil, err + } + + creationData.ImageReference = &armcompute.ImageDiskReference{ + ID: image.ID, + } + } + return creationData, nil +} + // LogVMCreation is a convenience method which helps to extract relevant details from the created virtual machine and logs it. // Today the azure create VM call is atomic only w.r.t creation of VM, OSDisk, DataDisk(s). NIC still has to be created prior to creation of the VM. // Therefore, this method produces a log which also prints the OSDisk, DataDisks that are created (which helps in traceability). For completeness it @@ -578,12 +672,16 @@ func LogVMCreation(location, resourceGroup string, vm *armcompute.VirtualMachine klog.Infof(msgBuilder.String()) } -func createVMCreationParams(providerSpec api.AzureProviderSpec, imageRef armcompute.ImageReference, plan *armcompute.Plan, secret *corev1.Secret, nicID, vmName string) (armcompute.VirtualMachine, error) { +func createVMCreationParams(providerSpec api.AzureProviderSpec, imageRef armcompute.ImageReference, plan *armcompute.Plan, secret *corev1.Secret, nicID, vmName string, imageRefDiskIDs map[DataDiskLun]DiskID) (armcompute.VirtualMachine, error) { vmTags := utils.CreateResourceTags(providerSpec.Tags) sshConfiguration, err := getSSHConfiguration(providerSpec.Properties.OsProfile.LinuxConfiguration.SSH) if err != nil { return armcompute.VirtualMachine{}, err } + dataDisks, err := getDataDisks(providerSpec.Properties.StorageProfile.DataDisks, vmName, imageRefDiskIDs) + if err != nil { + return armcompute.VirtualMachine{}, status.WrapError(codes.Internal, fmt.Sprintf("Failed to create vm creation params, Err: %v", err), err) + } vm := armcompute.VirtualMachine{ Location: to.Ptr(providerSpec.Location), @@ -613,7 +711,7 @@ func createVMCreationParams(providerSpec api.AzureProviderSpec, imageRef armcomp }, }, StorageProfile: &armcompute.StorageProfile{ - DataDisks: getDataDisks(providerSpec.Properties.StorageProfile.DataDisks, vmName), + DataDisks: dataDisks, ImageReference: &imageRef, OSDisk: &armcompute.OSDisk{ CreateOption: to.Ptr(armcompute.DiskCreateOptionTypes(providerSpec.Properties.StorageProfile.OsDisk.CreateOption)), @@ -663,19 +761,18 @@ func createVMCreationParams(providerSpec api.AzureProviderSpec, imageRef armcomp return vm, nil } -func getDataDisks(specDataDisks []api.AzureDataDisk, vmName string) []*armcompute.DataDisk { +func getDataDisks(dataDiskSpecs []api.AzureDataDisk, vmName string, imageRefDiskIDs map[DataDiskLun]DiskID) ([]*armcompute.DataDisk, error) { var dataDisks []*armcompute.DataDisk - if utils.IsSliceNilOrEmpty(specDataDisks) { - return dataDisks + if utils.IsSliceNilOrEmpty(dataDiskSpecs) { + return dataDisks, nil } - for _, specDataDisk := range specDataDisks { - dataDiskName := utils.CreateDataDiskName(vmName, specDataDisk) + for _, specDataDisk := range dataDiskSpecs { + dataDiskName := utils.CreateDataDiskName(vmName, specDataDisk.Name, specDataDisk.Lun) caching := armcompute.CachingTypesNone if !utils.IsEmptyString(specDataDisk.Caching) { caching = armcompute.CachingTypes(specDataDisk.Caching) } dataDisk := &armcompute.DataDisk{ - CreateOption: to.Ptr(armcompute.DiskCreateOptionTypesEmpty), Lun: to.Ptr(specDataDisk.Lun), Caching: to.Ptr(caching), @@ -686,9 +783,19 @@ func getDataDisks(specDataDisks []api.AzureDataDisk, vmName string) []*armcomput }, Name: to.Ptr(dataDiskName), } + if specDataDisk.ImageRef != nil { + diskID := imageRefDiskIDs[DataDiskLun(specDataDisk.Lun)] + if diskID == nil { + return nil, fmt.Errorf("unexpected error, this cannot happen and points to a coding error: "+ + "could not find id of pre created disk '%s' with lun '%d'", + dataDiskName, specDataDisk.Lun) + } + dataDisk.CreateOption = to.Ptr(armcompute.DiskCreateOptionTypesAttach) + dataDisk.ManagedDisk.ID = diskID + } dataDisks = append(dataDisks, dataDisk) } - return dataDisks + return dataDisks, nil } func getVMIdentity(specVMIdentityID *string) *armcompute.VirtualMachineIdentity { diff --git a/pkg/azure/provider/helpers/resourcegraphprocessor.go b/pkg/azure/provider/helpers/resourcegraphprocessor.go index d82147b9..5ab024d6 100644 --- a/pkg/azure/provider/helpers/resourcegraphprocessor.go +++ b/pkg/azure/provider/helpers/resourcegraphprocessor.go @@ -119,7 +119,7 @@ func getDataDiskNameSuffixes(providerSpec api.AzureProviderSpec) sets.Set[string dataDiskNameSuffixes := sets.New[string]() dataDisks := providerSpec.Properties.StorageProfile.DataDisks for _, dataDisk := range dataDisks { - dataDiskNameSuffixes.Insert(utils.GetDataDiskNameSuffix(dataDisk)) + dataDiskNameSuffixes.Insert(utils.GetDataDiskNameSuffix(dataDisk.Name, dataDisk.Lun)) } return dataDiskNameSuffixes } diff --git a/pkg/azure/provider/provider.go b/pkg/azure/provider/provider.go index 220a2bb7..4ac12b22 100644 --- a/pkg/azure/provider/provider.go +++ b/pkg/azure/provider/provider.go @@ -69,6 +69,7 @@ func (d defaultDriver) CreateMachine(ctx context.Context, req *driver.CreateMach if err != nil { return } + subnet, err := helpers.GetSubnet(ctx, d.factory, connectConfig, providerSpec) if err != nil { return @@ -79,10 +80,18 @@ func (d defaultDriver) CreateMachine(ctx context.Context, req *driver.CreateMach return } - vm, err := helpers.CreateVM(ctx, d.factory, connectConfig, providerSpec, imageReference, plan, req.Secret, nicID, vmName) + // create disks with image ref since they can not be created together with the vm + // TODO parallelize creation with nic? + imageRefDiskIDs, err := helpers.CreateDisksWithImageRef(ctx, d.factory, connectConfig, providerSpec, vmName) + if err != nil { + return + } + + vm, err := helpers.CreateVM(ctx, d.factory, connectConfig, providerSpec, imageReference, plan, req.Secret, nicID, vmName, imageRefDiskIDs) if err != nil { return } + resp = helpers.ConstructCreateMachineResponse(providerSpec.Location, vmName) helpers.LogVMCreation(providerSpec.Location, providerSpec.ResourceGroup, vm) return diff --git a/pkg/azure/testhelp/fakes/machineresources.go b/pkg/azure/testhelp/fakes/machineresources.go index 2c84e85d..d3cc2b2b 100644 --- a/pkg/azure/testhelp/fakes/machineresources.go +++ b/pkg/azure/testhelp/fakes/machineresources.go @@ -6,7 +6,6 @@ package fakes import ( "fmt" - "strings" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" @@ -293,7 +292,7 @@ func createDataDiskResources(spec api.AzureProviderSpec, vmID *string, vmName st specDataDisks := spec.Properties.StorageProfile.DataDisks dataDisks := make(map[string]*armcompute.Disk, len(specDataDisks)) for _, specDataDisk := range specDataDisks { - diskName := utils.CreateDataDiskName(vmName, specDataDisk) + diskName := utils.CreateDataDiskName(vmName, specDataDisk.Name, specDataDisk.Lun) dataDisks[diskName] = createDiskResource(spec, diskName, vmID, nil) } return dataDisks @@ -374,31 +373,18 @@ func createVMResource(spec api.AzureProviderSpec, vmName string, plan *armcomput } func createImageReference(imageRef api.AzureImageReference) *armcompute.ImageReference { - var ( - id *string - publisher *string - sku *string - offer *string - version *string - ) if !utils.IsEmptyString(imageRef.ID) { - id = to.Ptr(imageRef.ID) + return &armcompute.ImageReference{ + ID: to.Ptr(imageRef.ID), + } } if !utils.IsNilOrEmptyStringPtr(imageRef.URN) { - urnParts := strings.Split(*imageRef.URN, ":") - publisher = to.Ptr(urnParts[0]) - offer = to.Ptr(urnParts[1]) - sku = to.Ptr(urnParts[2]) - version = to.Ptr(urnParts[3]) + urnImageRef := utils.ToImageReference(*imageRef.URN) + return &urnImageRef } return &armcompute.ImageReference{ CommunityGalleryImageID: imageRef.CommunityGalleryImageID, - ID: id, - Offer: offer, - Publisher: publisher, - SKU: sku, SharedGalleryImageID: imageRef.SharedGalleryImageID, - Version: version, } } @@ -440,7 +426,7 @@ func createDataDisks(spec api.AzureProviderSpec, vmName string, deleteOption *ar } dataDisks := make([]*armcompute.DataDisk, 0, len(specDataDisks)) for _, disk := range specDataDisks { - diskName := utils.CreateDataDiskName(vmName, disk) + diskName := utils.CreateDataDiskName(vmName, disk.Name, disk.Lun) d := createDataDisk(disk.Lun, armcompute.CachingTypes(disk.Caching), deleteOption, disk.DiskSizeGB, armcompute.StorageAccountTypes(disk.StorageAccountType), diskName) dataDisks = append(dataDisks, d) } diff --git a/pkg/azure/testhelp/providerspec.go b/pkg/azure/testhelp/providerspec.go index a44ba217..46620d52 100644 --- a/pkg/azure/testhelp/providerspec.go +++ b/pkg/azure/testhelp/providerspec.go @@ -191,7 +191,7 @@ func (b *ProviderSpecBuilder) Build() api.AzureProviderSpec { func CreateDataDiskNames(vmName string, spec api.AzureProviderSpec) []string { var diskNames []string for _, specDataDisk := range spec.Properties.StorageProfile.DataDisks { - diskNames = append(diskNames, utils.CreateDataDiskName(vmName, specDataDisk)) + diskNames = append(diskNames, utils.CreateDataDiskName(vmName, specDataDisk.Name, specDataDisk.Lun)) } return diskNames } diff --git a/pkg/azure/utils/images.go b/pkg/azure/utils/images.go new file mode 100644 index 00000000..f2be977a --- /dev/null +++ b/pkg/azure/utils/images.go @@ -0,0 +1,19 @@ +package utils + +import ( + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" +) + +// ToImageReference transforms an image urn string (publisher:offer:sku:version) into an ImageReference +func ToImageReference(urn string) armcompute.ImageReference { + urnParts := strings.Split(urn, ":") + return armcompute.ImageReference{ + Publisher: to.Ptr(urnParts[0]), + Offer: to.Ptr(urnParts[1]), + SKU: to.Ptr(urnParts[2]), + Version: to.Ptr(urnParts[3]), + } +} diff --git a/pkg/azure/utils/images_test.go b/pkg/azure/utils/images_test.go new file mode 100644 index 00000000..f4c9cb64 --- /dev/null +++ b/pkg/azure/utils/images_test.go @@ -0,0 +1,20 @@ +package utils + +import ( + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" + . "github.com/onsi/gomega" +) + +func TestToImageReference(t *testing.T) { + expected := armcompute.ImageReference{ + Publisher: to.Ptr("publisher"), + Offer: to.Ptr("offer"), + SKU: to.Ptr("sku"), + Version: to.Ptr("version"), + } + g := NewWithT(t) + g.Expect(ToImageReference("publisher:offer:sku:version")).To(Equal(expected)) +} diff --git a/pkg/azure/utils/names.go b/pkg/azure/utils/names.go index b977dfe6..d56a9d6c 100644 --- a/pkg/azure/utils/names.go +++ b/pkg/azure/utils/names.go @@ -6,8 +6,6 @@ package utils import ( "fmt" - - "github.com/gardener/machine-controller-manager-provider-azure/pkg/azure/api" ) const ( @@ -42,22 +40,21 @@ func CreateOSDiskName(vmName string) string { } // CreateDataDiskName creates a name for a DataDisk using VM name and data disk name specified in the provider Spec -func CreateDataDiskName(vmName string, dataDisk api.AzureDataDisk) string { +func CreateDataDiskName(vmName, diskName string, lun int32) string { prefix := vmName - suffix := GetDataDiskNameSuffix(dataDisk) + suffix := GetDataDiskNameSuffix(diskName, lun) return fmt.Sprintf("%s%s", prefix, suffix) } // GetDataDiskNameSuffix creates the suffix based on an optional data disk name and required lun fields. -func GetDataDiskNameSuffix(dataDisk api.AzureDataDisk) string { - infix := getDataDiskInfix(dataDisk) +func GetDataDiskNameSuffix(diskName string, lun int32) string { + infix := getDataDiskInfix(diskName, lun) return fmt.Sprintf("-%s%s", infix, DataDiskSuffix) } -func getDataDiskInfix(dataDisk api.AzureDataDisk) string { - name := dataDisk.Name - if IsEmptyString(name) { - return fmt.Sprintf("%d", dataDisk.Lun) +func getDataDiskInfix(diskName string, lun int32) string { + if IsEmptyString(diskName) { + return fmt.Sprintf("%d", lun) } - return fmt.Sprintf("%s-%d", name, dataDisk.Lun) + return fmt.Sprintf("%s-%d", diskName, lun) } diff --git a/pkg/azure/utils/names_test.go b/pkg/azure/utils/names_test.go index 2f0b0f0c..617d8c65 100644 --- a/pkg/azure/utils/names_test.go +++ b/pkg/azure/utils/names_test.go @@ -47,7 +47,7 @@ func TestCreateDataDiskName(t *testing.T) { Lun: entry.lun, DiskSizeGB: 10, } - g.Expect(CreateDataDiskName(vmName, dataDisk)).To(Equal(entry.expectedDataDiskName)) + g.Expect(CreateDataDiskName(vmName, dataDisk.Name, dataDisk.Lun)).To(Equal(entry.expectedDataDiskName)) }) } }