diff --git a/staging/src/k8s.io/csi-translation-lib/plugins/azure_disk.go b/staging/src/k8s.io/csi-translation-lib/plugins/azure_disk.go index 1ccef2b68a4..8184881de9d 100644 --- a/staging/src/k8s.io/csi-translation-lib/plugins/azure_disk.go +++ b/staging/src/k8s.io/csi-translation-lib/plugins/azure_disk.go @@ -29,6 +29,8 @@ import ( const ( // AzureDiskDriverName is the name of the CSI driver for Azure Disk AzureDiskDriverName = "disk.csi.azure.com" + // AzureDiskTopologyKey is the topology key of Azure Disk CSI driver + AzureDiskTopologyKey = "topology.disk.csi.azure.com/zone" // AzureDiskInTreePluginName is the name of the intree plugin for Azure Disk AzureDiskInTreePluginName = "kubernetes.io/azure-disk" @@ -57,6 +59,35 @@ func NewAzureDiskCSITranslator() InTreePlugin { // TranslateInTreeStorageClassParametersToCSI translates InTree Azure Disk storage class parameters to CSI storage class func (t *azureDiskCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.StorageClass) (*storage.StorageClass, error) { + var ( + generatedTopologies []v1.TopologySelectorTerm + params = map[string]string{} + ) + for k, v := range sc.Parameters { + switch strings.ToLower(k) { + case zoneKey: + generatedTopologies = generateToplogySelectors(AzureDiskTopologyKey, []string{v}) + case zonesKey: + generatedTopologies = generateToplogySelectors(AzureDiskTopologyKey, strings.Split(v, ",")) + default: + params[k] = v + } + } + + if len(generatedTopologies) > 0 && len(sc.AllowedTopologies) > 0 { + return nil, fmt.Errorf("cannot simultaneously set allowed topologies and zone/zones parameters") + } else if len(generatedTopologies) > 0 { + sc.AllowedTopologies = generatedTopologies + } else if len(sc.AllowedTopologies) > 0 { + newTopologies, err := translateAllowedTopologies(sc.AllowedTopologies, AzureDiskTopologyKey) + if err != nil { + return nil, fmt.Errorf("failed translating allowed topologies: %v", err) + } + sc.AllowedTopologies = newTopologies + } + + sc.Parameters = params + return sc, nil } diff --git a/staging/src/k8s.io/csi-translation-lib/plugins/azure_disk_test.go b/staging/src/k8s.io/csi-translation-lib/plugins/azure_disk_test.go index a64bc746e18..ac78be23f3a 100644 --- a/staging/src/k8s.io/csi-translation-lib/plugins/azure_disk_test.go +++ b/staging/src/k8s.io/csi-translation-lib/plugins/azure_disk_test.go @@ -22,6 +22,8 @@ import ( "testing" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + storage "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -230,3 +232,64 @@ func TestTranslateAzureDiskInTreePVToCSI(t *testing.T) { } } } + +func TestTranslateInTreeStorageClassToCSI(t *testing.T) { + translator := NewAzureDiskCSITranslator() + + tcs := []struct { + name string + options *storage.StorageClass + expOptions *storage.StorageClass + expErr bool + }{ + { + name: "nothing special", + options: NewStorageClass(map[string]string{"foo": "bar"}, nil), + expOptions: NewStorageClass(map[string]string{"foo": "bar"}, nil), + }, + { + name: "empty params", + options: NewStorageClass(map[string]string{}, nil), + expOptions: NewStorageClass(map[string]string{}, nil), + }, + { + name: "zone", + options: NewStorageClass(map[string]string{"zone": "foo"}, nil), + expOptions: NewStorageClass(map[string]string{}, generateToplogySelectors(AzureDiskTopologyKey, []string{"foo"})), + }, + { + name: "zones", + options: NewStorageClass(map[string]string{"zones": "foo,bar,baz"}, nil), + expOptions: NewStorageClass(map[string]string{}, generateToplogySelectors(AzureDiskTopologyKey, []string{"foo", "bar", "baz"})), + }, + { + name: "some normal topology", + options: NewStorageClass(map[string]string{}, generateToplogySelectors(AzureDiskTopologyKey, []string{"foo"})), + expOptions: NewStorageClass(map[string]string{}, generateToplogySelectors(AzureDiskTopologyKey, []string{"foo"})), + }, + { + name: "some translated topology", + options: NewStorageClass(map[string]string{}, generateToplogySelectors(v1.LabelZoneFailureDomain, []string{"foo"})), + expOptions: NewStorageClass(map[string]string{}, generateToplogySelectors(AzureDiskTopologyKey, []string{"foo"})), + }, + { + name: "zone and topology", + options: NewStorageClass(map[string]string{"zone": "foo"}, generateToplogySelectors(AzureDiskTopologyKey, []string{"foo"})), + expErr: true, + }, + } + + for _, tc := range tcs { + t.Logf("Testing %v", tc.name) + gotOptions, err := translator.TranslateInTreeStorageClassToCSI(tc.options) + if err != nil && !tc.expErr { + t.Errorf("Did not expect error but got: %v", err) + } + if err == nil && tc.expErr { + t.Errorf("Expected error, but did not get one.") + } + if !reflect.DeepEqual(gotOptions, tc.expOptions) { + t.Errorf("Got parameters: %v, expected :%v", gotOptions, tc.expOptions) + } + } +}