mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Merge pull request #108611 from divyenpatel/add-csi-topology-translation-for-in-tree-vSphere-volumes
topology translation of in-tree vSphere volume to vSphere CSI
This commit is contained in:
commit
dd2596e40d
@ -32,6 +32,12 @@ const (
|
|||||||
// VSphereInTreePluginName is the name of the in-tree plugin for vSphere Volume
|
// VSphereInTreePluginName is the name of the in-tree plugin for vSphere Volume
|
||||||
VSphereInTreePluginName = "kubernetes.io/vsphere-volume"
|
VSphereInTreePluginName = "kubernetes.io/vsphere-volume"
|
||||||
|
|
||||||
|
// vSphereCSITopologyZoneKey is the zonal topology key for vSphere CSI Driver
|
||||||
|
vSphereCSITopologyZoneKey = "topology.csi.vmware.com/zone"
|
||||||
|
|
||||||
|
// vSphereCSITopologyRegionKey is the region topology key for vSphere CSI Driver
|
||||||
|
vSphereCSITopologyRegionKey = "topology.csi.vmware.com/region"
|
||||||
|
|
||||||
// paramStoragePolicyName used to supply SPBM Policy name for Volume provisioning
|
// paramStoragePolicyName used to supply SPBM Policy name for Volume provisioning
|
||||||
paramStoragePolicyName = "storagepolicyname"
|
paramStoragePolicyName = "storagepolicyname"
|
||||||
|
|
||||||
@ -104,7 +110,14 @@ func (t *vSphereCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.Stor
|
|||||||
// When this is true, Driver returns initialvolumefilepath in the VolumeContext, which is
|
// When this is true, Driver returns initialvolumefilepath in the VolumeContext, which is
|
||||||
// used in TranslateCSIPVToInTree
|
// used in TranslateCSIPVToInTree
|
||||||
params[paramcsiMigration] = "true"
|
params[paramcsiMigration] = "true"
|
||||||
// Note: sc.AllowedTopologies for Topology based volume provisioning will be supplied as it is.
|
// translate AllowedTopologies to vSphere CSI Driver topology
|
||||||
|
if len(sc.AllowedTopologies) > 0 {
|
||||||
|
newTopologies, err := translateAllowedTopologies(sc.AllowedTopologies, vSphereCSITopologyZoneKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed translating allowed topologies: %v", err)
|
||||||
|
}
|
||||||
|
sc.AllowedTopologies = newTopologies
|
||||||
|
}
|
||||||
sc.Parameters = params
|
sc.Parameters = params
|
||||||
return sc, nil
|
return sc, nil
|
||||||
}
|
}
|
||||||
@ -154,6 +167,10 @@ func (t *vSphereCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (
|
|||||||
if pv.Spec.VsphereVolume.StoragePolicyName != "" {
|
if pv.Spec.VsphereVolume.StoragePolicyName != "" {
|
||||||
csiSource.VolumeAttributes[paramStoragePolicyName] = pv.Spec.VsphereVolume.StoragePolicyName
|
csiSource.VolumeAttributes[paramStoragePolicyName] = pv.Spec.VsphereVolume.StoragePolicyName
|
||||||
}
|
}
|
||||||
|
// translate in-tree topology to CSI topology for migration
|
||||||
|
if err := translateTopologyFromInTreevSphereToCSI(pv, vSphereCSITopologyZoneKey, vSphereCSITopologyRegionKey); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to translate topology: %v", err)
|
||||||
|
}
|
||||||
pv.Spec.VsphereVolume = nil
|
pv.Spec.VsphereVolume = nil
|
||||||
pv.Spec.CSI = csiSource
|
pv.Spec.CSI = csiSource
|
||||||
return pv, nil
|
return pv, nil
|
||||||
@ -173,6 +190,10 @@ func (t *vSphereCSITranslator) TranslateCSIPVToInTree(pv *v1.PersistentVolume) (
|
|||||||
if ok {
|
if ok {
|
||||||
vsphereVirtualDiskVolumeSource.VolumePath = volumeFilePath
|
vsphereVirtualDiskVolumeSource.VolumePath = volumeFilePath
|
||||||
}
|
}
|
||||||
|
// translate CSI topology to In-tree topology for rollback compatibility.
|
||||||
|
if err := translateTopologyFromCSIToInTreevSphere(pv, vSphereCSITopologyZoneKey, vSphereCSITopologyRegionKey); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to translate topology. PV:%+v. Error:%v", *pv, err)
|
||||||
|
}
|
||||||
pv.Spec.CSI = nil
|
pv.Spec.CSI = nil
|
||||||
pv.Spec.VsphereVolume = vsphereVirtualDiskVolumeSource
|
pv.Spec.VsphereVolume = vsphereVirtualDiskVolumeSource
|
||||||
return pv, nil
|
return pv, nil
|
||||||
@ -206,3 +227,76 @@ func (t *vSphereCSITranslator) GetCSIPluginName() string {
|
|||||||
func (t *vSphereCSITranslator) RepairVolumeHandle(volumeHandle, nodeID string) (string, error) {
|
func (t *vSphereCSITranslator) RepairVolumeHandle(volumeHandle, nodeID string) (string, error) {
|
||||||
return volumeHandle, nil
|
return volumeHandle, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// translateTopologyFromInTreevSphereToCSI converts existing zone labels or in-tree vsphere topology to
|
||||||
|
// vSphere CSI topology.
|
||||||
|
func translateTopologyFromInTreevSphereToCSI(pv *v1.PersistentVolume, csiTopologyKeyZone string, csiTopologyKeyRegion string) error {
|
||||||
|
zoneLabel, regionLabel := getTopologyLabel(pv)
|
||||||
|
|
||||||
|
// If Zone kubernetes topology exist, replace it to use csiTopologyKeyZone
|
||||||
|
zones := getTopologyValues(pv, zoneLabel)
|
||||||
|
if len(zones) > 0 {
|
||||||
|
replaceTopology(pv, zoneLabel, csiTopologyKeyZone)
|
||||||
|
} else {
|
||||||
|
// if nothing is in the NodeAffinity, try to fetch the topology from PV labels
|
||||||
|
if label, ok := pv.Labels[zoneLabel]; ok {
|
||||||
|
if len(label) > 0 {
|
||||||
|
addTopology(pv, csiTopologyKeyZone, []string{label})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If region kubernetes topology exist, replace it to use csiTopologyKeyRegion
|
||||||
|
regions := getTopologyValues(pv, regionLabel)
|
||||||
|
if len(regions) > 0 {
|
||||||
|
replaceTopology(pv, regionLabel, csiTopologyKeyRegion)
|
||||||
|
} else {
|
||||||
|
// if nothing is in the NodeAffinity, try to fetch the topology from PV labels
|
||||||
|
if label, ok := pv.Labels[regionLabel]; ok {
|
||||||
|
if len(label) > 0 {
|
||||||
|
addTopology(pv, csiTopologyKeyRegion, []string{label})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// translateTopologyFromCSIToInTreevSphere converts CSI zone/region affinity rules to in-tree vSphere zone/region labels
|
||||||
|
func translateTopologyFromCSIToInTreevSphere(pv *v1.PersistentVolume,
|
||||||
|
csiTopologyKeyZone string, csiTopologyKeyRegion string) error {
|
||||||
|
zoneLabel, regionLabel := getTopologyLabel(pv)
|
||||||
|
|
||||||
|
// Replace all CSI topology to Kubernetes Zone label
|
||||||
|
err := replaceTopology(pv, csiTopologyKeyZone, zoneLabel)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to replace CSI topology to Kubernetes topology, error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace all CSI topology to Kubernetes Region label
|
||||||
|
err = replaceTopology(pv, csiTopologyKeyRegion, regionLabel)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to replace CSI topology to Kubernetes topology, error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
zoneVals := getTopologyValues(pv, zoneLabel)
|
||||||
|
if len(zoneVals) > 0 {
|
||||||
|
if pv.Labels == nil {
|
||||||
|
pv.Labels = make(map[string]string)
|
||||||
|
}
|
||||||
|
_, zoneOK := pv.Labels[zoneLabel]
|
||||||
|
if !zoneOK {
|
||||||
|
pv.Labels[zoneLabel] = zoneVals[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
regionVals := getTopologyValues(pv, regionLabel)
|
||||||
|
if len(regionVals) > 0 {
|
||||||
|
if pv.Labels == nil {
|
||||||
|
pv.Labels = make(map[string]string)
|
||||||
|
}
|
||||||
|
_, regionOK := pv.Labels[regionLabel]
|
||||||
|
if !regionOK {
|
||||||
|
pv.Labels[regionLabel] = regionVals[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -33,19 +33,17 @@ func TestTranslatevSphereInTreeStorageClassToCSI(t *testing.T) {
|
|||||||
Key: v1.LabelTopologyZone,
|
Key: v1.LabelTopologyZone,
|
||||||
Values: []string{"zone-a"},
|
Values: []string{"zone-a"},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Key: v1.LabelTopologyRegion,
|
|
||||||
Values: []string{"region-a"},
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
topologySelectorTermWithBetaLabels := v1.TopologySelectorTerm{[]v1.TopologySelectorLabelRequirement{
|
topologySelectorTermWithBetaLabels := v1.TopologySelectorTerm{[]v1.TopologySelectorLabelRequirement{
|
||||||
{
|
{
|
||||||
Key: v1.LabelFailureDomainBetaZone,
|
Key: v1.LabelFailureDomainBetaZone,
|
||||||
Values: []string{"zone-a"},
|
Values: []string{"zone-a"},
|
||||||
},
|
},
|
||||||
|
}}
|
||||||
|
expectedTopologySelectorTerm := v1.TopologySelectorTerm{[]v1.TopologySelectorLabelRequirement{
|
||||||
{
|
{
|
||||||
Key: v1.LabelFailureDomainBetaRegion,
|
Key: vSphereCSITopologyZoneKey,
|
||||||
Values: []string{"region-a"},
|
Values: []string{"zone-a"},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
@ -88,27 +86,27 @@ func TestTranslatevSphereInTreeStorageClassToCSI(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "translate with no parameter and allowedTopology",
|
name: "translate with no parameter and allowedTopology",
|
||||||
sc: NewStorageClass(map[string]string{}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
sc: NewStorageClass(map[string]string{}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
||||||
expSc: NewStorageClass(map[string]string{paramcsiMigration: "true"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
expSc: NewStorageClass(map[string]string{paramcsiMigration: "true"}, []v1.TopologySelectorTerm{expectedTopologySelectorTerm}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "translate with storagepolicyname and allowedTopology",
|
name: "translate with storagepolicyname and allowedTopology",
|
||||||
sc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
sc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
||||||
expSc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name", paramcsiMigration: "true"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
expSc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name", paramcsiMigration: "true"}, []v1.TopologySelectorTerm{expectedTopologySelectorTerm}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "translate with storagepolicyname and allowedTopology beta labels",
|
name: "translate with storagepolicyname and allowedTopology beta labels",
|
||||||
sc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name"}, []v1.TopologySelectorTerm{topologySelectorTermWithBetaLabels}),
|
sc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name"}, []v1.TopologySelectorTerm{topologySelectorTermWithBetaLabels}),
|
||||||
expSc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name", paramcsiMigration: "true"}, []v1.TopologySelectorTerm{topologySelectorTermWithBetaLabels}),
|
expSc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name", paramcsiMigration: "true"}, []v1.TopologySelectorTerm{expectedTopologySelectorTerm}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "translate with raw vSAN policy parameters, datastore and diskformat",
|
name: "translate with raw vSAN policy parameters, datastore and diskformat",
|
||||||
sc: NewStorageClass(map[string]string{"hostfailurestotolerate": "2", "datastore": "vsanDatastore", "diskformat": "thin"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
sc: NewStorageClass(map[string]string{"hostfailurestotolerate": "2", "datastore": "vsanDatastore", "diskformat": "thin"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
||||||
expSc: NewStorageClass(map[string]string{"hostfailurestotolerate-migrationparam": "2", "datastore-migrationparam": "vsanDatastore", "diskformat-migrationparam": "thin", paramcsiMigration: "true"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
expSc: NewStorageClass(map[string]string{"hostfailurestotolerate-migrationparam": "2", "datastore-migrationparam": "vsanDatastore", "diskformat-migrationparam": "thin", paramcsiMigration: "true"}, []v1.TopologySelectorTerm{expectedTopologySelectorTerm}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "translate with all parameters",
|
name: "translate with all parameters",
|
||||||
sc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name", "datastore": "test-datastore-name", "fstype": "ext4", "diskformat": "thin", "hostfailurestotolerate": "1", "forceprovisioning": "yes", "cachereservation": "25", "diskstripes": "4", "objectspacereservation": "10", "iopslimit": "32"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
sc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name", "datastore": "test-datastore-name", "fstype": "ext4", "diskformat": "thin", "hostfailurestotolerate": "1", "forceprovisioning": "yes", "cachereservation": "25", "diskstripes": "4", "objectspacereservation": "10", "iopslimit": "32"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
||||||
expSc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name", "datastore-migrationparam": "test-datastore-name", "csi.storage.k8s.io/fstype": "ext4", "diskformat-migrationparam": "thin", "hostfailurestotolerate-migrationparam": "1", "forceprovisioning-migrationparam": "yes", "cachereservation-migrationparam": "25", "diskstripes-migrationparam": "4", "objectspacereservation-migrationparam": "10", "iopslimit-migrationparam": "32", paramcsiMigration: "true"}, []v1.TopologySelectorTerm{topologySelectorTerm}),
|
expSc: NewStorageClass(map[string]string{"storagepolicyname": "test-policy-name", "datastore-migrationparam": "test-datastore-name", "csi.storage.k8s.io/fstype": "ext4", "diskformat-migrationparam": "thin", "hostfailurestotolerate-migrationparam": "1", "forceprovisioning-migrationparam": "yes", "cachereservation-migrationparam": "25", "diskstripes-migrationparam": "4", "objectspacereservation-migrationparam": "10", "iopslimit-migrationparam": "32", paramcsiMigration: "true"}, []v1.TopologySelectorTerm{expectedTopologySelectorTerm}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
@ -194,6 +192,84 @@ func TestTranslateVSphereCSIPVToInTree(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expErr: false,
|
expErr: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "translate valid vSphere CSI PV with topology Node Affinity rules to vSphere CSI PV with topology labels",
|
||||||
|
csiPV: &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pvc-d8b4475f-2c47-486e-9b57-43ae006f9b59",
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||||
|
CSI: &v1.CSIPersistentVolumeSource{
|
||||||
|
Driver: VSphereDriverName,
|
||||||
|
VolumeHandle: "e4073a6d-642e-4dff-8f4a-b4e3a47c4bbd",
|
||||||
|
FSType: "ext4",
|
||||||
|
VolumeAttributes: map[string]string{
|
||||||
|
paramStoragePolicyName: "vSAN Default Storage Policy",
|
||||||
|
AttributeInitialVolumeFilepath: "[vsanDatastore] 6785a85e-268e-6352-a2e8-02008b7afadd/kubernetes-dynamic-pvc-68734c9f-a679-42e6-a694-39632c51e31f.vmdk",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
|
NodeAffinity: &v1.VolumeNodeAffinity{
|
||||||
|
Required: &v1.NodeSelector{
|
||||||
|
NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
|
{
|
||||||
|
MatchExpressions: []v1.NodeSelectorRequirement{
|
||||||
|
{
|
||||||
|
Key: "topology.csi.vmware.com/zone",
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"z1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "topology.csi.vmware.com/region",
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"r1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
intreePV: &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pvc-d8b4475f-2c47-486e-9b57-43ae006f9b59",
|
||||||
|
Labels: map[string]string{"topology.kubernetes.io/zone": "z1", "topology.kubernetes.io/region": "r1"},
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||||
|
VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{
|
||||||
|
VolumePath: "[vsanDatastore] 6785a85e-268e-6352-a2e8-02008b7afadd/kubernetes-dynamic-pvc-68734c9f-a679-42e6-a694-39632c51e31f.vmdk",
|
||||||
|
FSType: "ext4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
|
NodeAffinity: &v1.VolumeNodeAffinity{
|
||||||
|
Required: &v1.NodeSelector{
|
||||||
|
NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
|
{
|
||||||
|
MatchExpressions: []v1.NodeSelectorRequirement{
|
||||||
|
{
|
||||||
|
Key: "topology.kubernetes.io/zone",
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"z1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "topology.kubernetes.io/region",
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"r1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expErr: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
@ -264,6 +340,124 @@ func TestTranslateVSphereInTreePVToCSI(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expErr: false,
|
expErr: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "translate valid vSphere in-tree PV with beta topology labels to vSphere CSI PV",
|
||||||
|
intreePV: &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pvc-d8b4475f-2c47-486e-9b57-43ae006f9b59",
|
||||||
|
Labels: map[string]string{"failure-domain.beta.kubernetes.io/zone": "z1", "failure-domain.beta.kubernetes.io/region": "r1"},
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||||
|
VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{
|
||||||
|
VolumePath: "[vsanDatastore] 6785a85e-268e-6352-a2e8-02008b7afadd/kubernetes-dynamic-pvc-68734c9f-a679-42e6-a694-39632c51e31f.vmdk",
|
||||||
|
FSType: "ext4",
|
||||||
|
StoragePolicyName: "vSAN Default Storage Policy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
csiPV: &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pvc-d8b4475f-2c47-486e-9b57-43ae006f9b59",
|
||||||
|
Labels: map[string]string{"failure-domain.beta.kubernetes.io/zone": "z1", "failure-domain.beta.kubernetes.io/region": "r1"},
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||||
|
CSI: &v1.CSIPersistentVolumeSource{
|
||||||
|
Driver: VSphereDriverName,
|
||||||
|
VolumeHandle: "[vsanDatastore] 6785a85e-268e-6352-a2e8-02008b7afadd/kubernetes-dynamic-pvc-68734c9f-a679-42e6-a694-39632c51e31f.vmdk",
|
||||||
|
FSType: "ext4",
|
||||||
|
VolumeAttributes: map[string]string{
|
||||||
|
paramStoragePolicyName: "vSAN Default Storage Policy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
|
NodeAffinity: &v1.VolumeNodeAffinity{
|
||||||
|
Required: &v1.NodeSelector{
|
||||||
|
NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
|
{
|
||||||
|
MatchExpressions: []v1.NodeSelectorRequirement{
|
||||||
|
{
|
||||||
|
Key: "topology.csi.vmware.com/zone",
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"z1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "topology.csi.vmware.com/region",
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"r1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "translate valid vSphere in-tree PV with GA topology labels to vSphere CSI PV",
|
||||||
|
intreePV: &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pvc-d8b4475f-2c47-486e-9b57-43ae006f9b59",
|
||||||
|
Labels: map[string]string{"topology.kubernetes.io/zone": "z1", "topology.kubernetes.io/region": "r1"},
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||||
|
VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{
|
||||||
|
VolumePath: "[vsanDatastore] 6785a85e-268e-6352-a2e8-02008b7afadd/kubernetes-dynamic-pvc-68734c9f-a679-42e6-a694-39632c51e31f.vmdk",
|
||||||
|
FSType: "ext4",
|
||||||
|
StoragePolicyName: "vSAN Default Storage Policy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
csiPV: &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pvc-d8b4475f-2c47-486e-9b57-43ae006f9b59",
|
||||||
|
Labels: map[string]string{"topology.kubernetes.io/zone": "z1", "topology.kubernetes.io/region": "r1"},
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||||
|
CSI: &v1.CSIPersistentVolumeSource{
|
||||||
|
Driver: VSphereDriverName,
|
||||||
|
VolumeHandle: "[vsanDatastore] 6785a85e-268e-6352-a2e8-02008b7afadd/kubernetes-dynamic-pvc-68734c9f-a679-42e6-a694-39632c51e31f.vmdk",
|
||||||
|
FSType: "ext4",
|
||||||
|
VolumeAttributes: map[string]string{
|
||||||
|
paramStoragePolicyName: "vSAN Default Storage Policy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
|
NodeAffinity: &v1.VolumeNodeAffinity{
|
||||||
|
Required: &v1.NodeSelector{
|
||||||
|
NodeSelectorTerms: []v1.NodeSelectorTerm{
|
||||||
|
{
|
||||||
|
MatchExpressions: []v1.NodeSelectorRequirement{
|
||||||
|
{
|
||||||
|
Key: "topology.csi.vmware.com/zone",
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"z1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "topology.csi.vmware.com/region",
|
||||||
|
Operator: v1.NodeSelectorOpIn,
|
||||||
|
Values: []string{"r1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expErr: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
|
Loading…
Reference in New Issue
Block a user