Skip to content

Commit ea3339d

Browse files
committed
feat: support accessTier in storage account creation
1 parent 2a93f91 commit ea3339d

File tree

5 files changed

+72
-1
lines changed

5 files changed

+72
-1
lines changed

docs/driver-parameters.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ protocol | specify blobfuse mount or NFSv3 mount | `fuse`, `nfs` | No | `fuse`
1616
containerName | specify the existing container(directory) 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
1717
containerNamePrefix | specify Azure storage directory prefix created by driver | can only contain lowercase letters, numbers, hyphens, and length should be less than 21 | No |
1818
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
19+
accessTier | [Access tier for storage account](https://learn.microsoft.com/en-us/azure/storage/blobs/access-tiers-overview) | Standard account can choose `Hot` or `Cool`, and Premium account can only choose `Premium` | No | empty(use default setting for different storage account types)
1920
allowBlobPublicAccess | Allow or disallow public access to all blobs or containers for storage account created by driver | `true`,`false` | No | `false`
2021
requireInfraEncryption | specify whether or not the service applies a secondary layer of encryption with platform managed keys for data at rest for storage account created by driver | `true`,`false` | No | `false`
2122
storageEndpointSuffix | specify Azure storage endpoint suffix | `core.windows.net`, `core.chinacloudapi.cn`, etc | No | if empty, driver will use default storage endpoint suffix according to cloud environment

pkg/blob/blob.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"sync"
2424
"time"
2525

26+
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage"
2627
azstorage "github.com/Azure/azure-sdk-for-go/storage"
2728
az "github.com/Azure/go-autorest/autorest/azure"
2829
"github.com/container-storage-interface/spec/lib/go/csi"
@@ -89,6 +90,7 @@ const (
8990
vnetResourceGroupField = "vnetresourcegroup"
9091
vnetNameField = "vnetname"
9192
subnetNameField = "subnetname"
93+
accessTierField = "accesstier"
9294
mountPermissionsField = "mountpermissions"
9395
useDataPlaneAPIField = "usedataplaneapi"
9496

@@ -593,6 +595,18 @@ func isSupportedProtocol(protocol string) bool {
593595
return false
594596
}
595597

598+
func isSupportedAccessTier(accessTier string) bool {
599+
if accessTier == "" {
600+
return true
601+
}
602+
for _, tier := range storage.PossibleAccessTierValues() {
603+
if accessTier == string(tier) {
604+
return true
605+
}
606+
}
607+
return false
608+
}
609+
596610
// container names can contain only lowercase letters, numbers, and hyphens,
597611
// and must begin and end with a letter or a number
598612
func isSupportedContainerNamePrefix(prefix string) bool {

pkg/blob/blob_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,3 +1478,50 @@ func TestReplaceWithMap(t *testing.T) {
14781478
}
14791479
}
14801480
}
1481+
1482+
func TestIsSupportedAccessTier(t *testing.T) {
1483+
tests := []struct {
1484+
accessTier string
1485+
expectedResult bool
1486+
}{
1487+
{
1488+
accessTier: "",
1489+
expectedResult: true,
1490+
},
1491+
{
1492+
accessTier: "TransactionOptimized",
1493+
expectedResult: false,
1494+
},
1495+
{
1496+
accessTier: "Hot",
1497+
expectedResult: true,
1498+
},
1499+
{
1500+
accessTier: "Cool",
1501+
expectedResult: true,
1502+
},
1503+
{
1504+
accessTier: "Premium",
1505+
expectedResult: true,
1506+
},
1507+
{
1508+
accessTier: "transactionOptimized",
1509+
expectedResult: false,
1510+
},
1511+
{
1512+
accessTier: "premium",
1513+
expectedResult: false,
1514+
},
1515+
{
1516+
accessTier: "unknown",
1517+
expectedResult: false,
1518+
},
1519+
}
1520+
1521+
for _, test := range tests {
1522+
result := isSupportedAccessTier(test.accessTier)
1523+
if result != test.expectedResult {
1524+
t.Errorf("isSupportedTier(%s) returned with %v, not equal to %v", test.accessTier, result, test.expectedResult)
1525+
}
1526+
}
1527+
}

pkg/blob/controllerserver.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
6969
}
7070
var storageAccountType, subsID, resourceGroup, location, account, containerName, containerNamePrefix, protocol, customTags, secretName, secretNamespace, pvcNamespace string
7171
var isHnsEnabled, requireInfraEncryption *bool
72-
var vnetResourceGroup, vnetName, subnetName string
72+
var vnetResourceGroup, vnetName, subnetName, accessTier string
7373
var matchTags, useDataPlaneAPI bool
7474
// set allowBlobPublicAccess as false by default
7575
allowBlobPublicAccess := to.BoolPtr(false)
@@ -142,6 +142,8 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
142142
vnetName = v
143143
case subnetNameField:
144144
subnetName = v
145+
case accessTierField:
146+
accessTier = v
145147
case mountPermissionsField:
146148
// only do validations here, used in NodeStageVolume, NodePublishVolume
147149
if v != "" {
@@ -187,6 +189,9 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
187189
if !isSupportedProtocol(protocol) {
188190
return nil, status.Errorf(codes.InvalidArgument, "protocol(%s) is not supported, supported protocol list: %v", protocol, supportedProtocolList)
189191
}
192+
if !isSupportedAccessTier(accessTier) {
193+
return nil, status.Errorf(codes.InvalidArgument, "accessTier(%s) is not supported, supported AccessTier list: %v", accessTier, storage.PossibleAccessTierValues())
194+
}
190195

191196
if containerName != "" && containerNamePrefix != "" {
192197
return nil, status.Errorf(codes.InvalidArgument, "containerName(%s) and containerNamePrefix(%s) could not be specified together", containerName, containerNamePrefix)
@@ -248,6 +253,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
248253
VNetResourceGroup: vnetResourceGroup,
249254
VNetName: vnetName,
250255
SubnetName: subnetName,
256+
AccessTier: accessTier,
251257
}
252258

253259
var accountKey string

test/e2e/dynamic_provisioning_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
8787
// make sure this is the first test case due to storeAccountKey is set as false
8888
"storeAccountKey": "false",
8989
"requireInfraEncryption": "true",
90+
"accessTier": "Hot",
9091
},
9192
}
9293
test.Run(cs, ns)
@@ -119,6 +120,7 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
119120
"skuName": "Standard_LRS",
120121
"secretNamespace": "default",
121122
"containerNamePrefix": "nameprefix",
123+
"accessTier": "Cool",
122124
},
123125
}
124126
test.Run(cs, ns)
@@ -187,6 +189,7 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
187189
"skuName": "Premium_LRS",
188190
"isHnsEnabled": "true",
189191
"allowBlobPublicAccess": "false",
192+
"accessTier": "Premium",
190193
"useDataPlaneAPI": "true",
191194
"containerName": "container-${pvc.metadata.name}",
192195
},

0 commit comments

Comments
 (0)