Code change:
return err } <del> // GetDiskLun finds the lun on the host that the vhd is attached to, given a vhd's diskName and diskURI func (ss *scaleSet) GetDiskLun(diskName, diskURI string, nodeName types.NodeName) (int32, error) { </del> <ins> // GetDataDisks gets a list of data disks attached to the node. func (ss *scaleSet) GetDataDisks(nodeName types.NodeName) ([]compute.DataDisk, error) { </ins> _, _, vm, err := ss.getVmssVM(string(nodeName)) if err != nil { <del> return -1, err </del> <ins> return nil, err </ins> } <del> disks := *vm.StorageProfile.DataDisks for _, disk := range disks { if disk.Lun != nil && (disk.Name != nil && diskName != "" && *disk.Name == diskName) || (disk.Vhd != nil && disk.Vhd.URI != nil && diskURI != "" && *disk.Vhd.URI == diskURI) || (disk.ManagedDisk != nil && *disk.ManagedDisk.ID == diskURI) { // found the disk glog.V(4).Infof("azureDisk - find disk: lun %d name %q uri %q", *disk.Lun, diskName, diskURI) return *disk.Lun, nil } } return -1, fmt.Errorf("Cannot find Lun for disk %s", diskName) } // GetNextDiskLun searches all vhd attachment on the host and find unused lun // return -1 if all luns are used func (ss *scaleSet) GetNextDiskLun(nodeName types.NodeName) (int32, error) { _, _, vm, err := ss.getVmssVM(string(nodeName)) if err != nil { return -1, err } used := make([]bool, maxLUN) disks := *vm.StorageProfile.DataDisks for _, disk := range disks { if disk.Lun != nil { used[*disk.Lun] = true } } for k, v := range used { if !v { return int32(k), nil } } return -1, fmt.Errorf("All Luns are used") } // DisksAreAttached checks if a list of volumes are attached to the node with the specified NodeName func (ss *scaleSet) DisksAreAttached(diskNames []string, nodeName types.NodeName) (map[string]bool, error) { attached := make(map[string]bool) for _, diskName := range diskNames { attached[diskName] = false } _, _, vm, err := ss.getVmssVM(string(nodeName)) if err != nil { if err == cloudprovider.InstanceNotFound { // if host doesn't exist, no need to detach glog.Warningf("azureDisk - Cannot find node %q, DisksAreAttached will assume disks %v are not attached to it.", nodeName, diskNames) return attached, nil } return attached, err } disks := *vm.StorageProfile.DataDisks for _, disk := range disks { for _, diskName := range diskNames { if disk.Name != nil && diskName != "" && *disk.Name == diskName { attached[diskName] = true } } </del> <ins> if vm.StorageProfile.DataDisks == nil { return nil, nil </ins> } <del> return attached, nil </del> <ins> return *vm.StorageProfile.DataDisks, nil </ins> }

Related discussion:
text: <!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: /kind cleanup What happened: VirtualMachineScaleSetVM and VirtualMachine are different data structures (because of different API versions), so the disk attach operation seems duplicate between vm and vmss. That means although disk operations are in same logic, some duplication are still required now. They should use same api version in the future and should be merged into same code base, e.g. move sharing logic to Refer What you expected to happen: vmss and vm disk operations should share same code logic. How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: Environment: Kubernetes version (use ): Cloud provider or hardware configuration: OS (e.g. from /etc/os-release): Kernel (e.g. ): Install tools: Others:
I have checked with currently we can’t merge, e.g. following two structs are different since they using different sdk-for-azure versions. While in the end when sdk-for-azure version is upgraded, above two versions should be same and at that time, we should merge functions like ‘AttachDisk’, ‘DetachDiskByName’, 'GetDiskLun', GetNextDiskLun, DisksAreAttached