Skip to content

Commit bff8ad5

Browse files
authored
Merge pull request #730 from cvvz/e2e-test-for-secret
test: add e2e test for provided credentials
2 parents 6f1968e + 791d631 commit bff8ad5

29 files changed

+4544
-77
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ require (
3838
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1
3939
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.0.0
4040
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1
41+
github.com/satori/go.uuid v1.2.0
4142
k8s.io/apiserver v0.24.3
4243
)
4344

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
573573
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
574574
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
575575
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
576+
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
577+
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
576578
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
577579
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
578580
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=

test/e2e/pre_provisioning_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Pre-Provisioned", func() {
240240
MountPathGenerate: "/mnt/test-",
241241
},
242242
NodeStageSecretRef: "azure-secret",
243+
Attrib: make(map[string]string),
243244
},
244245
},
245246
},
@@ -279,6 +280,7 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Pre-Provisioned", func() {
279280
NameGenerate: "test-volume-",
280281
MountPathGenerate: "/mnt/test-",
281282
},
283+
Attrib: make(map[string]string),
282284
},
283285
},
284286
},
@@ -315,6 +317,7 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Pre-Provisioned", func() {
315317
NameGenerate: "test-volume-",
316318
MountPathGenerate: "/mnt/test-",
317319
},
320+
Attrib: make(map[string]string),
318321
},
319322
},
320323
},

test/e2e/testsuites/pre_provisioned_keyvault_tester.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ func (t *PreProvisionedKeyVaultTest) Run(client clientset.Interface, namespace *
6161
accountKeySecret, err := keyVaultClient.CreateSecret(context.TODO(), accountName+"-key", accountKey)
6262
framework.ExpectNoError(err)
6363

64-
pod.Volumes[n].ContainerName = containerName
65-
pod.Volumes[n].StorageAccountname = accountName
66-
pod.Volumes[n].KeyVaultURL = *vault.Properties.VaultURI
67-
pod.Volumes[n].KeyVaultSecretName = *accountKeySecret.Name
64+
pod.Volumes[n].Attrib["containerName"] = containerName
65+
pod.Volumes[n].Attrib["storageAccountName"] = accountName
66+
pod.Volumes[n].Attrib["keyVaultURL"] = *vault.Properties.VaultURI
67+
pod.Volumes[n].Attrib["keyVaultSecretName"] = *accountKeySecret.Name
6868

6969
ginkgo.By("test storage account key...")
7070
tpod, cleanup := pod.SetupWithPreProvisionedVolumes(client, namespace, t.CSIDriver)

test/e2e/testsuites/pre_provisioned_provided_credentials_tester.go

Lines changed: 89 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"sigs.k8s.io/blob-csi-driver/pkg/blob"
2626
"sigs.k8s.io/blob-csi-driver/test/e2e/driver"
27+
"sigs.k8s.io/blob-csi-driver/test/utils/azure"
2728

2829
v1 "k8s.io/api/core/v1"
2930
clientset "k8s.io/client-go/kubernetes"
@@ -39,34 +40,101 @@ type PreProvisionedProvidedCredentiasTest struct {
3940
}
4041

4142
func (t *PreProvisionedProvidedCredentiasTest) Run(client clientset.Interface, namespace *v1.Namespace) {
43+
kvClient, err := azure.NewKeyVaultClient()
44+
framework.ExpectNoError(err)
45+
46+
authClient, err := azure.NewAuthorizationClient()
47+
framework.ExpectNoError(err)
48+
4249
for _, pod := range t.Pods {
4350
for n, volume := range pod.Volumes {
44-
accountName, accountKey, accountSasToken, containerName, err := t.Driver.GetStorageAccountAndContainer(context.Background(), volume.VolumeID, nil, nil)
51+
accountName, accountKey, _, _, err := t.Driver.GetStorageAccountAndContainer(context.Background(), volume.VolumeID, nil, nil)
4552
framework.ExpectNoError(err, fmt.Sprintf("Error GetStorageAccountAndContainer from volumeID(%s): %v", volume.VolumeID, err))
53+
var secretData map[string]string
54+
55+
var run = func() {
56+
tsecret := NewTestSecret(client, namespace, volume.NodeStageSecretRef, secretData)
57+
tsecret.Create()
58+
defer tsecret.Cleanup()
59+
60+
tpod, cleanup := pod.SetupWithPreProvisionedVolumes(client, namespace, t.CSIDriver)
61+
// defer must be called here for resources not get removed before using them
62+
for i := range cleanup {
63+
defer cleanup[i]()
64+
}
65+
66+
ginkgo.By("deploying the pod")
67+
tpod.Create()
68+
defer tpod.Cleanup()
69+
ginkgo.By("checking that the pods command exits with no error")
70+
tpod.WaitForSuccess()
71+
}
4672

47-
ginkgo.By("creating the secret")
48-
secreteData := map[string]string{"azurestorageaccountname": accountName}
49-
if accountKey != "" {
50-
secreteData["azurestorageaccountkey"] = accountKey
51-
} else {
52-
secreteData["azurestorageaccountsastoken"] = accountSasToken
73+
// test for storage account key
74+
ginkgo.By("Run for storage account key")
75+
secretData = map[string]string{
76+
"azurestorageaccountname": accountName,
77+
"azurestorageaccountkey": accountKey,
78+
}
79+
run()
80+
81+
// test for storage account SAS token
82+
ginkgo.By("Run for storage account SAS token")
83+
sasToken := GenerateSASToken(accountName, accountKey)
84+
secretData = map[string]string{
85+
"azurestorageaccountname": accountName,
86+
"azurestorageaccountsastoken": sasToken,
87+
}
88+
run()
89+
90+
// test for service principal
91+
ginkgo.By("Run for service principal")
92+
pod.Volumes[n].Attrib = map[string]string{
93+
"azurestorageauthtype": "SPN",
94+
"azurestoragespnclientid": kvClient.Cred.AADClientID,
95+
"azurestoragespntenantid": kvClient.Cred.TenantID,
96+
}
97+
secretData = map[string]string{
98+
"azurestorageaccountname": accountName,
99+
"azurestoragespnclientsecret": kvClient.Cred.AADClientSecret,
53100
}
54-
tsecret := NewTestSecret(client, namespace, volume.NodeStageSecretRef, secreteData)
55-
tsecret.Create()
56-
defer tsecret.Cleanup()
57-
58-
pod.Volumes[n].ContainerName = containerName
59-
tpod, cleanup := pod.SetupWithPreProvisionedVolumes(client, namespace, t.CSIDriver)
60-
// defer must be called here for resources not get removed before using them
61-
for i := range cleanup {
62-
defer cleanup[i]()
101+
102+
objectID, err := kvClient.GetServicePrincipalObjectID(context.TODO(), kvClient.Cred.AADClientID)
103+
framework.ExpectNoError(err, fmt.Sprintf("Error GetServicePrincipalObjectID from clientID(%s): %v", kvClient.Cred.AADClientID, err))
104+
105+
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s", kvClient.Cred.SubscriptionID, kvClient.Cred.ResourceGroup, accountName)
106+
107+
ginkgo.By(fmt.Sprintf("assign Storage Blob Data Contributor role to the service principal, objectID:%s", objectID))
108+
roleDef, err := authClient.GetRoleDefinition(context.TODO(), resourceID, "Storage Blob Data Contributor")
109+
framework.ExpectNoError(err, fmt.Sprintf("Error GetRoleDefinition from resourceID(%s): %v", resourceID, err))
110+
111+
roleDefID := *roleDef.ID
112+
_, err = authClient.AssignRole(context.TODO(), resourceID, objectID, roleDefID)
113+
framework.ExpectNoError(err, fmt.Sprintf("Error AssignRole (roleDefID(%s)) to objectID(%s) to access resource (resourceID(%s)), error: %v", roleDefID, objectID, resourceID, err))
114+
115+
run()
116+
117+
// test for managed identity
118+
// e2e-vmss test job uses msi blobfuse-csi-driver-e2e-test-id, other jobs use service principal
119+
objectID, err = kvClient.GetMSIObjectID(context.TODO(), "blobfuse-csi-driver-e2e-test-id")
120+
if err != nil {
121+
return
122+
}
123+
124+
ginkgo.By("Run for managed identity")
125+
pod.Volumes[n].Attrib = map[string]string{
126+
"azurestorageauthtype": "MSI",
127+
"azurestorageidentityobjectid": objectID,
128+
}
129+
130+
secretData = map[string]string{
131+
"azurestorageaccountname": accountName,
63132
}
133+
ginkgo.By(fmt.Sprintf("assign Storage Blob Data Contributor role to the managed identity, objectID:%s", objectID))
134+
_, err = authClient.AssignRole(context.TODO(), resourceID, objectID, roleDefID)
135+
framework.ExpectNoError(err, fmt.Sprintf("Error AssignRole (roleDefID(%s)) to objectID(%s) to access resource (resourceID(%s)), error: %v", roleDefID, objectID, resourceID, err))
64136

65-
ginkgo.By("deploying the pod")
66-
tpod.Create()
67-
defer tpod.Cleanup()
68-
ginkgo.By("checking that the pods command exits with no error")
69-
tpod.WaitForSuccess()
137+
run()
70138
}
71139
}
72140
}

test/e2e/testsuites/pre_provisioned_sastoken_tester.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,16 @@ func (t *PreProvisionedSASTokenTest) Run(client clientset.Interface, namespace *
6161
}()
6262

6363
ginkgo.By("generating SAS token...")
64-
sasToken := generateSASToken(accountName, accountKey)
64+
sasToken := GenerateSASToken(accountName, accountKey)
6565

6666
ginkgo.By("creating secret for SAS token...")
6767
accountSASSecret, err := keyVaultClient.CreateSecret(context.TODO(), accountName+"-sas", sasToken)
6868
framework.ExpectNoError(err)
6969

70-
pod.Volumes[n].ContainerName = containerName
71-
pod.Volumes[n].StorageAccountname = accountName
72-
pod.Volumes[n].KeyVaultURL = *vault.Properties.VaultURI
73-
pod.Volumes[n].KeyVaultSecretName = *accountSASSecret.Name
70+
pod.Volumes[n].Attrib["containerName"] = containerName
71+
pod.Volumes[n].Attrib["storageAccountName"] = accountName
72+
pod.Volumes[n].Attrib["keyVaultURL"] = *vault.Properties.VaultURI
73+
pod.Volumes[n].Attrib["keyVaultSecretName"] = *accountSASSecret.Name
7474

7575
tpod, cleanup := pod.SetupWithPreProvisionedVolumes(client, namespace, t.CSIDriver)
7676
// defer must be called here for resources not get removed before using them
@@ -88,7 +88,7 @@ func (t *PreProvisionedSASTokenTest) Run(client clientset.Interface, namespace *
8888
}
8989
}
9090

91-
func generateSASToken(accountName, accountKey string) string {
91+
func GenerateSASToken(accountName, accountKey string) string {
9292
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
9393
framework.ExpectNoError(err)
9494
serviceClient, err := azblob.NewServiceClientWithSharedKey(fmt.Sprintf("https://%s.blob.core.windows.net/", accountName), credential, nil)

test/e2e/testsuites/specs.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,8 @@ type VolumeDetails struct {
5050
VolumeID string
5151
// Optional, used with PVCs created from snapshots
5252
DataSource *DataSource
53-
ContainerName string
5453
NodeStageSecretRef string
55-
StorageAccountname string
56-
KeyVaultURL string
57-
KeyVaultSecretName string
54+
Attrib map[string]string
5855
}
5956

6057
type VolumeMode int
@@ -203,19 +200,7 @@ func (volume *VolumeDetails) SetupDynamicPersistentVolumeClaim(client clientset.
203200
func (volume *VolumeDetails) SetupPreProvisionedPersistentVolumeClaim(client clientset.Interface, namespace *v1.Namespace, csiDriver driver.PreProvisionedVolumeTestDriver) (*TestPersistentVolumeClaim, []func()) {
204201
cleanupFuncs := make([]func(), 0)
205202
ginkgo.By("setting up the PV")
206-
attrib := make(map[string]string)
207-
if volume.ContainerName != "" {
208-
attrib["containerName"] = volume.ContainerName
209-
}
210-
if volume.StorageAccountname != "" {
211-
attrib["storageAccountName"] = volume.StorageAccountname
212-
}
213-
if volume.KeyVaultURL != "" {
214-
attrib["keyVaultURL"] = volume.KeyVaultURL
215-
}
216-
if volume.KeyVaultSecretName != "" {
217-
attrib["keyVaultSecretName"] = volume.KeyVaultSecretName
218-
}
203+
attrib := volume.Attrib
219204
nodeStageSecretRef := volume.NodeStageSecretRef
220205
pv := csiDriver.GetPersistentVolume(volume.VolumeID, volume.FSType, volume.ClaimSize, volume.ReclaimPolicy, namespace.Name, attrib, nodeStageSecretRef)
221206
tpv := NewTestPreProvisionedPersistentVolume(client, pv)

test/manifest/linux-vmss.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@
5252
}
5353
},
5454
"servicePrincipalProfile": {
55-
"clientID": "{clientID}",
56-
"secret": "{secret}"
55+
"clientID": "msi"
5756
}
5857
}
5958
}

0 commit comments

Comments
 (0)