Merge pull request #91196 from andyzhangx/azuredisk-migration-topology

fix: topology translation issue in azure disk storage class migration
This commit is contained in:
Kubernetes Prow Robot 2020-05-26 19:12:55 -07:00 committed by GitHub
commit aba339c63a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 0 deletions

View File

@ -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
}

View File

@ -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)
}
}
}