mirror of https://github.com/k3s-io/k3s
Merge pull request #74926 from ddebroy/csiprov2
Add new CSI translation APIs required by CSI sidecars and unit testspull/564/head
commit
d31427637b
|
@ -1355,7 +1355,7 @@ func (ctrl *PersistentVolumeController) getCSINameFromIntreeName(pluginName stri
|
||||||
if ctrl.csiNameFromIntreeNameHook != nil {
|
if ctrl.csiNameFromIntreeNameHook != nil {
|
||||||
return ctrl.csiNameFromIntreeNameHook(pluginName)
|
return ctrl.csiNameFromIntreeNameHook(pluginName)
|
||||||
}
|
}
|
||||||
return csitranslation.GetCSINameFromIntreeName(pluginName)
|
return csitranslation.GetCSINameFromInTreeName(pluginName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// provisionClaimOperation provisions a volume. This method is running in
|
// provisionClaimOperation provisions a volume. This method is running in
|
||||||
|
|
|
@ -440,7 +440,7 @@ func (og *operationGenerator) GenerateDetachVolumeFunc(
|
||||||
// TODO(dyzz): This case can't distinguish between PV and In-line which is necessary because
|
// TODO(dyzz): This case can't distinguish between PV and In-line which is necessary because
|
||||||
// if it was PV it may have been migrated, but the same plugin with in-line may not have been.
|
// if it was PV it may have been migrated, but the same plugin with in-line may not have been.
|
||||||
// Suggestions welcome...
|
// Suggestions welcome...
|
||||||
if csilib.IsMigratableByName(pluginName) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) {
|
if csilib.IsMigratableIntreePluginByName(pluginName) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) {
|
||||||
// The volume represented by this spec is CSI and thus should be migrated
|
// The volume represented by this spec is CSI and thus should be migrated
|
||||||
attachableVolumePlugin, err = og.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
|
attachableVolumePlugin, err = og.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
|
||||||
if err != nil || attachableVolumePlugin == nil {
|
if err != nil || attachableVolumePlugin == nil {
|
||||||
|
|
|
@ -108,3 +108,8 @@ func (t *awsElasticBlockStoreCSITranslator) CanSupport(pv *v1.PersistentVolume)
|
||||||
func (t *awsElasticBlockStoreCSITranslator) GetInTreePluginName() string {
|
func (t *awsElasticBlockStoreCSITranslator) GetInTreePluginName() string {
|
||||||
return AWSEBSInTreePluginName
|
return AWSEBSInTreePluginName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCSIPluginName returns the name of the CSI plugin
|
||||||
|
func (t *awsElasticBlockStoreCSITranslator) GetCSIPluginName() string {
|
||||||
|
return AWSEBSDriverName
|
||||||
|
}
|
||||||
|
|
|
@ -155,6 +155,11 @@ func (g *gcePersistentDiskCSITranslator) GetInTreePluginName() string {
|
||||||
return GCEPDInTreePluginName
|
return GCEPDInTreePluginName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCSIPluginName returns the name of the CSI plugin
|
||||||
|
func (g *gcePersistentDiskCSITranslator) GetCSIPluginName() string {
|
||||||
|
return GCEPDDriverName
|
||||||
|
}
|
||||||
|
|
||||||
func pdNameFromVolumeID(id string) (string, error) {
|
func pdNameFromVolumeID(id string) (string, error) {
|
||||||
splitID := strings.Split(id, "/")
|
splitID := strings.Split(id, "/")
|
||||||
if len(splitID) != volIDTotalElements {
|
if len(splitID) != volIDTotalElements {
|
||||||
|
|
|
@ -40,4 +40,7 @@ type InTreePlugin interface {
|
||||||
|
|
||||||
// GetInTreePluginName returns the in-tree plugin name this migrates
|
// GetInTreePluginName returns the in-tree plugin name this migrates
|
||||||
GetInTreePluginName() string
|
GetInTreePluginName() string
|
||||||
|
|
||||||
|
// GetCSIPluginName returns the name of the CSI plugin that supersedes the in-tree plugin
|
||||||
|
GetCSIPluginName() string
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,3 +96,8 @@ func (t *osCinderCSITranslator) CanSupport(pv *v1.PersistentVolume) bool {
|
||||||
func (t *osCinderCSITranslator) GetInTreePluginName() string {
|
func (t *osCinderCSITranslator) GetInTreePluginName() string {
|
||||||
return CinderInTreePluginName
|
return CinderInTreePluginName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCSIPluginName returns the name of the CSI plugin
|
||||||
|
func (t *osCinderCSITranslator) GetCSIPluginName() string {
|
||||||
|
return CinderDriverName
|
||||||
|
}
|
||||||
|
|
|
@ -75,19 +75,29 @@ func TranslateCSIPVToInTree(pv *v1.PersistentVolume) (*v1.PersistentVolume, erro
|
||||||
return nil, fmt.Errorf("could not find in-tree plugin translation logic for %s", copiedPV.Spec.CSI.Driver)
|
return nil, fmt.Errorf("could not find in-tree plugin translation logic for %s", copiedPV.Spec.CSI.Driver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMigratableByName tests whether there is Migration logic for the in-tree plugin
|
// IsMigratableIntreePluginByName tests whether there is migration logic for the in-tree plugin
|
||||||
// for the given `pluginName`
|
// whose name matches the given name
|
||||||
func IsMigratableByName(pluginName string) bool {
|
func IsMigratableIntreePluginByName(inTreePluginName string) bool {
|
||||||
for _, curPlugin := range inTreePlugins {
|
for _, curPlugin := range inTreePlugins {
|
||||||
if curPlugin.GetInTreePluginName() == pluginName {
|
if curPlugin.GetInTreePluginName() == inTreePluginName {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCSINameFromIntreeName maps the name of a CSI driver to its in-tree version
|
// IsMigratedCSIDriverByName tests whether there exists an in-tree plugin with logic
|
||||||
func GetCSINameFromIntreeName(pluginName string) (string, error) {
|
// to migrate to the CSI driver with given name
|
||||||
|
func IsMigratedCSIDriverByName(csiPluginName string) bool {
|
||||||
|
if _, ok := inTreePlugins[csiPluginName]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCSINameFromInTreeName returns the name of a CSI driver that supersedes the
|
||||||
|
// in-tree plugin with the given name
|
||||||
|
func GetCSINameFromInTreeName(pluginName string) (string, error) {
|
||||||
for csiDriverName, curPlugin := range inTreePlugins {
|
for csiDriverName, curPlugin := range inTreePlugins {
|
||||||
if curPlugin.GetInTreePluginName() == pluginName {
|
if curPlugin.GetInTreePluginName() == pluginName {
|
||||||
return csiDriverName, nil
|
return csiDriverName, nil
|
||||||
|
@ -96,7 +106,16 @@ func GetCSINameFromIntreeName(pluginName string) (string, error) {
|
||||||
return "", fmt.Errorf("Could not find CSI Driver name for plugin %v", pluginName)
|
return "", fmt.Errorf("Could not find CSI Driver name for plugin %v", pluginName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPVMigratable tests whether there is Migration logic for the given Persistent Volume
|
// GetInTreeNameFromCSIName returns the name of the in-tree plugin superseded by
|
||||||
|
// a CSI driver with the given name
|
||||||
|
func GetInTreeNameFromCSIName(pluginName string) (string, error) {
|
||||||
|
if plugin, ok := inTreePlugins[pluginName]; ok {
|
||||||
|
return plugin.GetInTreePluginName(), nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("Could not find In-Tree driver name for CSI plugin %v", pluginName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPVMigratable tests whether there is migration logic for the given Persistent Volume
|
||||||
func IsPVMigratable(pv *v1.PersistentVolume) bool {
|
func IsPVMigratable(pv *v1.PersistentVolume) bool {
|
||||||
for _, curPlugin := range inTreePlugins {
|
for _, curPlugin := range inTreePlugins {
|
||||||
if curPlugin.CanSupport(pv) {
|
if curPlugin.CanSupport(pv) {
|
||||||
|
|
|
@ -76,4 +76,43 @@ func TestTranslationStability(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPluginNameMappings(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
inTreePluginName string
|
||||||
|
csiPluginName string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "GCE PD plugin name",
|
||||||
|
inTreePluginName: "kubernetes.io/gce-pd",
|
||||||
|
csiPluginName: "pd.csi.storage.gke.io",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "AWS EBS plugin name",
|
||||||
|
inTreePluginName: "kubernetes.io/aws-ebs",
|
||||||
|
csiPluginName: "ebs.csi.aws.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Logf("Testing %v", test.name)
|
||||||
|
csiPluginName, err := GetCSINameFromInTreeName(test.inTreePluginName)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error when mapping In-tree plugin name to CSI plugin name %s", err)
|
||||||
|
}
|
||||||
|
if !IsMigratedCSIDriverByName(csiPluginName) {
|
||||||
|
t.Errorf("%s expected to supersede an In-tree plugin", csiPluginName)
|
||||||
|
}
|
||||||
|
inTreePluginName, err := GetInTreeNameFromCSIName(csiPluginName)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Error when mapping CSI plugin name to In-tree plugin name %s", err)
|
||||||
|
}
|
||||||
|
if !IsMigratableIntreePluginByName(inTreePluginName) {
|
||||||
|
t.Errorf("%s expected to be migratable to a CSI name", inTreePluginName)
|
||||||
|
}
|
||||||
|
if inTreePluginName != test.inTreePluginName || csiPluginName != test.csiPluginName {
|
||||||
|
t.Errorf("CSI plugin name and In-tree plugin name do not map to each other: [%s => %s], [%s => %s]", test.csiPluginName, inTreePluginName, test.inTreePluginName, csiPluginName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: test for not modifying the original PV.
|
// TODO: test for not modifying the original PV.
|
||||||
|
|
Loading…
Reference in New Issue