@@ -18,11 +18,13 @@ package plugins
18
18
19
19
import (
20
20
"fmt"
21
+ "regexp"
21
22
"strings"
22
23
23
24
v1 "k8s.io/api/core/v1"
24
25
storage "k8s.io/api/storage/v1"
25
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27
+ "k8s.io/klog"
26
28
)
27
29
28
30
const (
@@ -32,14 +34,19 @@ const (
32
34
AzureFileInTreePluginName = "kubernetes.io/azure-file"
33
35
34
36
separator = "#"
35
- volumeIDTemplate = "%s#%s#%s"
37
+ volumeIDTemplate = "%s#%s#%s#%s "
36
38
// Parameter names defined in azure file CSI driver, refer to
37
39
// https://github.com/kubernetes-sigs/azurefile-csi-driver/blob/master/docs/driver-parameters.md
38
40
azureFileShareName = "shareName"
41
+
42
+ secretNameTemplate = "azure-storage-account-%s-secret"
43
+ defaultSecretNamespace = "default"
39
44
)
40
45
41
46
var _ InTreePlugin = & azureFileCSITranslator {}
42
47
48
+ var secretNameFormatRE = regexp .MustCompile (`azure-storage-account-(.+)-secret` )
49
+
43
50
// azureFileCSITranslator handles translation of PV spec from In-tree
44
51
// Azure File to CSI Azure File and vice versa
45
52
type azureFileCSITranslator struct {}
@@ -61,9 +68,14 @@ func (t *azureFileCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Vol
61
68
return nil , fmt .Errorf ("volume is nil or Azure File not defined on volume" )
62
69
}
63
70
64
- var (
65
- azureSource = volume .AzureFile
71
+ azureSource := volume .AzureFile
72
+ accountName , err := getStorageAccountName (azureSource .SecretName )
73
+ if err != nil {
74
+ klog .Warningf ("getStorageAccountName(%s) returned with error: %v" , azureSource .SecretName , err )
75
+ accountName = azureSource .SecretName
76
+ }
66
77
78
+ var (
67
79
pv = & v1.PersistentVolume {
68
80
ObjectMeta : metav1.ObjectMeta {
69
81
// Must be unique per disk as it is used as the unique part of the
@@ -74,12 +86,12 @@ func (t *azureFileCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Vol
74
86
PersistentVolumeSource : v1.PersistentVolumeSource {
75
87
CSI : & v1.CSIPersistentVolumeSource {
76
88
Driver : AzureFileDriverName ,
77
- VolumeHandle : fmt .Sprintf (volumeIDTemplate , "" , azureSource . SecretName , azureSource .ShareName ),
89
+ VolumeHandle : fmt .Sprintf (volumeIDTemplate , "" , accountName , azureSource .ShareName , "" ),
78
90
ReadOnly : azureSource .ReadOnly ,
79
91
VolumeAttributes : map [string ]string {azureFileShareName : azureSource .ShareName },
80
- NodePublishSecretRef : & v1.SecretReference {
81
- Name : azureSource .ShareName ,
82
- Namespace : "default" ,
92
+ NodeStageSecretRef : & v1.SecretReference {
93
+ Name : azureSource .SecretName ,
94
+ Namespace : defaultSecretNamespace ,
83
95
},
84
96
},
85
97
},
@@ -98,15 +110,21 @@ func (t *azureFileCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume)
98
110
return nil , fmt .Errorf ("pv is nil or Azure File source not defined on pv" )
99
111
}
100
112
101
- var (
102
- azureSource = pv .Spec .PersistentVolumeSource .AzureFile
103
- volumeID = fmt .Sprintf (volumeIDTemplate , "" , azureSource .SecretName , azureSource .ShareName )
113
+ azureSource := pv .Spec .PersistentVolumeSource .AzureFile
114
+ accountName , err := getStorageAccountName (azureSource .SecretName )
115
+ if err != nil {
116
+ klog .Warningf ("getStorageAccountName(%s) returned with error: %v" , azureSource .SecretName , err )
117
+ accountName = azureSource .SecretName
118
+ }
119
+ volumeID := fmt .Sprintf (volumeIDTemplate , "" , accountName , azureSource .ShareName , "" )
104
120
121
+ var (
105
122
// refer to https://github.com/kubernetes-sigs/azurefile-csi-driver/blob/master/docs/driver-parameters.md
106
123
csiSource = & v1.CSIPersistentVolumeSource {
107
124
Driver : AzureFileDriverName ,
108
- NodePublishSecretRef : & v1.SecretReference {
109
- Name : azureSource .ShareName ,
125
+ NodeStageSecretRef : & v1.SecretReference {
126
+ Name : azureSource .SecretName ,
127
+ Namespace : defaultSecretNamespace ,
110
128
},
111
129
ReadOnly : azureSource .ReadOnly ,
112
130
VolumeAttributes : map [string ]string {azureFileShareName : azureSource .ShareName },
@@ -115,7 +133,7 @@ func (t *azureFileCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume)
115
133
)
116
134
117
135
if azureSource .SecretNamespace != nil {
118
- csiSource .NodePublishSecretRef .Namespace = * azureSource .SecretNamespace
136
+ csiSource .NodeStageSecretRef .Namespace = * azureSource .SecretNamespace
119
137
}
120
138
121
139
pv .Spec .PersistentVolumeSource .AzureFile = nil
@@ -137,22 +155,21 @@ func (t *azureFileCSITranslator) TranslateCSIPVToInTree(pv *v1.PersistentVolume)
137
155
ReadOnly : csiSource .ReadOnly ,
138
156
}
139
157
140
- if csiSource .NodePublishSecretRef != nil && csiSource .NodePublishSecretRef .Name != "" {
141
- azureSource .SecretName = csiSource .NodePublishSecretRef .Name
142
- azureSource .SecretNamespace = & csiSource .NodePublishSecretRef .Namespace
158
+ if csiSource .NodeStageSecretRef != nil && csiSource .NodeStageSecretRef .Name != "" {
159
+ azureSource .SecretName = csiSource .NodeStageSecretRef .Name
160
+ azureSource .SecretNamespace = & csiSource .NodeStageSecretRef .Namespace
143
161
if csiSource .VolumeAttributes != nil {
144
162
if shareName , ok := csiSource .VolumeAttributes [azureFileShareName ]; ok {
145
163
azureSource .ShareName = shareName
146
164
}
147
165
}
148
166
} else {
149
- _ , _ , fileShareName , err := getFileShareInfo (csiSource .VolumeHandle )
167
+ _ , storageAccount , fileShareName , _ , err := getFileShareInfo (csiSource .VolumeHandle )
150
168
if err != nil {
151
169
return nil , err
152
170
}
153
171
azureSource .ShareName = fileShareName
154
- // to-do: for dynamic provision scenario in CSI, it uses cluster's identity to get storage account key
155
- // secret for the file share is not created, we may create a serect here
172
+ azureSource .SecretName = fmt .Sprintf (secretNameTemplate , storageAccount )
156
173
}
157
174
158
175
pv .Spec .CSI = nil
@@ -190,12 +207,25 @@ func (t *azureFileCSITranslator) RepairVolumeHandle(volumeHandle, nodeID string)
190
207
}
191
208
192
209
// get file share info according to volume id, e.g.
193
- // input: "rg#f5713de20cde511e8ba4900#pvc-file-dynamic-17e43f84-f474-11e8-acd0-000d3a00df41"
194
- // output: rg, f5713de20cde511e8ba4900, pvc-file-dynamic-17e43f84-f474-11e8-acd0-000d3a00df41
195
- func getFileShareInfo (id string ) (string , string , string , error ) {
210
+ // input: "rg#f5713de20cde511e8ba4900#pvc-file-dynamic-17e43f84-f474-11e8-acd0-000d3a00df41#diskname.vhd "
211
+ // output: rg, f5713de20cde511e8ba4900, pvc-file-dynamic-17e43f84-f474-11e8-acd0-000d3a00df41, diskname.vhd
212
+ func getFileShareInfo (id string ) (string , string , string , string , error ) {
196
213
segments := strings .Split (id , separator )
197
214
if len (segments ) < 3 {
198
- return "" , "" , "" , fmt .Errorf ("error parsing volume id: %q, should at least contain two #" , id )
215
+ return "" , "" , "" , "" , fmt .Errorf ("error parsing volume id: %q, should at least contain two #" , id )
216
+ }
217
+ var diskName string
218
+ if len (segments ) > 3 {
219
+ diskName = segments [3 ]
220
+ }
221
+ return segments [0 ], segments [1 ], segments [2 ], diskName , nil
222
+ }
223
+
224
+ // get storage account name from secret name
225
+ func getStorageAccountName (secretName string ) (string , error ) {
226
+ matches := secretNameFormatRE .FindStringSubmatch (secretName )
227
+ if len (matches ) != 2 {
228
+ return "" , fmt .Errorf ("could not get account name from %s, correct format: %s" , secretName , secretNameFormatRE )
199
229
}
200
- return segments [ 0 ], segments [ 1 ], segments [ 2 ], nil
230
+ return matches [ 1 ], nil
201
231
}
0 commit comments