...
1
16
17 package csimigration
18
19 import (
20 "errors"
21 "fmt"
22
23 v1 "k8s.io/api/core/v1"
24 "k8s.io/component-base/featuregate"
25 csilibplugins "k8s.io/csi-translation-lib/plugins"
26 "k8s.io/kubernetes/pkg/features"
27 "k8s.io/kubernetes/pkg/volume"
28 )
29
30
31
32 type PluginNameMapper interface {
33 GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error)
34 GetCSINameFromInTreeName(pluginName string) (string, error)
35 }
36
37
38 type PluginManager struct {
39 PluginNameMapper
40 featureGate featuregate.FeatureGate
41 }
42
43
44 func NewPluginManager(m PluginNameMapper, featureGate featuregate.FeatureGate) PluginManager {
45 return PluginManager{
46 PluginNameMapper: m,
47 featureGate: featureGate,
48 }
49 }
50
51
52
53
54
55 func (pm PluginManager) IsMigrationCompleteForPlugin(pluginName string) bool {
56
57
58 if !pm.IsMigrationEnabledForPlugin(pluginName) {
59 return false
60 }
61
62 switch pluginName {
63 case csilibplugins.AWSEBSInTreePluginName:
64 return pm.featureGate.Enabled(features.InTreePluginAWSUnregister)
65 case csilibplugins.GCEPDInTreePluginName:
66 return pm.featureGate.Enabled(features.InTreePluginGCEUnregister)
67 case csilibplugins.AzureFileInTreePluginName:
68 return pm.featureGate.Enabled(features.InTreePluginAzureFileUnregister)
69 case csilibplugins.AzureDiskInTreePluginName:
70 return pm.featureGate.Enabled(features.InTreePluginAzureDiskUnregister)
71 case csilibplugins.CinderInTreePluginName:
72 return pm.featureGate.Enabled(features.InTreePluginOpenStackUnregister)
73 case csilibplugins.VSphereInTreePluginName:
74 return pm.featureGate.Enabled(features.InTreePluginvSphereUnregister)
75 case csilibplugins.PortworxVolumePluginName:
76 return pm.featureGate.Enabled(features.InTreePluginPortworxUnregister)
77 case csilibplugins.RBDVolumePluginName:
78 return pm.featureGate.Enabled(features.InTreePluginRBDUnregister)
79 default:
80 return false
81 }
82 }
83
84
85
86 func (pm PluginManager) IsMigrationEnabledForPlugin(pluginName string) bool {
87
88
89
90 switch pluginName {
91 case csilibplugins.AWSEBSInTreePluginName:
92 return true
93 case csilibplugins.GCEPDInTreePluginName:
94 return true
95 case csilibplugins.AzureFileInTreePluginName:
96 return true
97 case csilibplugins.AzureDiskInTreePluginName:
98 return true
99 case csilibplugins.CinderInTreePluginName:
100 return true
101 case csilibplugins.VSphereInTreePluginName:
102 return true
103 case csilibplugins.PortworxVolumePluginName:
104 return pm.featureGate.Enabled(features.CSIMigrationPortworx)
105 case csilibplugins.RBDVolumePluginName:
106 return pm.featureGate.Enabled(features.CSIMigrationRBD)
107 default:
108 return false
109 }
110 }
111
112
113
114 func (pm PluginManager) IsMigratable(spec *volume.Spec) (bool, error) {
115 if spec == nil {
116 return false, fmt.Errorf("could not find if plugin is migratable because volume spec is nil")
117 }
118
119 pluginName, _ := pm.GetInTreePluginNameFromSpec(spec.PersistentVolume, spec.Volume)
120 if pluginName == "" {
121 return false, nil
122 }
123
124 return pm.IsMigrationEnabledForPlugin(pluginName), nil
125 }
126
127
128
129 type InTreeToCSITranslator interface {
130 TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
131 TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error)
132 }
133
134
135
136 func TranslateInTreeSpecToCSI(spec *volume.Spec, podNamespace string, translator InTreeToCSITranslator) (*volume.Spec, error) {
137 var csiPV *v1.PersistentVolume
138 var err error
139 inlineVolume := false
140 if spec.PersistentVolume != nil {
141 csiPV, err = translator.TranslateInTreePVToCSI(spec.PersistentVolume)
142 } else if spec.Volume != nil {
143 csiPV, err = translator.TranslateInTreeInlineVolumeToCSI(spec.Volume, podNamespace)
144 inlineVolume = true
145 } else {
146 err = errors.New("not a valid volume spec")
147 }
148 if err != nil {
149 return nil, fmt.Errorf("failed to translate in-tree pv to CSI: %v", err)
150 }
151 return &volume.Spec{
152 Migrated: true,
153 PersistentVolume: csiPV,
154 ReadOnly: spec.ReadOnly,
155 InlineVolumeSpecForCSIMigration: inlineVolume,
156 }, nil
157 }
158
159
160
161
162 func CheckMigrationFeatureFlags(f featuregate.FeatureGate, pluginMigration,
163 pluginUnregister featuregate.Feature) (migrationComplete bool, err error) {
164
165 if f.Enabled(pluginMigration) && f.Enabled(pluginUnregister) {
166 return true, nil
167 }
168 return false, nil
169 }
170
View as plain text