Skip to content

Commit 7a9303d

Browse files
authored
Merge pull request #591 from andyzhangx/secret-name-field
feat: add secretName in storage class parameters
2 parents 7aef946 + a0a25f2 commit 7a9303d

File tree

4 files changed

+58
-8
lines changed

4 files changed

+58
-8
lines changed

docs/driver-parameters.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ skuName | Azure storage account type (alias: `storageAccountType`) | `Standard_L
1212
location | Azure location | `eastus`, `westus`, etc. | No | if empty, driver will use the same location name as current k8s cluster
1313
resourceGroup | Azure resource group name | existing resource group name | No | if empty, driver will use the same resource group name as current k8s cluster
1414
storageAccount | specify Azure storage account name| STORAGE_ACCOUNT_NAME | - No for blobfuse mount </br> - Yes for NFSv3 mount | - For blobfuse mount: if empty, driver will find a suitable storage account that matches `skuName` in the same resource group; if a storage account name is provided, storage account must exist. </br> - For NFSv3 mount, storage account name must be provided
15-
storeAccountKey | whether store account key to k8s secret | `true`,`false` | No | `true`
1615
protocol | specify blobfuse mount or NFSv3 mount | `fuse`, `nfs` | No | `fuse`
1716
containerName | specify the existing container name | existing container name | No | if empty, driver will create a new container name, starting with `pvc-fuse` for blobfuse or `pvc-nfs` for NFSv3
18-
isHnsEnabled | enable `Hierarchical namespace` for Azure DataLake storage account(only for blobfuse) | `true`,`false` | No | `false`
1917
server | specify Azure storage account server address | existing server address, e.g. `accountname.privatelink.blob.core.windows.net` | No | if empty, driver will use default `accountname.blob.core.windows.net` or other sovereign cloud account address
2018
allowBlobPublicAccess | Allow or disallow public access to all blobs or containers for storage account created by driver | `true`,`false` | No | `false`
2119
storageEndpointSuffix | specify Azure storage endpoint suffix | `core.windows.net` | No | if empty, driver will use default storage endpoint suffix according to cloud environment, e.g. `core.windows.net`
2220
tags | [tags](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources) would be created in newly created storage account | tag format: 'foo=aaa,bar=bbb' | No | ""
21+
--- | **Following parameters are only for blobfuse** | --- | --- |
22+
storeAccountKey | whether store account key to k8s secret <br><br> Note: <br> `false` means driver would leverage kubelet identity to get account key | `true`,`false` | No | `true`
23+
secretName | specify secret name to store account key | | No |
24+
secretNamespace | specify the namespace of secret to store account key | `default`,`kube-system`, etc | No | `default`
25+
isHnsEnabled | enable `Hierarchical namespace` for Azure DataLake storage account | `true`,`false` | No | `false`
2326

2427
- `fsGroup` securityContext setting
2528

@@ -54,8 +57,11 @@ volumeAttributes.resourceGroup | Azure resource group name | existing resource g
5457
volumeAttributes.storageAccount | existing storage account name | existing storage account name | Yes |
5558
volumeAttributes.containerName | existing container name | existing container name | Yes |
5659
volumeAttributes.protocol | specify blobfuse mount or NFSv3 mount | `fuse`, `nfs` | No | `fuse`
60+
--- | **Following parameters are only for blobfuse** | --- | --- |
61+
volumeAttributes.secretName | secret name that stores storage account name and key(only applies for SMB) | | No |
62+
volumeAttributes.secretNamespace | secret namespace | `default`,`kube-system`, etc | No | `default`
5763
nodeStageSecretRef.name | secret name that stores(check below examples):<br>`azurestorageaccountkey`<br>`azurestorageaccountsastoken`<br>`msisecret`<br>`azurestoragespnclientsecret` | existing Kubernetes secret name | No |
58-
nodeStageSecretRef.namespace | namespace where the secret is | k8s namespace | Yes |
64+
nodeStageSecretRef.namespace | secret namespace | k8s namespace | Yes |
5965
--- | **Following parameters are only for feature: blobfuse [Managed Identity and Service Principal Name auth](https://github.com/Azure/azure-storage-fuse#environment-variables)** | --- | --- |
6066
volumeAttributes.AzureStorageAuthType | Authentication Type | `Key`, `SAS`, `MSI`, `SPN` | No | `Key`
6167
volumeAttributes.AzureStorageIdentityClientID | Identity Client ID | | No |
@@ -70,6 +76,9 @@ volumeAttributes.keyVaultURL | Azure Key Vault DNS name | existing Azure Key Vau
7076
volumeAttributes.keyVaultSecretName | Azure Key Vault secret name | existing Azure Key Vault secret name | No |
7177
volumeAttributes.keyVaultSecretVersion | Azure Key Vault secret version | existing version | No |if empty, driver will use "current version"
7278

79+
- Note
80+
- only mounting blobfuse requires account key, and if secret is not provided in PV config, driver would try to get `azure-storage-account-{accountname}-secret` in the pod namespace, if not found, driver would try using kubelet identity to get account key directly using Azure API.
81+
- mounting blob storage NFSv3 does not need account key, it requires storage account configured with same vnet with agent node.
7382

7483
- create a Kubernetes secret for `nodeStageSecretRef.name`
7584
```console

pkg/blob/blob.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,14 +613,19 @@ func setAzureCredentials(kubeClient kubernetes.Interface, accountName, accountKe
613613
return secretName, err
614614
}
615615

616-
// GetStorageAccesskey get Azure storage (account name, account key)
617-
func (d *Driver) GetStorageAccesskey(ctx context.Context, accountOptions *azure.AccountOptions, secrets map[string]string, secretNamespace string) (string, string, error) {
616+
// GetStorageAccesskey get Azure storage account key from
617+
// 1. secrets (if not empty)
618+
// 2. use k8s client identity to read from k8s secret
619+
// 3. use cluster identity to get from storage account directly
620+
func (d *Driver) GetStorageAccesskey(ctx context.Context, accountOptions *azure.AccountOptions, secrets map[string]string, secretName, secretNamespace string) (string, string, error) {
618621
if len(secrets) > 0 {
619622
return getStorageAccount(secrets)
620623
}
621624

622625
// read from k8s secret first
623-
secretName := fmt.Sprintf(secretNameTemplate, accountOptions.Name)
626+
if secretName == "" {
627+
secretName = fmt.Sprintf(secretNameTemplate, accountOptions.Name)
628+
}
624629
_, accountKey, err := d.GetStorageAccountFromSecret(secretName, secretNamespace)
625630
if err != nil {
626631
klog.V(2).Infof("could not get account(%s) key from secret(%s) namespace(%s), error: %v, use cluster identity to get account key instead", accountOptions.Name, secretName, secretNamespace, err)

pkg/blob/controllerserver.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
6666
if parameters == nil {
6767
parameters = make(map[string]string)
6868
}
69-
var storageAccountType, resourceGroup, location, account, containerName, protocol, customTags, secretNamespace string
69+
var storageAccountType, resourceGroup, location, account, containerName, protocol, customTags, secretName, secretNamespace string
7070
var isHnsEnabled *bool
7171
// set allowBlobPublicAccess as false by default
7272
allowBlobPublicAccess := to.BoolPtr(false)
@@ -94,6 +94,8 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
9494
protocol = v
9595
case tagsField:
9696
customTags = v
97+
case secretNameField:
98+
secretName = v
9799
case secretNamespaceField:
98100
secretNamespace = v
99101
case isHnsEnabledField:
@@ -224,7 +226,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
224226
accountOptions.Name = accountName
225227

226228
if accountKey == "" {
227-
if accountName, accountKey, err = d.GetStorageAccesskey(ctx, accountOptions, req.GetSecrets(), secretNamespace); err != nil {
229+
if accountName, accountKey, err = d.GetStorageAccesskey(ctx, accountOptions, req.GetSecrets(), secretName, secretNamespace); err != nil {
228230
return nil, fmt.Errorf("failed to GetStorageAccesskey on account(%s) rg(%s), error: %v", accountOptions.Name, accountOptions.ResourceGroup, err)
229231
}
230232
}

test/e2e/dynamic_provisioning_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"os"
2424
"os/exec"
2525
"strings"
26+
"time"
2627

2728
"sigs.k8s.io/blob-csi-driver/test/e2e/driver"
2829
"sigs.k8s.io/blob-csi-driver/test/e2e/testsuites"
@@ -121,6 +122,39 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
121122
test.Run(cs, ns)
122123
})
123124

125+
ginkgo.It("should create a volume on demand with specified secretName", func() {
126+
pods := []testsuites.PodDetails{
127+
{
128+
Cmd: "echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data",
129+
Volumes: []testsuites.VolumeDetails{
130+
{
131+
ClaimSize: "10Gi",
132+
MountOptions: []string{
133+
"-o allow_other",
134+
"--file-cache-timeout-in-seconds=120",
135+
"--cancel-list-on-mount-seconds=0",
136+
},
137+
VolumeMount: testsuites.VolumeMountDetails{
138+
NameGenerate: "test-volume-",
139+
MountPathGenerate: "/mnt/test-",
140+
},
141+
},
142+
},
143+
},
144+
}
145+
scParameters := map[string]string{
146+
"skuName": "Standard_LRS",
147+
"secretNamespace": "kube-system",
148+
}
149+
scParameters["secretName"] = fmt.Sprintf("secret-%d", time.Now().Unix())
150+
test := testsuites.DynamicallyProvisionedCmdVolumeTest{
151+
CSIDriver: testDriver,
152+
Pods: pods,
153+
StorageClassParameters: scParameters,
154+
}
155+
test.Run(cs, ns)
156+
})
157+
124158
ginkgo.It("should create a deployment object, write and read to it, delete the pod and write and read to it again", func() {
125159
pod := testsuites.PodDetails{
126160
Cmd: "echo 'hello world' >> /mnt/test-1/data && while true; do sleep 1; done",

0 commit comments

Comments
 (0)